汇编语言第二章.docx
《汇编语言第二章.docx》由会员分享,可在线阅读,更多相关《汇编语言第二章.docx(57页珍藏版)》请在冰点文库上搜索。
汇编语言第二章
第二章8086的指令系统
一汇编语言指令格式
⒈格式
标号:
指令助记符目的操作数,源操作数;注释
⒉说明
●标号表示该指令在主存中的逻辑地址
注意:
在此处应该解释一下逻辑地址和物理地址以及偏移地址的概念。
●注意:
每个指令助记符就代表一种指令
●目的和源操作数表示参与操作的对象
●注释是对该指令或程序段功能的说明
⒊操作数的表达
r8——任意一个8位通用寄存器
AHALBHBLCHCLDHDL
r16——任意一个16位通用寄存器
AXBXCXDXSIDIBPSP
reg——代表r8或r16
seg——段寄存器CS/DS/ES/SS
m8——一个8位存储器操作数单元(所有主存寻址方式)
m16——一个16位存储器操作数单元(所有主存寻址方式)
mem——代表m8或m16
i8——一个8位立即数
i16——一个16位立即数
imm——代表i8或i16
dest——目的操作数
src——源操作数
二8086指令系统概述
Intel8086指令系统共有117条基本指令,可分成6个功能组
①数据传送类指令
②算术运算类指令
③位操作类指令
④串操作类指令
⑤控制转移类指令
⑥处理机控制类指令
三学习指令的注意事项
指令的功能——该指令能够实现何种操作。
通常指令助记符就是指令功能的英文单词或其缩写形式
指令支持的寻址方式——该指令中的操作数可以采用何种寻址方式
指令对标志的影响——该指令执行后是否对各个标志位有影响,以及如何影响
其他方面——该指令其他需要特别注意的地方,如指令执行时的约定设置、必须预置的参数、隐含使用的寄存器等
提示:
全面而准确地理解每条指令的功能和应用,是编写汇编语言程序的关键
四数据传送类指令
数据传送是计算机中最基本、最重要的一种操作
传送指令也是最常使用的一类指令
传送指令把数据从一个位置传送到另一个位置
除标志寄存器传送指令外,均不影响标志位
重点掌握
MOVXCHGXLATPUSHPOPLEA
⒈通用数据传送指令
Ø提供方便灵活的通用传送操作
有3条指令
MOV
XCHG
XLAT
①传送指令MOV(move)
Ø把一个字节或字的操作数从源地址传送至目的地址
MOVreg/mem,imm
;立即数送寄存器或主存
moval,4;al←4,字节传送
movcx,0ffh;cx←00ffh,字传送
movsi,200h;si←0200h,字传送
movbyteptr[si],0ah
;byteptr说明是字节操作
movwordptr[si+2],0bh
;wordptr说明是字操作
注意:
立即数是字节量还是字量;
明确指令是字节操作还是字操作
MOVreg/mem/seg,reg
;寄存器送(段)寄存器或主存
movax,bx;ax←bx,字传送
movah,al;ah←al,字节传送
movds,ax;ds←ax,字传送
mov[si],al;[si]←al,字节传送
MOVreg/seg,mem
;主存送(段)寄存器
moval,[bx]
movdx,[bp];dx←ss:
[bp]
moves,[si];es←ds:
[si]
注意:
不存在存储器向存储器的传送指令
MOVreg/mem,seg
;段寄存器送寄存器或主存
mov[si],ds
movax,es;ax←es
movds,ax;ds←ax←es
注意:
对段寄存器的操作有一些限制
Ø非法传送种种
Ø两个操作数的类型不一致
⏹例如源操作数是字节,而目的操作数是字;或相反
例:
情况1:
绝大多数双操作数指令,除非特别说明,目的操作数与源操作数必须类型一致,否则为非法指令
MOVAL,050AH
;非法指令:
050Ah为字,而AL为字节
情况2:
寄存器有明确的字节或字类型,有寄存器参与的指令其操作数类型就是寄存器的类型
情况3:
对于存储器单元与立即数同时作为操作数的情况,必须显式指明;byteptr指示字节类型,wordptr指示字类型
Ø两个操作数不能都是存储器
⏹传送指令很灵活,但主存之间的直接传送却不允许
8086指令系统不允许两个操作数都是存储单元(除串操作指令),要实现这种传送,可通过寄存器间接实现
movax,buffer1
;ax←buffer1(将buffer1内容送ax)
movbuffer2,ax
;buffer2←ax
;这里buffer1和buffer2是两个字变量
;实际表示直接寻址方式
Ø段寄存器的操作有一些限制
⏹段寄存器属专用寄存器,对他们的操作能力有限
情况1:
不允许立即数传送给段寄存器
MOVDS,100H
;非法指令:
立即数不能传送段寄存器
情况2:
不允许直接改变CS值
MOVCS,[SI];不允许使用的指令
情况3:
不允许段寄存器之间的直接数据传送
MOVDS,ES
;非法指令:
不允许段寄存器间传送
②交换指令XCHG(exchange)
Ø把两个地方的数据进行互换
XCHGreg,reg/mem
;regreg/mem
⏹寄存器与寄存器之间对换数据
⏹寄存器与存储器之间对换数据
⏹不能在存储器与存储器之间对换数据
例:
寄存器间交换
movax,1234h;ax=1234h
movbx,5678h;bx=5678h
xchgax,bx
;ax=5678h,bx=1234h
xchgah,al;ax=7856h
例:
寄存器与存储器交换
xchgax,[2000h];字交换
;等同于xchg[2000h],ax
xchgal,[2000h];字节交换
;等同于xchg[2000h],al
③换码指令XLAT(translate)
功能:
将BX指定的缓冲区中、AL指定的位移处的一个字节数据取出赋给AL
XLAT;al←ds:
[bx+al]
例:
代码转换
movbx,100h
moval,03h
xlat
Ø换码指令执行前:
在主存建立一个字节量表格,内含要转换成的目的代码
表格首地址存放于BX,AL存放相对表格首地址的位移量
Ø换码指令执行后:
将AL寄存器的内容转换为目标代码
④堆栈操作指令
Ø堆栈是一个“后进先出FILO”(或说“先进后出FILO”)的主存区域,位于堆栈段中;SS段寄存器记录其段地址
Ø堆栈只有一个出口,即当前栈顶;用堆栈指针寄存器SP指定
Ø栈顶是地址较小的一端(低端),栈底不变
堆栈的操作:
堆栈只有两种基本操作:
进栈和出栈,对应两条指令PUSH和POP
POP
;出栈指令把栈顶的一个字传送至指定的目的操作数,然后堆栈指针SP加2
PUSH
;进栈指令先使堆栈指针SP减2,然后把一个字操作数存入堆栈顶部
注意演示
格式:
PUSHr16/m16/seg
;SP←SP-2
;SS:
[SP]←r16/m16/seg
例:
pushax
push[2000h]
格式:
POPr16/m16/seg
;r16/m16/seg←SS:
[SP]
;SP←SP+2
例:
popax
pop[2000h]
堆栈的特点:
Ø堆栈操作的单位是字,进栈和出栈只对字量
Ø字量数据从栈顶压入和弹出时,都是低地址字节送低字节,高地址字节送高字节
Ø堆栈操作遵循先进后出原则,但可用存储器寻址方式随机存取堆栈中的数据
Ø堆栈常用来
例:
现场保护恢复
临时存放数据
传递参数
保存和恢复寄存器
pushax;进入子程序后
pushbx
pushds
...
popds;返回主程序前
popbx
popax
⒉标志寄存器传送指令
①概述
标志寄存器传送指令用来传送标志寄存器FLAGS的内容,方便进行对各个标志位的直接操作
有2对4条指令
n低8位传送:
LAHF和SAHF
n16位传送:
PUSHF和POPF
②标志低字节进出AH指令
LAHF
;AH←FLAGS的低字节
ØLAHF指令将标志寄存器的低字节送寄存器AH
ØSF/ZF/AF/PF/CF状态标志位分别送入AH的第7/6/4/2/0位,而AH的第5/3/1位任意
SAHF
;FLAGS的低字节←AH
ØSAHF将AH寄存器内容送FLAGS的低字节
Ø用AH的第7/6/4/2/0位相应设置SF/ZF/AF/PF/CF标志
③标志寄存器进出堆栈指令
PUSHF
;SP←SP-2
;SS:
[SP]←FLAGS
ØPUSHF指令将标志寄存器的内容压入堆栈,同时栈顶指针SP减2
POPF
;FLAGS←SS:
[SP]
;SP←SP+2
ØPOPF指令将栈顶字单元内容送标志寄存器,同时栈顶指针SP加2
例:
置位单步标志
pushf;保存全部标志到堆栈
popax;从堆栈中取出全部标志
orax,0100h;设置D8=TF=1,
;ax其他位不变
pushax;将ax压入堆栈
popf;FLAGS←AX
;将堆栈内容取到标志寄存器
⒊地址传送指令
1概述
Ø地址传送指令将存储器单元的逻辑地址送至指定的寄存器
n有效地址传送指令LEA
n指针传送指令LDS和LES
Ø注意不是获取存储器单元的内容
2有效地址传送指令LEA(loadEA)
将存储器操作数的有效地址传送至指定的16位寄存器中
格式:
LEAr16,mem
;r16←mem的有效地址EA
例:
获取有效地址
movbx,0400h
movsi,3ch
leabx,[bx+si+0f62h]
;BX=0400h+003ch+0f62h=139EH
说明:
获得主存单元的有效地址;不是物理地址,也不是该单元的内容
可以实现计算功能
3指针传送指令
LDSr16,mem
;r16←mem,
;DS←mem+2
ØLDS指令将主存中mem指定的字送至r16,并将mem的下一字送DS寄存器
LESr16,mem
;r16←mem,
;ES←mem+2
ØLES指令将主存中mem指定的字送至r16,并将mem的下一字送ES寄存器
例:
地址指针传送
movwordptr[3060h],0100h
movwordptr[3062h],1450h
lesdi,[3060h];es=1450h,di=0100h
ldssi,[3060h];ds=1450h,si=0100h
说明:
mem指定主存的连续4个字节作为逻辑地址(32位的地址指针),送入DS:
r16或ES:
r16
⒋输入输出指令
①概述
Ø8086通过输入输出指令与外设进行数据交换;呈现给程序员的外设是端口(Port)即I/O地址
Ø8086用于寻址外设端口的地址线为16条,端口最多为216=65536(64K)个,端口号为0000H~FFFFH
Ø每个端口用于传送一个字节的外设数据
②输入指令IN
4
5
6
①概述
将外设数据传送给CPU内的AL/AX
格式1:
INAL,i8
注意演示
;字节输入:
AL←I/O端口(i8直接寻址)
格式2:
INAL,DX
;字节输入:
AL←I/O端口(DX间接寻址)
格式3:
INAX,i8
;字输入:
AX←I/O端口(i8直接寻址)
格式4:
INAX,DX
;字输入:
AX←I/O端口(DX间接寻址)
例:
输入字量
;直接寻址,字节量输入
●两段功能相同
●字量数据传送实际上实现了连续的两个端口地址的字节量传送
inal,21h
movah,al
inal,20h
;直接寻址,字量输入
inax,20h
;间接寻址,字量输入
movdx,20h
inax,dx
②输出指令OUT
将CPU内的AL/AX数据传送给外设
格式1:
OUTi8,AL
;字节输出:
I/O端口←AL(i8直接寻址)
格式2:
OUTDX,AL
;字节输出:
I/O端口←AL(DX间接寻址)
格式3:
OUTi8,AX
;字输出:
I/O端口←AX(i8直接寻址)
格式4:
OUTDX,AX
;字输出:
I/O端口←AX(DX间接寻址)
例:
输出字节量
;间接寻址,字节量输出
movdx,3fch
moval,80h
outdx,al
⒌算术运算类指令
①概述
Ø四则运算是计算机经常进行的一种操作。
算术运算指令实现二进制(和十进制)数据的四则运算
Ø请注意算术运算类指令对标志的影响
⏹掌握:
ADD/ADC/INC、SUB/SBB/DEC/NEG/CMP
⏹熟悉:
MUL/IMUL、DIV/IDIV
⏹理解:
CBW/CWD、DAA/DAS、AAA/AAS/AAM/AAD
②加法指令ADD
说明:
ØADD指令将源与目的操作数相加,结果送到目的操作数
ØADD指令按状态标志的定义相应设置
格式:
ADDreg,imm/reg/mem
;reg←reg+imm/reg/mem
ADDmem,imm/reg
;mem←mem+imm/reg
例:
加法运算
moval,0fbh;al=0fbh
addal,07h;al=02h
movwordptr[200h],4652h
;[200h]=4652h
movbx,1feh;bx=1feh
addal,bl;al=00h
addwordptr[bx+2],0f0f0h
;[200h]=3742h
③带进位加法指令ADC
说明:
ØADC指令将源与目的操作数相加,再加上进位CF标志,结果送到目的操作数
ØADC指令按状态标志的定义相应设置
ØADC指令主要与ADD配合,实现多精度加法运算
格式:
ADCreg,imm/reg/mem
;reg←reg+imm/reg/mem+CF
ADCmem,imm/reg
;mem←mem+imm/reg+CF
例:
双字加法
movax,4652h;ax=4652h
addax,0f0f0h;ax=3742h,CF=1
movdx,0234h;dx=0234h
adcdx,0f0f0h;dx=f325h,CF=0
;DX.AX=02344652H
+F0F0F0F0H
=F3253742H
④增量指令INC(increment)
说明:
ØINC指令对操作数加1(增量)
ØINC指令不影响进位CF标志,按定义设置其他状态标志
格式:
INCreg/mem
;reg/mem←reg/mem+1
例:
incbx
incbyteptr[bx]
⑤减法指令SUB(subtract)
说明:
ØSUB指令将目的操作数减去源操作数,结果送到目的操作数
ØSUB指令按照定义相应设置状态标志
格式:
SUBreg,imm/reg/mem
;reg←reg-imm/reg/mem
SUBmem,imm/reg
;mem←mem-imm/reg
例:
减法运算
moval,0fbh;al=0fbh
subal,07h;al=0f4h,CF=0
movwordptr[200h],4652h
;[200h]=4652h
movbx,1feh;bx=1feh
subal,bl;al=0f6h
subwordptr[bx+2],0f0f0h
;[200h]=5562h,CF=1
7带借位减法指令SBB
说明:
ØSBB指令将目的操作数减去源操作数,再减去借位CF(进位),结果送到目的操作数。
ØSBB指令按照定义相应设置状态标志
ØSBB指令主要与SUB配合,实现多精度减法运算
格式:
SBBreg,imm/reg/mem
;reg←reg-imm/reg/mem-CF
SBBmem,imm/reg
;mem←mem-imm/reg-CF
例:
双字减法
movax,4652h;ax=4652h
subax,0f0f0h;ax=5562h,CF=1
movdx,0234h;dx=0234h
sbbdx,0f0f0h;dx=1143h,CF=1
;DX.AX=02344652H
-F0F0F0F0H
=11435562H
8减量指令DEC(decrement)
说明:
ØDEC指令对操作数减1(减量)
ØDEC指令不影响进位CF标志,按定义设置其他状态标志
格式:
DECreg/mem
;reg/mem←reg/mem-1
注意:
●INC指令和DEC指令都是单操作数指令
●主要用于对计数器和地址指针的调整
9求补指令NEG(negative)
说明:
ØNEG指令对操作数执行求补运算:
用零减去操作数,然后结果返回操作数
Ø求补运算也可以表达成:
将操作数按位取反后加1
ØNEG指令对标志的影响与用零作减法的SUB指令一样
格式:
NEGreg/mem
;reg/mem←0-reg/mem
例:
求补运算
movax,0ff64h
negal
;ax=ff9ch,OF=0、SF=1、ZF=0、PF=1、CF=1
subal,9dh
;ax=ffffh,OF=0、SF=1、ZF=0、PF=1、CF=1
negax
;ax=0001h,OF=0、SF=0、ZF=0、PF=0、CF=1
decal
;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=1
negax
;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=0
10比较指令CMP(compare)
说明:
ØCMP指令将目的操作数减去源操作数,按照定义相应设置状态标志
ØCMP指令执行的功能与SUB指令,但结果不回送目的操作数
格式:
CMPreg,imm/reg/mem
;reg-imm/reg/mem
CMPmem,imm/reg
;mem-imm/reg
例:
比较AL与100
cmpal,100;al-100
jbbelow
;al<100,跳转到below执行
subal,100
;al≥100,al←al-100
incah;ah←ah+1
below:
...
注意:
执行比较指令之后,可以根据标志判断两个数是否相等、大小关系等
11
12
⑾乘法指令
无符号乘法:
MULr8/m8
;无符号字节乘法
;AX←AL×r8/m8
MULr16/m16
;无符号字乘法
;DX.AX←AX×r16/m16
有符号乘法:
IMULr8/m8
;有符号字节乘法
;AX←AL×r8/m8
IMULr16/m16
;有符号字乘法
;DX.AX←AX×r16/m16
乘法指令的功能:
Ø乘法指令分无符号和有符号乘法指令
Ø乘法指令的源操作数显式给出,隐含使用另一个操作数AX和DX
⏹字节量相乘:
AL与r8/m8相乘,得到16位的结果,存入AX
⏹字量相乘:
AX与r16/m16相乘,得到32位的结果,其高字存入DX,低字存入AX
Ø乘法指令利用OF和CF判断乘积的高一半是否具有有效数值
Ø乘法指令如下影响OF和CF标志:
⏹MUL指令——若乘积的高一半(AH或DX)为0,则OF=CF=0;否则OF=CF=1
⏹IMUL指令——若乘积的高一半是低一半的符号扩展,则OF=CF=0;否则均为1
Ø乘法指令对其他状态标志没有定义
注意:
对标志没有定义:
指令执行后这些标志是任意的、不可预测(就是谁也不知道是0还是1);
对标志没有影响:
指令执行不改变标志状态
例:
乘法运算
moval,0b4h;al=b4h=180
movbl,11h;bl=11h=17
mulbl;ax=Obf4h=3060
;OF=CF=1,AX高8位不为0
moval,0b4h;al=b4h=-76
movbl,11h;bl=11h=17
imulbl;ax=faf4h=-1292
;OF=CF=1,AX高8位含有效数字
⑿除法指令
无符号除法:
DIVr8/m8;无符号字节除法:
AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数
DIVr16/m16;无符号字除法:
;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数
有符号除法:
IDIVr8/m8;有符号字节除法:
AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数
IDIVr16/m16;有符号字除法:
;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数
除法指令的功能:
Ø除法指令分无符号和有符号除法指令
Ø除法指令的除数显式给出,隐含使用另一个操作数AX和DX作为被除数
⏹字节量除法:
AX除以r8/m8,8位商存入AL,8位余数存入AH
⏹字量除法:
DX.AX除以r16/m16,16位商存入AX,16位余数存入DX
Ø除法指令对标志没有定义
Ø除法指令会产生结果溢出
除法错中断
:
Ø当被除数远大于除数时,所得的商就有可能超出它所能表达的范围。
如果存放商的寄存器AL/AX不能表达,便产生溢出,8086CPU中就产生编号为0的内部中断——除法错中断
⏹对DIV指令,除数为0,或者在字节除时商超过8位,或者在字除时商超过16位,则发生除法溢出
⏹对IDIV指令,除数为0,或者在字节除时商不在-128~127范围内,或者在字除时商不在-32768~32767范围内,则发生除法溢出
例:
除法运算
movax,0400h;ax=400h=1024
movbl,0b4h;bl=b4h=180
divbl;商al=05h=5
;余数ah=7ch=124
movax,0400h;ax=400h=1024
movbl,0b4h;bl=b4h=-76
idivbl;商al=f3h=-13
;余数ah=24h=36
⒀符号扩展指令
CBW;AL的符号扩展至AH
;如AL的最高有效位是0,则AH=00
;AL的最高有效位为1,则AH=FFH。
AL不变
CWD;AX的符号扩展至DX
;如AX的最高有效位是0,则DX=00
;AX的最高有效位为1,则DX=FFFFH。
AX不变
Ø什么是符号扩展
Ø符号扩展是指用一个操作数的符号位(即最高位)形成另一个操作数,后一个操作数的各位是全0(正数)或全1(负数)。
符号扩展不改变数据大小
⏹对于数据64H(表示数据100),其最高位D7为0,符号扩展后高8位都是0,成为0064H(仍表示数据100)
⏹对于数据ff00H(表示有符号数-256),其最高位D15为1,符号扩展后高16位都是1,成为ffffff00H(仍表示有符号数