640 likes | 696 Views
第 7 章 : 整數算術. 章節概要. 移位與迴旋指令 移位與迴旋指令的應用 乘法與除法指令 延伸加法與減法 ASCII 與未緊縮十進制的算術運算. 移位與迴旋指令. 邏輯對算術位移 SHL 指令 SHR 指令 SAL and SAR 指令 ROL 指令 ROR 指令 RCL and RCR 指令 SHLD/SHRD 指令. 邏輯對算術位移. 這種方式會將移位過程中新建立的位元位置填入 0. 這種方式會將新建立的位元位置,填入 該數值原本的正負號位元 :. SHL 指令.
E N D
章節概要 • 移位與迴旋指令 • 移位與迴旋指令的應用 • 乘法與除法指令 • 延伸加法與減法 • ASCII與未緊縮十進制的算術運算
移位與迴旋指令 • 邏輯對算術位移 • SHL 指令 • SHR 指令 • SAL and SAR 指令 • ROL指令 • ROR指令 • RCL and RCR指令 • SHLD/SHRD指令
邏輯對算術位移 • 這種方式會將移位過程中新建立的位元位置填入 0 • 這種方式會將新建立的位元位置,填入 該數值原本的正負號位元:
SHL指令 • 指令用於對目標運算元執行向左邏輯移位,並 且將最低位元填入 0。 • 運算元類型: • SHL reg,imm8 • SHL mem,imm8 • SHL reg,CL • SHL mem,CL
如果將十進位 10 左移 2 位元,則結果相當於將其乘以 4 mov dl,5 shl dl,2 ; DL = 20 快速乘法 SHL 可以執行 2 的次方數的高速乘法 mov dl,5 shl dl,1
將任何無號的整數向右邏輯移位 n 位元,相當於將其除以 2n mov dl,80 shr dl,1 ; DL = 40 shr dl,2 ; DL = 10 SHR 指令 • SHR指令用於對目標運算元執行向右邏輯移位,並 將最高位元填入 0。.
算術位移保持數字的符號。 mov dl,-80 sar dl,1 ; DL = -40 sar dl,2 ; DL = -10 SAL 和SAR 指令 • SAL (向左算術移位)與 SHL 指令是完全一樣的。 • SAR (向右算術移位)指令則對其目標運算元,執行 算術右移的運算:
習題. . . 指出每位移後的 AL 的十六進位值: mov al,6Bh shr al,1 a. shl al,3 b. mov al,8Ch sar al,1 c. sar al,3 d. 35h A8h C6h F8h
ROL 指令 • ROL (迴旋)指令用於將每個位元向左移位。 • 最高位 元將複製到進位旗標以及最低位元位置 • 沒有位元遺失 mov al,11110000b rol al,1 ; AL = 11100001b mov dl,3Fh rol dl,4 ; DL = F3h
ROR 指令 • ROR (向右迴旋)指令用於將每個位元向右移位 • 最低 位元會同時複製到進位旗標與最高位元位置中 • 沒有位元遺失 mov al,11110000b ror al,1 ; AL = 01111000b mov dl,3Fh ror dl,4 ; DL = F3h
習題. . . 指出每次迴旋後的 AL 的十六進位值: mov al,6Bh ror al,1 a. rol al,3 b. B5h ADh
RCL 指令 • RCL (包含進位旗標的向左迴旋)指令用於將每個位元向 左移位 • 進位旗標會複製到最小有效位元 • 最大有效位元複 製到進位旗標中 clc ; CF = 0 mov bl,88h ; CF,BL = 0 10001000b rcl bl,1 ; CF,BL = 1 00010000b rcl bl,1 ; CF,BL = 0 00100001b
RCR 指令 • RCR (包含進位旗標的向右迴旋)指令用於將 每個位元向右移位 • 進位旗標會複製到最大有效位元 • 最小有效位 元會複製到進位旗標 stc ; CF = 1 mov ah,10h ; CF,AH = 00010000 1 rcr ah,1 ; CF,AH = 10001000 0
習題. . . 指出每次迴旋後的 AL 的十六進位值: stc mov al,6Bh rcr al,1 a. rcl al,3 b. B5h AEh
SHLD 指令 • 指令用於將目的運算元向左移位指定的位元數 • 移位過程中所產生的未定位元,填入來源運算元最大有效位元的位元值 • 來源運算元的值並不會受影響 • 語法: SHLD destination, source, count
SHLD 例題 下列敘述會將 wval 左移 4 位元,並且將 AX 的最高四個位元,插入 wval 的最低 四個位元: .data wval WORD 9BA6h .code mov ax,0AC36h shld wval,ax,4 Before: After:
SHRD 指令 • 指令用於將目的運算元向右移位指定的位元數 • 移位過程中所產生的未定位元位置,則填入來源運算元最小有效位元的位元值 • 來源運算元的值並不會受影響 • 語法: SHRD destination, source, count
SHRD 例題 在下列例子中,AX 會右移四個位元,而且 DX 的最低四個位元將移位到 AX 的 最高四個位元內: mov ax,234Bh mov dx,7654h shrd ax,dx,4 Before: After:
習題. . . 指出每個運算元的十六進位值: mov ax,7C36h mov dx,9FA6h shld dx,ax,4 ; DX = shrd dx,ax,8 ; DX = FA67h 36FAh
移位與迴旋指令的應用 • 移位多個雙字組 • 二進位的乘法 • 顯示二進位位元 • 分隔位元串
移位多個雙字組 • 程式有時需要在排列裡面位移所有的位元,可能當移動一個點陣圖的圖解從一個螢幕點到另外一的影像的時候 • 下列各項改變對右邊的 1 位元 3 雙字組 的排列: (視野完全的原始碼) .data ArraySize = 3 array DWORD ArraySize DUP(99999999h) ; 1001 1001... .code mov esi,0 shr array[esi + 8],1 ; high dword rcr array[esi + 4],1 ; middle dword, include Carry rcr array[esi],1 ; low dword, include Carry
二進位乘法 • 當乘數為 2 的次方數時,SHL 指令可以有 效率地執行無號數的乘法運算。 • 將一個無號整數向左移位 n 位元,相當於對它乘以 2n. • 例如,如果想要將無號的 EAX 乘以 36,我們可以將 36 分解成 25 + 22,並且使用乘法的分配律完成運算 EAX * 36 = EAX * (32 + 4) = (EAX * 32)+(EAX * 4) mov eax,123 mov ebx,eax shl eax,5 ; mult by 25 shl ebx,2 ; mult by 22 add eax,ebx
習題. . . 無號整數相乘26, 使用位移和加法指令. Hint: 26 = 16 + 8 + 2. mov ax,2 ; test value mov dx,ax shl dx,4 ; AX * 16 push dx ; save for later mov dx,ax shl dx,3 ; AX * 8 shl ax,1 ; AX * 2 add ax,dx ; AX * 10 pop dx ; recall AX * 16 add ax,dx ; AX * 26
顯示二進位位元 運算法則:位移 MSB 進入旗標中;如果CF=1,對字串加一個 "1" 字元;否則,加一個 "0" 字元。在一個迴路,32次重複。 mov ecx,32 mov esi,offset buffer L1: shl eax,1 mov BYTE PTR [esi],'0' jnc L2 mov BYTE PTR [esi],'1' L2: inc esi loop L1
分隔月份的數值: mov ax,dx ; make a copy of DX shr ax,5 ; shift right 5 bits and al,00001111b ; clear bits 4-7 mov month,al ; save in month variable 分隔位元串 • MS-DOS 檔案日期領域包含年,月和日進入 16 位元:
乘法和除法指令 • MUL 指令 • IMUL指令 • DIV指令 • 有號整數除法 • 實行算術語言
MUL 指令 • MUL (無號數相乘) 指令乘一個8-, 16-, 或 32-bit 被任一運算元 AL, AX,或 EAX. • 指令格式: MUL r/m8 MUL r/m16 MUL r/m32 MUL 運算元 :
將 12345h 乘以 1000h,結果產生了 32位元的乘積: mov eax,12345h mov ebx,1000h mul ebx ; EDX:EAX = 0000000012345000h, CF=0 MUL 例題 將 16 位元的數值 2000h,乘以 100h : .data val1 WORD 2000h val2 WORD 100h .code mov ax,val1 mul val2 ; DX:AX = 00200000h, CF=1 檢查進位旗標可以知道乘積的上半部是否能無虞地予以忽略
習題. . . 什麼將會是 DX ,AX的十六進位值,和進位標旗在下列的指令執行之後? mov ax,1234h mov bx,100h mul bx DX = 0012h, AX = 3400h, CF = 1
習題. . . 什麼將會是 EDX ,EAX的十六進位值,和進位標旗在下列的指令執行之後? mov eax,00128765h mov ecx,10000h mul ecx EDX = 00000012h, EAX = 87650000h, CF = 1
IMUL 指令 • IMUL (有號數相乘)增加一個 8,16, 或 32 位元有符號運算任一AL ,AX,或 EAX • 指令會保存乘積的正負號,藉以執行 有號整數的乘法運算 例題:乘法48 * 4,使用 8-bit運算: mov al,48 mov bl,4 imul bl ; AX = 00C0h, OF=1 OF=1 因為AH 不是一個有號延伸AL.
IMUL 例題 乘法4,823,424 * -423: mov eax,4823424 mov ebx,-423 imul ebx ; EDX:EAX = FFFFFFFF86635D80h, OF=0 OF=0 因為EDX 是一個有號延伸EAX.
習題. . . 什麼將是 DX ,AX的十六進位值,和進位標旗在下列的指令執行之後? mov ax,8760h mov bx,100h imul bx DX = FF87h, AX = 6000h, OF = 1
DIV 指令 • DIV (無號的除法運算 )指令用於執行 8 位元、16 位元和 32 位元的無號整數除法運算 • 一個運算元被供應 (暫存器或者記憶運算元), 這被假定是除數 • 指令表格: DIV r/m8 DIV r/m16 DIV r/m32
指令執行的是 32 位元無號數除法運算: mov edx,0 ; clear dividend, high mov eax,8003h ; dividend, low mov ecx,100h ; divisor div ecx ; EAX = 00000080h, DX = 3 DIV 例題 指令執行16 位元無號數除法運算 (8003h / 100h): mov dx,0 ; clear dividend, high mov ax,8003h ; dividend, low mov cx,100h ; divisor div cx ; AX = 0080h, DX = 3
習題. . . 什麼將是 DX 和AX的十六進位值在下列的指令行之後? ?或,如果除法溢位發生,你能指出那當做你的答案: mov dx,0087h mov ax,6000h mov bx,100h div bx DX = 0000h, AX = 8760h
習題. . . 什麼將是 DX 和AX的十六進位值在下列的指令行之後? ?或,如果除法溢位發生,你能指出那當做你的答案: mov dx,0087h mov ax,6002h mov bx,10h div bx Divide Overflow
有號整數除法 • 有號整數一定是符號延伸在除法發生之前 • 高的位元組/字/雙字組複製符號教低位元組/字/雙字組 • 舉例來說,高的位元組包含符號的複製從低的位元組:
CBW, CWD, CDQ 指令 • CBW, CWD, 和 CDQ指令提供 • 重要的有號延長的運算: • CBW (將位元組轉換成字組)將 AL 的符號 位元,延伸到 AH • CWD (將字組轉換成雙字組)將 AX 的符號位元,延伸進 DX • CDQ (將雙字組轉換成四字組)將EAX 的符號位元,延伸進 EDX • 舉例: mov eax,0FFFFFF9Bh cdq ; EDX:EAX = FFFFFFFFFFFFFF9Bh
IDIV 指令 • IDIV (有號除法 )有號整數除法運算 • 使用的運算元與 DIV 一樣 例題: 8-bit指令會將 -48 除以 5。 mov al,-48 cbw ; extend AL into AH mov bl,5 idiv bl ; AL = -9, AH = -3
Example: 32-bit -48除以5 mov eax,-48 cdq ; extend EAX into EDX mov ebx,5 idiv ebx ; EAX = -9, EDX = -3 IDIV 例題 Example: 16-bit -48除以5 mov ax,-48 cwd ; extend AX into DX mov bx,5 idiv bx ; AX = -9, DX = -3
習題. . . 什麼將是 DX 和AX的十六進位值在下列的指令執行之後?或,如果除法溢位發生,寫出你的答案: mov ax,0FDFFh ; -513 cwd mov bx,100h idiv bx DX = FFFFh (-1), AX = FFFEh (-2)
例題: var4 = (var1 + var2) * var3 mov eax,var1 add eax,var2 mul var3 joTooBig ; check for overflow mov var4,eax ; save product 實作算術運算式(1 of 3) • 一些好推論學習該如何推做語法: • 學習如何編輯 • 測試你的 MUL , IMUL , DIV 和 IDIV 的理解 • 32位元溢位的檢查
例題: var4 = (var1 * 5) / (var2 – 3) mov eax,var1 ; left side mov ebx,5 mul ebx ; EDX:EAX = product mov ebx,var2 ; right side sub ebx,3 div ebx ; final division mov var4,eax 實作算術運算式(2 of 3) 例題: eax = (-var1 * var2) + var3 mov eax,var1 neg eax mul var2 jo TooBig ; check for overflow add eax,var3
實作算術運算式(3 of 3) 例題: var4 = (var1 * -5) / (-var2 % var3); mov eax,var2 ; begin right side neg eax cdq ; sign-extend dividend idiv var3 ; EDX = remainder mov ebx,edx ; EBX = right side mov eax,-5 ; begin left side imul var1 ; EDX:EAX = left side idiv ebx ; final division mov var4,eax ; quotient 有時首先計算語法用右手術語是最容易的。
習題. . . 實作下列語法使用有號32位元整數 eax = (ebx * 20) / ecx mov eax,20 mul ebx div ecx
習題. . . 實作下列語法使用有號32位元整數.貯存而且回復 ECX 和 EDX : eax = (ecx * edx) / eax push ecx push edx push eax ; EAX needed later mov eax,ecx mul edx ; left side: EDX:EAX pop ecx ; saved value of EAX div ecx ; EAX = quotient pop edx ; restore EDX, ECX pop ecx
習題. . . 實作下列語法使用有號32位元整數.不要修正任何變數除了 var3 : var3 = (var1 * -var2) / (var3 – ebx) mov eax,var1 mov edx,var2 neg edx mul edx ; left side: edx:eax mov ecx,var3 sub ecx,ebx div ecx ; eax = quotient mov var3,eax
延伸ASCII加法與減法 • ADC 指令 • 延伸加法例題 • SBB 指令