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.