汇编语言与接口技术(第4版) 第3章 80*86指令系统和寻址方式 简易知识点
这一章是基础的核心内容,很重要,不会的话不太行容易寄
这里目前没有做80386相关的,只做了8086/8088相关的,如果后面我经常遇到会再补充
贴一个目录
8086/8088的寻址方式
首先一张图说明寻址
图片来源于慕课【https://www.icourse163.org/learn/ZZU-1001796025?tid=1468782468#/learn/announce】的PPT
但是这个慕课讲得太细致了很多听不懂,而且和这本书的结构可以说基本上完全不同,所以完全不建议去听
有没有什么好点儿的我能听懂的课安利给我谢谢谢谢
一、数据寻址方式
1.立即寻址,操作数为立即数
由于数据寄存器例如AX原本16位,具体在用的时候一般会拆成两个8位的高字节AH和低字节AL,所以在操作数为立即数的时候就会出现下面的两种情况
MOV AX, 0A7FH ;AX<-0A7FH,执行后,AH=0AH,AL=7FH
MOV AL, 5H ;AX<-5H
2. 寄存器寻址,操作数为寄存器操作数
寄存器寻址的指令本身存放在存储器的DS代码段,而操作数则在CPU寄存器中,所以指令执行过程中不用访问存储器,因此执行速度很快。
寄存器寻址可以进行16位操作数操作,也可以进行8位操作数操作。
MOV AX, BX
MOV AH, AL
3. 存储器寻址,操作数为存储器操作数
(1)直接寻址
会在指令的操作码后面直接给出操作数的16位偏移地址/有效地址EA。该有效地址与指令的操作码一起存放在内存的代码段(低位L在前,高位X在后)。操作数隐含数据段操作,存放在内存的DS中
MOV AX, [2000H]
此时2000H必须加上[],需要区别于上面的立即寻址,如果是2000H则是将AX=2000H进行立即寻址,而此时则是将一个地址为2000H的内存单元的内容传送给AX,但是具体里面的内容是啥需要看题给出DS段寄存器
Eg:DS=3000H,牵扯到EA,所以要进行“左移4位”(详见第2章课后题)。所以上式中实际有效的访问内存的物理地址为3000H*10H+2000H=32000H
(2)寄存器间接寻址
指令中的操作数存放在存储器中,存储单元的有效地址由寄存器BX、BP、SI、DI等指出,即为EX=基址/变址寄存器的内容,对寄存器指向的存储单元进行数据操作。用来存放存储器操作数偏移地址的寄存器称为地址指针
在以BX、SI、DI进行寄存器间接寻址时,隐含的数据段寄存器为DS
MOV AX,[BX] ;物理地址=DS*16+BX
MOV [DI],DX ;物理地址=DS*16+DI
在以BP进行寄存器间接寻址时,隐含的数据段寄存器为SS
MOV [BP], BX
允许段超越,可以使用上面约定为外的其他段寄存器
MOV AX,ES:[BX] ;物理地址=ES*16+BX
MOV DS:[BP], DX ;物理地址=DS*16+BP
(3)相对寄存器寻址
EA=基址/变址寄存器的内容±16/8位位移量
MOV AX.3003H{SI}
假设DS=3000H,SI=2000H,则指令操作的
存储器物理地址=3000H*10H+EA=30000H+2000H+3003=35003H
MOV SI,08H[BX] ;物理地址= DS*16+BX+08H
MOV AX,[BX+100H] ;物理地址= DS*16+BX+100H
MOV AL,[BP+08H] ;物理地址= SS*16+BP+08H
MOV 0200H[BP],AX ;物理地址= SS*16+BP+0200H
(4)基址、变址寻址
EA=基址寄存器的内容+变址寄存器的内容
MOV AX,[BX][SI]
假设BX=1500H,SI=2000H,DS=8000H,
物理地址=DS10H+EA=8000H10H+1500H+2000H=83500H
(5)相对的基址、变址寻址
MOV AX, MASK[BX][SI]
假设MASK=64H, BX=A500H,SI=2200H,DS=6000H
物理地址=DS10H+EA=6000H10H+A500H+2200H+64Y=6C764H
讲完寻址了,就要讲常用命令了,常用命令主要分为数据传送指令、算数运算指令、逻辑运算和移位指令、控制专业指令、串操作指令、程序控制指令和处理器控制指令。本章节不会一次性学完
二、8086/8088常用指令
一、数据传送类指令
注意:源操作数和目标操作数长度必须一致,这一点可以出让你找错误的题
1.MOV指令
MOV dest,src ;dest←src
将一个操作数从存储器传送到寄存器,或从寄存器传送到存储器,或从寄存器传送到寄存器,也可以将一个立即数存入寄存器或存储单元,但不能用于存储器与存储器之间,以及段寄存器之间的数据传送
8位16位都可以传,但是这取决于寄存器的位数
MOV指令的6种数据传输格式
1)CPU的通用寄存器之间的数据传输
MOV AL, BL ;BL寄存器的8位数送到AL寄存器
MOV SI, BX ;BX寄存器的16位数送到SI寄存器
2)立即数(常数)到存储单元的数据传输
MOV MEM_BYTE, 20H ;将立即数20H送到MEM_BYTE存储单元
MOV DS:[0005H], 4500H ;将立即数4500H送到 DS:0005H的存储单元中
3)立即数到通用寄存器的数据传输
MOV AL, 20H ;将立即数20H送到AL寄存器
MOV SP, 2000H ;将立即数2000H送入SP寄存器
4)通用寄存器和存储单元之间的数据传输
MOV AL, DS:[1000H] ;将地址DS:1000H存储单元的内容送到AL
MOV ES:[0002H], BX ;将BX中的16位数据传输到地址ES:0002H所指的两个相邻存储单元中
5)段寄存器和存储单元之间的数据传输
MOV ES, [BX] ;BX寄存器所指内容传送到ES
MOV [1000H], CS ;将CS内容传送到地址为1000H的存储器单元
6)通用寄存器和段寄存器之间的数据传输。
MOV AX, ES ;将ES段地址传送到DS段
MOV DS, AX
2.交换指令XCHG
交换两个操作数。可以是两个寄存器操作数,或一个寄存器与一个存储器操作数,但是两个操作数不能同时为存储器操作数。任一个操作数都不能使用段寄存器,也不能使用立即数。
XCHG AL, BL ;(AL)与(BL)寄存器的字节型数据进行交换
XCHG BX, CX ;(BX)与(CX)寄存器的字型数据进行交换
XCHG DS: [2200H], DL ;(DL)与地址DS:2200H的内容进行交换,(DH)与地址DS:2201H的内容进行交换
3.取有效地址指令LEA
这个如果做实验的话还是会经常用到的,但是做实验纯看理论之前完全不知道这指令的具体用处,大多数情况下可以用MOV代替
LEA 16位通用寄存器,存储单元
;LEA指令的作用是将有效地址(在这里指地址偏移值)送通用寄存器,而不是将存储单元的内容送通用寄存器
LEA BX,DS:1000H ;将地址1000H送到BX,即(BX)=1000H
LEA BX,BUFFER ;将存储变量BUFFER的变量地址传送到BX
LEA BX,[2728] ;将2728偏移地址送BX
LEA SP, [BP][DI] ;将[BP+DI]寻址方式的偏移地址送SP
4.装入地址指令
LDS dest,src ;将内存中连续4个字节内容送到DS和指定的通用寄存器
;dest必须为通用寄存器,src必须是内存操作数
LDS DI,[2130H] ;将2130H和2131H单元的内容送DI
;将2132H和2133H单元的内容送DS(这里就看出来上面提到的“送连续4个字节”了)
5. 标志传送指令
LAHF ;将标志寄存器的低8位送入AH
SAHF ;将AH的内容送入标志寄存器的低8位
6. 表转换指令XLAT
XLAT label
XLAT ;AL← DS:((BX)+(AL))
7. 堆栈操作指令
根据数据结构所学,压栈操作是先将SP减2,再将数据压入SS:SP指向的单元;弹出操作则先将SS:SP指向的数据弹出,再将SP加2
PUSH src ;16位的寄存器或存储单元
POP dest ;16位的寄存器或存储单元
8. 符号扩展指令
这个在后面的比较中会常用到
1)字节扩展指令
CBW
;将AL中的单字节数的符号扩展到AH中。若AX<80H,则0→AH;若AL≥80H,则FFH→AH。
MOV AL, 6FH ;AL=01101111B
CBW ;AH=00000000B, AL内容不变
MOV AL, 0AFH ;AL=10101111B
CBW ;AH=11111111B, AL内容不变
2)字扩展双字指令
CWD
;将AX中的单字节数的符号扩展到DX中。若AX<8000H,则0→DX;若AL≥8000H,则FFFFH→DX。
MOV AX, 4F0AH ;AX=4F0AH
CWD ;DX=0000H, AX内容不变
MOV AX, 0EF0AH ;AX=0EF0AH;
CWD ;DX=0FFFFH, AX内容不变
二、算数运算指令
这里的最好都知道,而且带进位的也要知道,因为会牵扯到后面的分支语句循环语句的判断
加法类指令
1)不带进位的加法指令
ADD dest,src ;dest←(dest)+(src)
说明: ADD指令不允许两个存储器单元内容相加,两个操作数不能同时为存储器操作数。 ADD指令也不允许在两个段寄存器之间相加。
对标志位有影响,主要是CF、ZF、OF、SF标志位。
2)带进位标志的加法指令
ADC dest,src ;dest←(dest)+(src)+(CF)
说明:ADC指令和ADD指令的功能类似,区别在于ADC在完成两个字或2个字节数相加的同时,还要考虑进位标志CF的值,若进位位CF为1,则将结果加1。
注意:src源操作数和 dest目的操作数不能同时为存储单元。段寄存器不能进行算术运算。
3)加1指令
INC reg/mem ;reg/mem←(reg)/(mem)+1
要求:reg为8位或16位通用寄存器,mem为8位或16位存储单元
指令功能:将源操作数加1,再送回该操作数。这条指令一般用于循环程序的指针修改,INC指令只有一个操作数。
说明: 操作数可以是寄存器或存储单元,但不能为立即数。 INC指令影响标志位AF、OF、PF、SF和ZF,但不影响CF位。
INC指令将操作数视为无符号数。
减法类指令
1)不带借位的减法指令
SUB dest, src ;dest←(dest)−(src)
指令功能:将目的操作数减去源操作数,结果送到目的操作数,并根据结果设置标志。
说明: SUB指令不允许两个存储器单元内容相减,两个操作数不能同时为存储器操作数。 SUB指令也不允许在两个段寄存器之间相减。
对标志位有影响,主要是CF、ZF、OF、SF。
2)带借位的减法指令
SBB dest, src ;dest←(dest)-(src)-(CF)
SBB指令与SUB指令的功能相似,区别是SBB在完成字节或字相减的同时,还要减去借位CF。
说明: src源操作数和 dest目的操作数不能同时为存储单元。 段寄存器不能进行算术运算。
3)减1指令
DEC reg/mem ;reg/mem←(reg)/(mem)-1
减1指令只有一个操作数。操作数可以为寄存器或者存储单元,不能为立即数。该指令实现将操作数中的内容减1,又叫减量指令。
DEC CX ;(CX)←(CX) - 1
DEC DS:[100H+2] ;将数据段DS偏移地址100H+2所指单元内容
;减1,结果送回该单元
注意:DEC指令和INC指令一样,执行后对CF不产生影响。
4) 取补指令
NEG reg/mem ;reg/mem←0-(reg)/(mem)
将操作数取补后送回源操作数,即将操作数连同符号逐位取反,然后在末位加1,适用于操作数在机器内用补码表示的场合。
NEG指令的操作数可以是8位或16位通用寄存器和存储器操作数,不能为立即数。
MOV AL,00000001B ;AL=00000001B
NEG AL ;将AL中的数取补,AL=11111111B
NEG WORD PTR [SI+1] ;将SI+1、SI+2单元中的内容取补
5) 比较指令
CMP dest,src ;(dest)−(src)
指令功能:将目的操作数与源操作数相减,不送回结果,只根据结果置标志位。
CMP AX,BX ;将AX-BX后,置标志位
CMP AL,20H ;将AX-20H后,置标志位
说明:本指令通过比较(相减)结果置标志位,表示两个操作数的关系。比较有以下几种情况,以CMP A,B为例说明。
判断两个操作数是否相等:可根据ZF标志位判断,若ZF=1,说明A=B;若ZF=0,说明A≠B。 判断两个操作数的大小:
①判断两个无符号操作数的大小:可根据CF标志位来判断,若CF=1,说明A<B;若CF=0,说明A≥B。
②判断两个带符号操作数的大小:可根据SF及OF标志来判断,若SF⊕OF=1,即SF与OF不同时,说明A<B;若SF⊕OF=0,即SF与OF相同时,则A≥B。
乘法类指令
1)无符号数乘法指令
MUL reg/mem ;dest←隐含被乘数AL/AX乘以乘数reg/mem
MUL dest,src ;dest←被乘数(dest)乘以乘数(src)
要求:dest 目的操作数可为8位、16位通用寄存器或存储单元,src源操作数可为8位、16位通用寄存器、存储单元或立即数,但dest,src不能同为存储器。
指令功能:完成两个不带符号的8位或16位二进制数的乘法计算。乘积存放在AH,AL或DX,AX中。
MOV AL,NUMBER1
MUL NUMBER2 ;将AL的内容乘以NUMBER2,乘积存放在AX中
MOV AX,NUMBER1
MUL NUMBER2 ;将AX的内容乘以NUMBER2,乘积的高16位放在DX中,低16位放在AX中
2) 带符号乘法指令
IMUL reg/mem
IMUL dest,src
要求:dest 目的操作数可为8位、16位通用寄存器或存储单元,src源操作数可为8位、16位通用寄存器、存储单元或立即数,但dest,src不能同为存储器。
指令功能:完成两个带符号的8位或16位二进制数乘法计算。乘积存放在AH,AL或DX,AX中。
除法类指令
1)无符号数除法指令
DIV src ;隐含被除数AX/DX或AX除以除数(src)
DIV dest,src ;被除数(dest)除以除数(src)
要求:dest目的操作数可为8位、16位通用寄存器或存储单元,src源操作数可为8位、16位通用寄存器、存储单元或立即数,但dest,src不能同为存储器。
指令功能:当用DIV指令进行无符号数的字或字节相除时,所得的商和余数均为无符号数,分别放在AL和AH中,若进行无符号数的双字或字相除时,所得的商和余数也是无符号数,分别放在AX和DX中。
2) 带符号除法指令
IDIV src
IDIV dest,src
要求:dest 目的操作数可为8位、16位通用寄存器或存储单元,src源操作数可为8位、16位通用寄存器、存储单元或立即数,但dest,src不能同为存储器。
指令功能:IDIV指令用于两个带符号数相除,其功能和对操作数长度的要求与DIV指令类似,本指令执行时,将被除数、除数都作为带符号数,其相除操作和DIV相同。
MOV DX,NUMBER_MSB
MOV AX,NUMBER_LSB
IDIV DIVSR ;被除数高16位在DX中,低16位在AX中,除数为16位,其结果商在AX中, 余数在DX中
BCD调整指令
BCD调整指令分为两类,即组合的和未组合的BCD调整指令。
1)组合的BCD调整指令
DAA
DAS
第一条指令对在AL中的和(由两个组合的BCD码相加后的结果)进行调整,产生一个组合的BCD码;
第二条指令对在AL中的差(由两个组合的BCD码相减后的结果)进行调整,产生一个组合的BCD码。
① DAA指令的调整方法:
如AL中的低四位在A - F之间,或AF为1,则AL ← (AL)+6,且AF 位置1。
如AL中的高四位在A - F之间,或CF为1,则AL ← (AL)+60H,且CF位置1。
② DAS指令的调整方法:
如AL中的低四位在A - F之间,或AF为1,则AL ← (AL)-6,且AF 位置1。
如AL中的高四位在A - F之间,或CF为1,则AL ← (AL)-60H,且CF位置1。
DAA 和DAS指令影响标志AF,CF,PF,SF和ZF,但不影响标志OF。
MOV AL,34H
ADD AL,47H ;AL=7BH, AF=0, CF=0
DAA ;AL=81H, AF=1, CF=0
ADC AL,87H ;AL=08H, AF=0, CF=1
DAA ;AL=68H, AF=0, CF=1
ADC AL,79H ;AL=E2H, AF=1, CF=0
DAA ;AL=48H, AF=1, CF=0
2)未组合的BCD调整指令
AAA
AAS、AAM、AAD
指令功能:AAA 指令用于对ADD指令运算后AL中的内容进行调整。
AAS 指令用于对SUB指令运算后AL中的内容进行调整。
AAM 指令用于对MUL指令运算后AX中的乘积进行BCD调整。
除法的情况却不同,AAD指令用于调整DIV运算前AH、AL中除数,以便除法所得的商是有效的未组合的BCD数。
AAA和AAS两条指令会影响AF与CF,而对OF、PF、SF和ZF没有意义。
AAA这条指令对在AL中的和(由两个未组合的BCD码相加后的结果)进行调整,产生一个未组合的BCD码。调整方法如下:
① 如AL中的低4位在0-9之间,且AF为0,则转③。
② 如AL中的低4位在A- F之间,或AF为1,则AL ← (AL)+6,AH ← (AH)+1,AF位置1。
③ 清除AL中的高4位。
④ AF位的值送CF位。
下面是该指令的一个程序片段:
MOV AX,7
ADD AL,6 ;AL=0DH, AH=00H, AF=0,CF=0
AAA ;AL=03H, AH=01H, AF=1,CF=1
ADC AL,6 ;AL=09H, AH=01H, AF=0,CF=0
AAA ;AL=09H, AH=01H, AF=0,CF=0
ADD AL,39H ;AL=42H, AH=01H, AF=1,CF=0
AAA ;AL=08H, AH=02H, AF=1,CF=1
三、逻辑指令
逻辑运算指令包括AND、OR、XOR、NOT和TEST指令。
AND dest,src ;dest←(dest)∧(src)
OR dest,src ;dest←(dest)∨(src)
XOR dest,src ;dest←(dest)⊕(src)
NOT reg/mem ;reg/mem←0FFFFH−(reg)/(mem)
TEST dest,src ;(dest)∧(src)
指令要求:dest为8位或16位通用寄存器或存储单元,src为8位或16位通用寄存器、存储单元或立即数。reg为8位或16位通用寄存器,mem为8位或16位存储单元。
注意:src源操作数和dest目的操作数不能同时为存储单元,段寄存器不能进行逻辑运算。
四、移位与循环移位指令
这个在进行一些乘法计算的时候,依照进制的特性有的时候会很有用,比如一次实验
(1)算术移位指令
SAL reg/mem,1/CL
SAR reg/mem,1/CL
要求: reg为8位或16位通用寄存器,mem为8位或16位存储单元。
指令功能:SAL为算术左移指令,算术左移1次或CL指定的次数。SAR为算术右移指令,算术右移1次或CL指定的次数。
MOV AL,8CH ;AL=8CH
SHL AL,1 ;AL=18H,CF=1,PF=1,ZF=0,SF=0,OF=1
MOV CL,6 ;CL=6
SHL AL,CL ;AL=0,CF=0,PF=1,ZF=1,SF=0,OF=0
(2)逻辑移位指令
SHL reg/mem,1/CL
SHR reg/mem,1/CL
要求:reg为8位或16位通用寄存器,mem为8位或16位存储单元。
指令功能:SHL为逻辑左移指令,逻辑左移1次或CL指定的次数,与SAL相同。SHR为逻辑右移指令,逻辑右移1次或CL指定的次数。
下面的程序片段实现把寄存器AL中的内容(设为无符号数)乘10,结果存放在AX中。
XOR AH,AH ;(AH)=0
SHL AX,1 ;2×AX
MOV BX,AX ;暂存
SHL AX,1 ;4×AX
SHL AX,1 ;8×AX
ADD AX,BX ;8×AX+2×AX
(3)循环移位指令
ROL reg/mem,1/CL
ROR reg/mem,1/CL
RCL reg/mem,1/CL
RCR reg/mem,1/CL
要求:reg为8位或16位通用寄存器,mem为8位或16位存储单元。
指令功能:ROL为循环左移指令,循环左移1次或CL指定的次数。ROR为循环右移指令,循环右移1次或CL指定的次数。RCL为带进位循环左移指令,带进位循环左移1次或CL指定的次数。RCR为带进位循环右移指令,带进位循环右移1次或CL指定的次数。
五、处理器指令
(1)标志位处理指令
在前面介绍的有关指令中,已经涉及到了对标志位的影响问题,由此可以利用标志位的状态对所执行的程序进行控制。通过标志位处理指令,可直接对指定的标志位进行设置或消除操作。
(1) 清进位位指令CLC ,即CF←0
(2) 进位标志位置“1”指令STC,即CF←1。
(3) 进位位求反指令CMC, 即CF←CF的反。
(4) 方向标志位清“0”指令CLD,即DF←0。
(5) 方向标志位置“1” 指令STD,即DF←1。
(6) 中断标志位清“0”指令CLI, 即IF←0。
(7) 中断标志位置sd“1”指令STI,即IF←1。
(2)同步与控制指令
1)ESC 指令
ESC i8,mem
ESC指令是 CPU要求协处理器完成某项任务的指令,它的功能是使某个协处理器可以从 CPU的程序中取得操作数进行处理。在以8086 为处理器的微机系统中,可以配备协处理器,例如 8087和8089,从而构成一个多处理器系统,在这种系统中 8086 按照最大模式运行,协处理器则完成某个特定的功能。
2) WAIT 指令
WAIT 指令通常在 CPU 执行完 ESC 指令后用来等待外部事件,即等待 8086 CPU的信号线TEST上的有效信号。当TEST=1时,表示 CPU 正处于等待状态,并继续执行WAIT 指令,每隔5个时钟周期就测试一次TEST状态;一旦测试到TEST-0,则CPU结束 WAIT 指令,继续执行后续指令。WAIT 与ESC 两条指令是成对使用的,它们之间可以插人一段程序。
3) LOCK 指令
LOCK 是一个字节的指令前缀,不是一条独立的指令,可位于任何指令的前端。在执行带有 LOCK 前缀的命令后,禁止其他处理器占用总线,故它可称为总线锁定前缀。
总线封锁常用于资源共享的最大方式系统中。可利用 LOCK 指令,在任一时刻只允许一个处理器工作,而其他均被封锁。
(3) 暂停和空操作指令
1) 暂停指令
HLT
功能:HLT 指令使处理器暂时停止执行后续指令,直到不可屏蔽中断 NMI 发生、可屏蔽中断INTR被识别或处理器复位为止。
2) 空操作指令
NOP
功能:NOP 指令执行空操作。它除了引起 IP 的变化外,对计算机无任何影响。
NOP 指令可用于填充内存以形成正确的转移地址或延时作用,这在程序设计中有时是很必要的。
HLT和NOP都是单字节指令。