X86 匯編/算術

維基教科書,自由的教學讀本

二進制算術指令[編輯]

有帶進位或不帶進位的加減乘除,遞增,遞減和反號等指令.

二元算术指令   ; 靶 <- 靶 二元算术指令 源. 靶可为通存器或内存, 源可为通存器或立即数或内存若靶为通存器.

加法:
add   ; 靶 <- 靶 + 源. 置CF标志若溢出. 其逆操作为减法sub. 比较指令cmp操作同sub但不更新靶

add ax,bx    ; ax <- ax+bx
add ax,[si]  ; ax <- ax+[si]
add [di], ax ; [di] <- [di]+ax
add ax, 0x55 ; ax <- ax+0x55
add [身高], 1 ; [身高] <- [身高]+1

进位加: ; 其逆操作为借位减法sbb
adc ax,bx    ;  ax <- ax + bx + CF. 置CF标志若溢出

增1: ; 不影响CF. 其逆操作为降1 dec. 
inc ax ; ax <- ax+1
inc dword [bx] ; dword [bx] <- dword [bx] + 1

反号指令neg反转操作数符号:
neg ax ; ax <- -ax

换加:
xadd ax, bx ; 等价于 xchg ax, bx; add ax,bx

所有上述指令更新SF, ZF, PF  OF标志.

无号乘法mul:
mul X   ; AX<-AL*X当X为1字节, DX:AX<-AX*X当X为词, EDX:EAX<-EAX*X当X为双词. CF与OF被置位若积高半部分非零否则清零.

有号乘法imul有三种格式:
1. 单被操者. mul.
imul bl ; ax<-al*bl;
imul word [si] ; dx:ax<-ax*(word [si])
2. 双被操者. 靶为通存器, 源为通存器或内存或立即数.
imul bx,cx  ; bx<-bx*cx
imul bx,[si] ; bx<-bx*[si]
imul bx, 22; bx<-bx*22
3. 三被操者. 靶为通存器, 首源为通存器或内存, 次源为立即数.
imul ax,bx,22 ; ax<-bx*22
imul ax,[si],22 ; ax<-[si]*22

无号除法div: 除数,商和余数同尺寸, 被除数尺寸两倍之. 操作数规则同无号乘法
div 字节 ; AX为被除数, 结果AL为商, AH为余数
div    ; DX:AX为被除数, 结果AX为商, DX为余数
div 双词 ; EDX:EAX为被除数, 结果EAX为商, EDX为余数

有号除法idiv:
idiv 操作数 ; 加存器处以操作数. 寄存器使用及操作数规则同div.

十進制算術指令[編輯]

十進制數常用BCD(二進制編碼的十進制)碼表示, 四位二進制數的BCD碼為緊碼(packed), 表以一個字節的為非緊碼(松碼,unpacked). x86的十進制運算先用二進制算術指令計算, 再對結果進行十進制調整. 也可對輸入做調整. 十進制算術指令daa, das, aaa, aas沒有被操者. aam, aad的標準式也有被操者, 但其通用式有一個立即數被操者以指示生成的數字之基, 可將AX值變成任何基之兩位松碼.

助記符 全名 說明
daa 加後十進制調整, decimal adjust after addition 在兩對緊碼相加後, 調整AL值成有效緊碼. 若有進位則置CF
das 減後十進制調整, decimal adjust after subtraction 在兩對緊碼相減後, 調整AL值成有效緊碼. 若有借位則置CF
aaa 加後美碼調整, ASCII adjust after addition 在倆松碼相加後, 調整AL值成有效松碼並清其高四位. 若有進位則置CF並將AH增一
aas 減後美碼調整, ASCII adjust after subtraction 在倆松碼相減後, 調整AL值成有效松碼並清其高四位. 若有借位則置CF並將AH減一
aam 乘後美碼調整, ASCII adjust after multiplication 在兩松碼相乘後, 將AL值調成兩有效松碼. 高權位松碼留AH中, 低者留AL中.
aad 除後美碼調整, ASCII adjust before division 為使兩松碼相除得有效松碼, 調整AX中的值成除法運算的兩有效松碼操作數. 高權位松碼存AH中, 低者存AL中. 調整結果並存AL中, AH存0.