最近在学习 16位汇编编程,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习汇编开发的童鞋们提供一份参考。
运行环境:
- 操作系统: Windows 10家庭版
- 编译器:Windows XP Debug
算术运算类指令
掌握:ADD/ADC/INC、SUB/SBB/DEC/ NEG/CMP
熟悉:MUL/IMUL、DIV/IDIV
理解:CBW/CWD、DAA/DAS、 AAA/ AAS/AAM/AAD
加法指令ADD
1 | ADD reg,imm/reg/mem |
带进位加法指令ADC
ADC指令将源与目的操作数相加,再加上进位CF标志,
结果送到目的操作数 ADC指令按状态标志的定义相应设置
ADC指令主要与ADD配合,实现多精度加法运算
1 | ADC reg,imm/reg/mem |
增量指令INC(increment)
INC指令对操作数加1(增量)INC指令不影响进位CF标志,按定义设置其他状态标志
1 | INC reg/mem |
减法指令SUB(subtract)
- SUB指令将目的操作数减去源操作数,结果送到目的操作数
SUB指令按照定义相应设置状态标志
1 | SUB reg,imm/reg/mem |
带借位减法指令SBB
SBB指令将目的操作数减去源操作数,再减去借位CF(进位),结果送到目的操作数。
SBB指令按照定义相应设置状态标志
SBB指令主要与SUB配合,实现多精度减法运算
1 | SBB reg,imm/reg/mem |
demo:
1 | mov ax,4652h ;ax=4652h |
减量指令DEC(decrement)
DEC指令对操作数减1(减量)
DEC指令不影响进位CF标志,按定义设置其他状态标志
1 | DEC reg/mem |
INC指令和DEC指令都是单操作数指令主要用于对计数器和地址指针的调整
求补指令NEG(negative)
NEG指令对操作数执行求补运算:用零减去操作数,然后结果返回操作数
求补运算也可以表达成:将操作数按位取反后加1
NEG指令对标志的影响与用零作减法的SUB指令一样
1 | NEG reg/mem |
比较指令CMP(compare)
CMP指令将目的操作数减去源操作数,按照定义相应设置状态标志
CMP指令执行的功能与SUB指令相同,但结果不回送目的操作数
1 | CMP reg,imm/reg/mem |
乘法指令
不带符号位乘法(MUL)
1 | MUL r8/m8 |
带符号位的乘法(IMUL)
1 | IMUL r8/m8 |
MUL指令——若乘积的高一半(AH或DX)为0,则OF=CF=0;否则OF=CF=1
IMUL指令——若乘积的高一半是低一半的符号扩展,则OF=CF=0;否则均为1
除法指令
不带符号位的除法(DIV)
1 | DIV r8/m8 |
带符号位的除法(IDIV)
1 | DIV r8/m8 |
- 除法指令分无符号和有符号除法指令
- 除法指令的除数显式给出,隐含使用另一个操作数AX和DX作为被除数字节量除法:AX除以r8/m8,8位商存入AL,8位余数存入AH字量除法:DX.AX除以r16/m16,16位商存入AX,16位余数存入DX
- 除法指令对标志没有定义
- 除法指令会产生结果溢出
位移指令
左移指令(SHL)
使目的操作数逻辑左移一位,最低位用 0 填充。最高位移入进位标志位,而进位标志位中原来的数值被丢弃
若将 1100 1111 左移 1 位,该数就变为 1001 1110:
1 | SHL reg, imm8 |
位元乘法
数值进行左移(向 MSB 移动)即执行了位元乘法(Bitwise Multiplication)
1 | mov dl, 5 ; 移动前:00000101 = 5 |
右移指令(SHR)
使目的操作数逻辑右移一位,最高位用 0 填充。最低位复制到进位标志位,而进位标志位中原来的数值被丢弃
1 | mov al, 0D0h ; AL = 11010000b |
位元除法
数值进行右移(向 LSB 移动)即执行了位元除法(Bitwise Division)。
1 | mov dl, 32 ;移动前:00100000 = 32 |