Intel汇编程序设计-整数算术指令(下)
7.5 ?擴(kuò)展加法和減法
? ? 擴(kuò)展精度的假發(fā)和減法是指任意尺寸大小數(shù)字的加法和減法。例如要求你寫一個C++程序,把兩個1024位的整數(shù)相加,解決方案可不是那么簡單!但在匯編語言中,ADC(帶進(jìn)位加)指令和SBB(帶進(jìn)位減)指令非常適合于解決此類問題。
7.5.1 ?ADC指令
ADC(AddWithCarry)指令把源操作數(shù)、目的操作數(shù)以及進(jìn)位標(biāo)志相加。指令格式與MOV指令是一樣的:
ADC ?reg ,reg
ADC ?mem ,reg
ADC ?reg ,mem
ADC ?mem ,imm
ADC ?reg ,imm
例如,下面的指令把兩個8位整數(shù)相加(FFh+FFh),16位解雇01FEh被存放在DL:AL中:
mov ?dl ,0
mov ?al ,0FFh
add ??al ,0FFh ??;AL = FE
adc ??dl ,0 ?????;DL = 01
?
兩個32位整數(shù)相加(FFFFFFFFh+FFFFFFFFh)相加,在EDX:EAX中存放64位的和0000001FFFFFFFEh:
mov ?edx ,0
mov ?eax ,0FFFFFFFFh
add ??eax ,0FFFFFFFFh
adc ??edx ,0
7.5.2 ?擴(kuò)展加法的例子
? ? 下面的Extended_Add過程把兩個任意相同尺寸的整數(shù)相加,程序使用一個循環(huán)把沒對雙字相加,保存進(jìn)位標(biāo)志,并是僅為標(biāo)志參與后面的雙字的假發(fā)運(yùn)算:
?
? ? 下面摘自ExtAdd.asm的程序片段調(diào)用了Extended_Add過程,例子中傳遞的是兩個64位整數(shù)。注意特別分配了額外的雙字節(jié)以保存可能出現(xiàn)的進(jìn)位值:
?
果真發(fā)生了進(jìn)位,注意一個問題,就是比如op1?QWORD 0A2B2A40674981234h
eax ?= ?OFFSET op1
那么[eax] 是74981234h ?而[eax+4]是0A2B2A406。一開始我在最后輸出的時(shí)候沒看懂,后臺調(diào)試的時(shí)候想起來了。
?
7.5.3 ?SBB指令
? ?SBB(subtract with borrow)指令從墓地操作數(shù)中減去源操作數(shù)和進(jìn)位標(biāo)志的值。指令允許你的操作與ADC是相同的。
下面的例子是執(zhí)行64位的減法,把EDX:EAX設(shè)置為0000000100000000h并從中減去1,程序首先減去低32位值,進(jìn)位標(biāo)志將被設(shè)置,然后再減去高32位和進(jìn)位標(biāo)志值:
mov ?edx ,1 ???;高半部分
mov ?eax ,0 ???;低半部分
sub ??eax , 1 ??;減去1
sbb ??edx ,0 ??;減去1的高半部分(0)
EDX:EAX 中的64位差值是00000000FFFFFFFFh。
7.6 ?ACCII和未壓縮十進(jìn)制算術(shù)指令
? ?到現(xiàn)在為止,本書講述的整數(shù)算術(shù)指令都是處理二進(jìn)制數(shù)值的,盡管CPU是以二進(jìn)制算術(shù)方式進(jìn)行運(yùn)算的,但是也能處理ASCII十進(jìn)制數(shù)串的算術(shù)運(yùn)算。后者可以方便地有用戶輸出并在控制臺窗口中顯示,無需轉(zhuǎn)換成二進(jìn)制數(shù)值。假設(shè)程序需要用戶輸入兩個數(shù)字并把他們相加,下面是一個輸出樣例,其中用書輸入了3402和1256:
???Enter first numbers: ???3402
???Enter second number: ?1256
???The sum is: ??????????4658
在計(jì)算和顯示數(shù)字的時(shí)候有兩種選擇:
1.把兩個操作數(shù)轉(zhuǎn)換成二進(jìn)制數(shù)值并相加,然后把和從二進(jìn)制數(shù)轉(zhuǎn)換成ASCII碼數(shù)字串的格式化后顯示。
2.連續(xù)地把沒對ASCII數(shù)字直接相加,這樣就和是ASCII數(shù)字串,可以直接在屏幕上顯示。
第二種選擇要求在對ASCII數(shù)字相加后使用特殊指令來調(diào)整其和,指令集中有4條指令可以處理這一類的ASCII加法、減法、乘法和除法:
mov ???ah ,0
mov ???al ,’8’?????;AX = 0038h
add ????al,’2’?????;AX = 006Ah
aaa ?????????????;AX = 0100h(結(jié)果的ASCII碼調(diào)整)
or ?????ax ,3030h ;AX = 3130h=’10’(轉(zhuǎn)換成ACSCII碼)
AAS AAM AAD也是如此。
7.7.1 ?DAA指令
DAA指令把ADD和ADC指令執(zhí)行后AL中的二進(jìn)制數(shù)轉(zhuǎn)換成壓縮的十進(jìn)制數(shù)格式。
mov ?al ,35h
add ?al ,48h ???;AL = 7Dh
daa ???????????;AL = 83h(調(diào)整結(jié)果)
7.7.2 ?DAS指令
DAS(decimal adjust after subtraction)指令將SUB或SBB指令執(zhí)行后AL中的二進(jìn)制轉(zhuǎn)換成壓縮的十進(jìn)制格式。
mov bl ,48h
mov al ,85h
sub al ,bl ??;AL = 3Dh
das ??????;AL = 37h(調(diào)整結(jié)果)
7.8 本章小結(jié)
?
?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Intel汇编程序设计-整数算术指令(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows核心编程 第五章 作业(下
- 下一篇: Windows核心编程 第六章 线程基础