指令格式
1.指令的书写格式
标号: 指令助记符 操作数 ; 注释
2.操作数的3种形式:
立即操作数:指令的操作数是立即数,并直接出现在指令中。
寄存器操作数:操作数是寄存器的值,指令中使用寄存器名。
内存操作数:操作数是某个内存单元的值,指令中给出有效地址EA,段地址在某个段寄存器中。
1.立即数: 8位或16位立即数。
2.寄存器操作数:
8位/16位通用寄存器和段寄存器(除了FS和GS)。
3.内存操作数
包括下列几种形式。
Variable 或 [Variable]
[reg]
disp[reg]
[base][index]
disp[base][index]
?***说明:
Variable是变量名或变量名 ± 整数表达式。
reg为BX、BP、SI、DI。
disp可以是常量或变量,汇编后为一个常数,若是变量,则取其偏移地址。
base为BX或BP,index为SI或DI。
有效地址为各项之和。如disp[base][index]形式,EA = base + index + disp。
若使用了BP,则隐含段地址在SS,否则在DS。
当段地址不在隐含的段寄存器时,可使用段超越前缀,形式为:段寄存器名:
1.立即数: 32位立即数。
2.寄存器操作数: 32位通用寄存器以及FS和GS。
3.内存操作数
包括下列几种形式。
[base]
disp[base]
[base][index]
disp[base][index]
[index*n]
disp[index*n]
[base][index*n]
disp[base][index*n]
***说明:
base、index为任一32位通用寄存器(index不能取ESP)。
n为比例因子,取1、2、4或8。
若包含base且base为EBP或ESP,则隐含段地址在SS;否则,隐含段地址在DS。
若在16位CPU上编程,则不能使用这些寻址方式。
为了描述方便,采用下列符号约定:
dest — 目的操作数
src — 源操作数
oprdn — 第n个操作数,如oprd1, oprd2, oprd3
= — 赋值
/ — 或者
reg8 — 8位通用寄存器AH/AL/BH/BL/CH/CL/DH/DL
reg16 — 16位通用寄存器AX/BX/CX/DX/SI/DI/BP/SP
reg32 — 32位通用寄存器EAX/EBX/ECX/EDX/ESI/EDI/EBP/ESP
reg — reg8/reg16/reg32
seg — 段寄存器CS/DS/SS/ES/FS/GS
mem8 — 8位内存操作数
mem16 — 16位内存操作数
mem32 — 32位内存操作数
mem — mem8/mem16/mem32
mem64 — 64位内存操作数
imm8 — 8位立即数
imm16 — 16位立即数
imm32 — 32位立即数
imm — imm8/imm16/imm32
1. MOV ( Move ):传送
一般形式:
MOV dest, src ; dest = src。将源操作数src复制到目的操作数dest,src不变。
语法格式:
MOV reg/mem/seg, reg/mem/seg/imm
对标志位的影响:无。
说明:
dest与src不能作如下搭配:
MOV mem, mem ; 错误
MOV seg, seg ; 错误
MOV seg, imm ; 错误
dest不能是CS。
dest与src必须类型匹配,即同时是字节、字或双字类型。
2. XCHG ( Exchange ):交换
一般形式:
XCHG oprd1, oprd2 ; 交换oprd1与oprd2的内容
语法格式:
XCHG reg/mem, reg/mem
对标志位的影响:无。
说明:
oprd1与oprd2不能作如下搭配:
XCHG mem, mem ; 错误
oprd1与oprd2类型必须匹配。、
【例】
xchg ebx, edx
xchg [ebp][eax*4], edx
3. LEA (Load Effective Address ) :装入有效地址
语法格式:
LEA reg16, mem ; reg16 = mem的有效地址
对标志位的影响:无。
【例】设BX = 5678H,EAX = 1,EDX = 2。
lea si, 2[bx] ; 执行后,SI = 567AH
lea si, 2[eax][edx] ; 执行后,SI = 5
4. LDS、LES
语法格式:
LDS reg16, mem32 ; reg16 = mem32的低字,DS = mem32的高字
LES reg16, mem32 ; reg16 = mem32的低字,ES = mem32的高字
对标志位的影响:无。
5. 堆栈操作指令
80x86系统的堆栈具有如下特点:
堆栈是在内存的堆栈段中,具有“先进后出”的特点。
堆栈只有一个出入口,即当前栈顶。当堆栈为空时,栈顶和栈底指向同一内存单元。
堆栈有两个基本操作:PUSH(进栈)和POP(出栈)。PUSH操作使栈顶向低地址方向移动,而POP操作则刚好相反。
堆栈操作只能以字或双字为单位。
SS:SP指向栈顶。
(1)PUSH与POP:进栈与出栈
语法格式:
PUSH reg16/seg/mem16/ reg32/mem32
POP reg16/seg/mem16/ reg32/mem32 ; 操作数不能是CS
PUSH imm ; 286新增
功能描述:
PUSH指令(16位):
SP = SP - 2
SS:[SP] = 16位操作数
POP指令(16位):
16位操作数 = SS:[SP]
SP = SP + 2
PUSH指令(32位):
SP = SP - 4
SS:[SP] = 32位操作数
POP指令(32位):
32位操作数 = SS:[SP]
SP = SP + 4
对标志位的影响:无。
(2)PUSHF与POPF:标志寄存器进栈和出栈
语法格式:
PUSHF ; FLAGS进栈
POPF ; 栈顶字出栈到FLAGS
对标志位的影响:只有POPF指令会以弹出值设置标志寄存器。
【例】设SP = 100H, EBX = 12345678H, 给出下列指令依次执行后的结果。
push bx ; ss:[00ffh] = 56h, ss:[00feh] = 78h, sp = 0feh
pop ax ; ax = 5678h, sp = 100h
push ebx ; ss:[00feh] = 1234h, ss:[00fch] = 5678h, sp = 0fch
pop ax ; ax = 5678h, sp = 0feh
pop ax ; ax = 1234h, sp = 100h
【例】交换AX与CX的值。
push ax
push cx
pop ax
pop cx
6. 标志寄存器传送指令
(1)LAHF(Load AH from Flags)
语法格式:
LAHF ; AH = FLAGS的低8位
对标志位的影响:无。
?
(2)SAHF(Store AH into Flags)
语法格式:
SAHF ; FLAGS的低8位 = AH
对标志位的影响:由新装入值确定。
符号扩展与零扩展指令
(1)CBW、CWD、CWDE与CDQ
语法格式:
CBW ; AL符号扩展为AX
CWD ; AX符号扩展为32位数DX:AX
CWDE ; AX符号扩展为EAX;386新增
CDQ ; EAX符号扩展为64位数EDX:EAX;386新增
【例】设AL = 0FEH,给出依次执行下列指令后的结果。
cbw ; ax = 0fffeh
cwd ; dx = 0ffffh, ax不变,即dx:ax = -2
cwde ; eax = 0fffffffeh(-2)
cdq ; edx = 0ffffffffh, eax不变,即edx:eax = -2
(2)MOVSX
一般形式:
MOVSX dest, src ; src符号扩展为dest;386新增
语法格式:
MOVSX reg16, reg8/mem8
MOVSX reg32, reg8/mem8/reg16/mem16
功能描述:MOVSX是CBW、CWD和CWDE的一般形式,用来将8位数符号扩展为16位或32位数,或者将16位数符号扩展为32位数。
【例】 CBW和CWDE的功能可由MOVSX指令实现。
movsx ax, al ; 等价于cbw
movsx eax, ax ; 等价于cwde
movsx eax, al ; 等价于顺序执行cbw与cwde
(3)MOVZX
一般形式:
MOVZX dest, src ; src零扩展为dest;386新增
语法格式:
MOVZX reg16, reg8/mem8
MOVZX reg32, reg8/mem8/reg16/mem16
8. XLAT(Translate):换码
语法格式:
XLAT ; AL = DS:[ BX +AL ]
功能描述:将DS:BX所指内存区中、由AL指定位移处的一个字节赋给AL。
对标志位的影响:无。
算术指令
1. 加法
一般形式:
ADD dest, src ; dest = dest + src
ADC dest, src ; dest = dest + src + CF
INC dest ; dest = dest + 1
语法格式:
ADD reg/mem, reg/mem/imm
ADC reg/mem, reg/mem/imm
INC reg/mem
对标志位的影响:
ADD、ADC:按一般规则影响CF、OF、SF和ZF。
INC:不影响CF,其它同ADD。
说明:ADD与ADC的2个操作数必须类型匹配,且不能同时是内存操作数。
2. 减法
一般形式:
SUB dest, src ; dest = dest – src
SBB dest, src ; dest = dest - src – CF
CMP dest, src ; dest – src。 与SUB的区别在于,不将减法结果存入dest。
DEC dest ; dest = dest - 1
NEG dest ; dest = 0 – dest
语法格式:
SUB reg/mem, reg/mem/imm
SBB reg/mem, reg/mem/imm
CMP reg/mem, reg/mem/imm
DEC reg/mem
NEG reg/mem
对标志位的影响:
SUB、SBB、CMP、NEG:按一般规则影响CF、OF、SF和ZF。CF表示借位。
DEC:不影响CF,其它同SUB。
说明:2个操作数必须类型匹配,且不能同时是内存操作数。
3. 乘法
(1)MUL(Unsigned Multiplication):无符号乘法
一般形式:
MUL src
语法格式:
MUL reg8/mem8 ; AX = AL × src
MUL reg16/mem16 ; DX:AX = AX × src
MUL reg32/mem32 : EDX:EAX = EAX × src
对标志位的影响:若8位×8位、16位×16位或32位×32位的结果分别能由8、16或32位容纳(即结果的高一半为0),则CF = OF = 0,否则,CF = OF = 1;其余标志无定义。
说明:由于2个n位数的乘积可能需要2n位,因此,若操作数是8位,则结果为16位;同样,16位操作数相乘结果为32位,32位数相乘结果为64位。
(2)IMUL(Integer Multiplication):带符号乘法
一般形式:
IMUL src
语法格式:
IMUL reg8/mem8 ; AX = AL × src。执行带符号乘法,下同。
IMUL reg16/mem16 ; DX:AX = AX × src
IMUL reg32/mem32 : EDX:EAX = EAX × src
对标志位的影响:若结果的高一半为低一半的符号扩展,则CF = OF = 0,否则,CF = OF = 1;其余标志无定义。
说明:由于2个n位数的乘积可能需要2n位,因此,若操作数是8位,则结果为16位;同样,16位操作数相乘结果为32位,32位数相乘结果为64位。
【例】对于同一个二进制数,采用 MUL与IMUL执行的结果可能不同。设AL = 0FFH,BL = 1,分别执行下列指令,会得出不同结果。
mul bl ; ax = 0ffh(255)
imul bl ; ax = 0ffffh(-1)
4. 除法
一般形式:
DIV src ; 无符号数除法
IDIV src ; 带符号数除法
语法格式:
DIV reg/mem
IDIV reg/mem
功能描述:
src是8位:AX÷src,结果商在AL、余数在AH。
src是16位:DX:AX÷src,结果商在AX、余数在DX。
src是32位:EDX:EAX÷src,结果商在EAX、余数在EDX。
对标志位的影响:无定义。
5.十进制调整指令
(1)压缩BCD码调整指令
语法格式:
DAA ; 调整AL中的和为压缩BCD码
DAS ; 调整AL中的差为压缩BCD码
功能描述:
DAA:通常先执行ADD/ADC指令,将2个压缩BCD码相加,结果存放在AL中。然后使用该指令将AL调整为压缩BCD码格式。
DAS:通常先执行SUB/SBB指令,将2个压缩BCD码相减,结果存放在AL中。然后使用该指令将AL调整为压缩BCD码格式。
对标志位的影响:OF不确定;CF反映压缩BCD码相加/相减的进位/借位状态;按一般规则影响SF和ZF。
说明:若使用DAA/DAS指令,则参加加法/减法运算的操作数应该是压缩BCD码。如果将任意2个二进制数相加/减,然后调整,将得不到正确结果。
DAA的调整算法如下:
if ( AL低4位 > 9 或 AF = 1) then
AL = AL + 6;
AF = 1 ;
endif
if ( AL高4位 > 9 或 CF = 1 ) then
AL = AL + 60H;
CF = 1;
endif
DAS的调整算法如下:
if ( AL低4位 > 9 或 AF = 1 ) then
AL = AL – 6;
AF = 1;
endif
if ( AL高4位 > 9 或 CF = 1 ) then
AL = AL - 60h;
CF = 1;
endif
(2)非压缩BCD码调整指令
语法格式:
AAA ; 调整AL中的和为非压缩BCD码
; 调整后,AL高4位 = 0,AH = AH + 产生的CF
AAS ; 调整AL中的差为非压缩BCD码
; 调整后,AL高4位 = 0,AH = AH - 产生的CF
AAM ; AH = AX div 10,AL = AX mod 10
AAD ; AL = AH × 10 + AL,AH = 0
功能描述:
AAA:通常先执行ADD/ADC指令,以AL为目的操作数,将2个非压缩BCD码(高4位无关)相加。然后使用AAA将AL调整为非压缩BCD码格式,且高4位 = 0,同时将调整产生的进位加到AH中。
AAS:通常先执行SUB/SBB指令,以AL为目的操作数,将2个非压缩BCD码(高4位无关)相减。然后使用AAS将AL调整为非压缩BCD码格式,且高4位 = 0,同时将调整产生的借位从AH中减去。
AAM与AAD:略。
对标志位的影响:
AAA与AAS:CF反映非压缩BCD码加/减的进位/借位;OF、SF和ZF不确定。
AAA的调整算法如下:
if ( AL低4位 > 9 或 AF = 1 ) then
AL = AL + 6;
AH = AH + 1;
AF = 1;
CF = 1;
else
AF = 0;
CF = 0;
endif
AL = AL AND 0FH ; AL高4位清0
AAS的调整算法如下:
if ( AL低4位 > 9 或 AF = 1) then
AL = AL – 6;
AH = AH – 1;
AF = 1;
CF = 1;
else
AF = 0;
CF = 0;
endif
AL = AL AND 0FH ; AL高4位清0