汇编语言学习笔记

三、8086基本指令

数据传送指令

通用数据传送指令

1. MOV传送指令
MOV   dst, src	; (dst) ← (src) 
;	格式 : MOV  reg/mem/seg, reg/mem/seg/imm

a. 对标志位无影响
b. 不允许两个操作数同时是段寄存器或者存储器
c. 代码段寄存器CS和立即数均不能作为目的操作数
d. 立即数不能传送到段寄存器中
e. destsrc必须类型匹配,即同时是字节或字类型。至少1个操作数的类型要明确,不能出现二义性

段寄存器与通用寄存器,通用寄存器之间可以互送数据(CS不能作为目的操作数)

2. XCHG交换
XCHG   oprd1, oprd2 	; (oprd1) ↔ (oprd2)
;	格式	:	XCHG    reg/mem,reg/mem 
3. XLAT指令
XLAT			;	(AL) ← [(BX) + (AL)]
;	说明	:	将BX中内容与AL中内容相加,作为偏移地址,将数据段中对应字节单元内容送入AL中

a . BX通常为表格首址,利用该指令实现查表。由于AL只有8位,所以表格长度不能超过256
b . OPR为表格首地址(一般为符号地址),只为可读性而设置,不真正发挥作用

堆栈和栈操作指令

a. 堆栈中数据的存取遵循“先进后出”的原则
b. 堆栈的活动端称为栈顶,固定端称为栈底
c. 8086/8088的堆栈的伸展方向是从高地址向低地址最高地址是栈底
d. 堆栈操作都是字操作,进栈时SP自动减2,出栈时SP自动加2
e. 堆栈指令:PUSH和POP。编程时,进栈和出栈的指令通常是成对出现的
f. SS:SP在任何时候都指向当前的栈顶。栈顶指针SP总是指向最后进栈的数据

1. PUSH 进栈指令
PUSH reg/mem/seg 	; mem[(ss)x16 + (sp)] ← (reg/mem/seg) & (sp) ← (sp - 2)
2. POP 出栈指令
POP reg/mem/seg 	; (reg/mem/seg) ← mem[(ss)x16 + (sp)] & (sp) ← (sp + 2)

标志类指令

1. 标志处理指令
CLC 	;	(clear carry)		进位位置0指令
CMC 	;	(complement carry)	进位位求反指令
STC 	;	(set carry)			进位位置1指令
CLD 	;	(clear direction)	方向标志位置0指令
STD 	;	(set direction)		方向标志位置1指令
CLI 	;	(clear interrupt)	中断标志置0指令
STI 	;	(set interrupt)		中断标志置1指令

2. 标志传送指令

(1) 标志寄存器进栈指令

PUSHF	;	(sp) ← (sp -2), F 进栈

(2) 标志寄存器出栈指令

POPF	;	(sp) ← (sp + 2),(F) ← (栈顶元素)

地址传送指令

偏移地址传送指令 LEA
LEA  reg16, mem	; 22 

主存按源地址的寻址方式计算偏移地址,将偏 移地址送入指定寄存器

a. 该指令的目的操作数不能使用段寄存器
b. 源操作数可使用除立即数和寄存器外的任一种存储器寻址方式

LEA 指令与MOV 指令的区别
LEA SI, BUFF 是将标号BUFF的偏移地址送入寄存器中;
MOV SI, BUFF 指令是将标号BUFF所指存储单元的内容送入 SI。

MOV BX, OFFSET LIST功能相同 MOV指令速度比LEA快,但OFFSET只能用于符号地址

段寄存器装入指令 LDS/LES

格式:LDS/LES REG,SRC
操作 : (REG) ← (SRC) & (SREG)←(SRC+2)

LDS bx,	[2000H]	;	(bx) ← mem[2000H,2001H] & (ds) ← mem[2002H,2003H]

a. LDS与LES指定的段寄存器分别为DS和ES
b. SRC只能用存储器寻址方式
c. 目的寄存器不允许使用段寄存器

输入/输出指令

指令不影响标志位

1. IN 输入指令

格式 IN al/ax, PORT/DX

IN 	ax, 13H		;	 从端口13送一个字到ax
2. OUT 输出指令

格式 OUT PORT/DX, AL/AX

OUT 5,	al	;	从al寄存器输出一个字节到端口5

算术运算指令

指令影响标志位

加法指令

1. ADD 加法指令

格式:ADD DST , SRC

ADD   reg/ mem, reg/mem /imm	;	(DST)←(SRC)+(DST)  

影响标志位:CF(通过加法运算是否有进位判断)、OF、SF、PF、ZF和AF

2. ADC 带进位加法指令

格式:ADC DST , SRC

ADC reg/ mem , reg/mem /imm 	;	(DST)←(SRC)+(DST)+CF

如果结果再有进位,则置位CF,否则CF位清0,
影响标志位:CF、OF、SF、PF、ZF和AF

3. INC加1指令

格式:INC OPR (reg/mem)

INC   reg/mem		;	(reg/mem) ← (reg/mem + 1)

a. 根据结 果设置除CF以外的标志位
b. 操作数不能为立即数
c. 经常用于修改地址指针

减法指令

1. SUB 减法指令

格式:SUB DST , SRC

SUB reg/ mem , reg/mem /imm	;	(DST)←(DST)-(SRC)

若减数>被减数,CF=1;否则CF=0

#####2. SBB 带借位减法指令
格式:SBB DST , SRC

SBB   reg/mem , reg/mem/imm	;	(DST)←(DST)-(SRC)-CF
3. DEC 减1指令

格式:DEC OPR(reg/mem)

DEC reg/mem	;	(OPR)←(OPR)-1

DEC将操作数内容减1,把结果送回操作数中,并根据结果设置除CF以外的标志位

a. 操作数不能为立即数
b. 经常用于修改地址指针

4. NEG 求补指令

格式:NEG OPR(reg/mem)

NEG mem/reg ; 	(OPR) ← -(OPR)

影响所有标志位

5. CMP比较指令

格式:CMP OPR1 , OPR2

CMP   reg/ mem, reg/mem/imm	; 根据 (OPR1)-(OPR2) 的结果设置标志位

该指令执行减法操作, 但它并不保存结果,只是根据结果设置条件标志位
若ZF=1,则两数相等;若ZF ≠ 0则两数不等

  • 如果两数不等且为无符号数
    若CF=1,则目的操作数小于源操作数;否则相反

  • 如果两数不等且为有符号数
    若OF XOR SF=0(OF=SF),则目的数大于等于源数
    若OF XOR SF=1(OF≠SF),则目的数小于源数

a. CMP指令后往往跟着一条条件转移指令

乘法指令

1. MUL 无符号数乘法指令

格式:MUL SRC(reg/mem)

MUL reg/mem
;	字节操作数	:	(AX)←(AL)*(SRC)
;	字操作数	:	(DX,AX)←(AX)*(SRC)
2. IMUL 带符号数乘法指令

格式:IMUL SRC(reg/mem)

IMUL reg/mem

执行的操作与MUL相同,但必须是带符号数

乘法指令对除CF位和OF位以外的标志位无定义

对于MUL指令,如果乘积的高一半为0,则CF位和OF位均为0;否则CF位和OF位均为1

对于IMUL指令,如果乘积的高一半是低一半的符号扩展,则CF位和OF位均为 0;否则就均为1

除法指令

1. DIV 无符号数除法指令

格式:DIV SRC(reg/mem)

  • 字节操作
    (AL)←(AX)/(SRC)的商
    (AH)←(AX)/(SRC)的余数

  • 字操作
    (AX)←(DX,AX)/(SRC)的商
    (DX)←(DX,AX)/(SRC)的余数

2. IDIV 带符号数除法指令

格式:IDIV SRC(reg/mem)

执行的操作与DIV相同,但操作数为带符号数

除法指令对所有条件码位均无定义
IDIV字节相除时,商的范围是-080H7FH,字相除时,商的范围是-8000H7FFFH。如果除数为“0”或商超出累加器容量,则产生除法错误故障(中断0)
余数的符号和被除数相同
除法运算和CBW,CWD配合使用

类型转换指令

1. CBW 字节转换为字指令
CBW		; AL的内容符号扩展到AH,形成AX中的字 

若(AL)<80H,则(AH)=0;若(AL)>=80H,则(AH)=0FFH

2. CWD 字转换为双字指令
CWD	;	AX的内容符号扩展到DX,形成DX,AX中的双字

若(AX)<8000H,则(DX)=0;若 (AX)>=8000H,则(DX)=0FFFFH

a. CBW/CWD常被安排IDIV指令(带符号数除法)之前

十进制调整指令

DAA ; (decimal adjust for addition)  DAA为加法的十进制调整指令,必须紧跟在把两个组合BCD码相加的ADD或ADC指令之后,把AL内容调整为组合BCD码格式
DAS	; (decimal adjust for subtraction) DAS为减法的十进制调整指令,必须紧跟在把两个组合BCD码相减的SUB或SBB指令之后,把AL内容调整为组合BCD码格式
AAA ; (ASCII adjust for addition) 
AAS ; (ASCII adjust for subtraction) 
AAM ; (ASCII adjust for multiplication)
AAD ; (ASCII adjust for division)

a. DAA/DAS指令对OF标志无定义,但影响所有其他条件标志
b. AAA/AAS影响AF和CF,其余标志则无意义
c. AAM/AAD根据AL中的结果影响状态标志位SF、ZF和PF,但其余几个状态标志位的值不确定

位操作类指令

指令影响标志位

逻辑运算指令

1. AND 逻辑与指令
AND     mem/reg, mem/reg/imm	;	(DST) ← (DST) & (SRC)
2. OR 逻辑或指令
OR     mem/reg, mem/reg/imm	;	(DST) ← (DST) | (SRC)
3. XOR 异或指令
XOR     mem/reg, mem/reg/imm	;	(DST) ← (DST) xor (SRC)
4. TEST 测试指令
TEST	mem/reg, mem/reg/imm	;	(DST) ← (DST) & (SRC)

测试指令:进行逻辑“与”运算,结果不保存,根据结果设置标志位。常用于判断操作数的某位或某几位是“0”还是“1”

5. NOT 逻辑非指令
AND     mem/reg, mem/reg/imm	;	(DST) ← (DST) & (SRC)

NOT指令不影响标志位,其他4种指令将使CF位和OF位为0,AF位无定义,而SF位、 ZF位和PF位则根据运算结果设置

移位指令

说明 : SAL/SHR/SAR/ROL/ROR/RCL/RCR/SHL reg/mem , 1/CL

移位次数可以是1或CL寄存器的值:
为1时二进制数各个数位只移一位;
如需要移位的次数大于1,必须将移位次数送CL寄存器,再执行移位指令

逻辑左移指令SHL和算术左移指令SAL
逻辑右移指令SHR和算术右移指令SAR
循环左移指令ROL和循环右移指令ROR
带CF位的循环左移指令RCL和循环右移指令RCR

串处理指令

串基本处理指令包括:
MOVS (move string)
LODS (load from string)
STOS (store in to string)
CMPS (compare string)
SCAS (scan string)

与上述基本指令配合使用的前缀有:
REP (repeat)
REPE/REPZ (repeat while equal/zero)
REPNE/REPNZ (repeat while not equal/not zero)

0. REP 重复串操作

重复串操作直到CX内容为0为止

REP  MOVS/LODS/STOS

执行的操作:
①如(CX)=0,则退出REP,否则往下执行;
②(CX) ← (CX)-1;
③执行其后的串指令;
④重复① ~ ③。
需要注意的是CX的递减是不影响标志位

1. MOVS 串传送指令

三种格式

MOVS   DST,SRC
MOVSB	;	MOVS ES:BYTE PTR [DI], DS:[SI] 
MOVSW	;	MOVS ES:WORD PTR [DI], DS:[SI] 

执行的操作
① ((ES):(DI))←((DS):(SI))
②字节操作:
(SI)←(SI)±1
(DI)←(DI)±1
③字操作:
(SI)←(SI)±2
(DI)←(DI)±2
当方向标志位DF=0时用+,DF=1时用−

串操作的准备工作
①把存放在数据段中的源串首地址(如反向传送则应是末地址)放入源变址寄存器中;
②把将要存放数据串的附加段中的目的串首地址(或反向传送时的末地址)放入目的变址寄存器中;
③如果使用重复前缀,把数据串长度放入CX;
④建立方向标志。
CLD (clear direction flag) 该指令使 DF=0;
STD (set direction flag) 该指令使 DF=1。

控制转移指令

无条件转移指令

段内直接转移 JMP SHORT OPR\JMP NEAR PTR OPR
段内间接近转移 JMP WORD PTR OPR
段间直接远转移 JMP FAR PTR OPR
段间间接远转移 JMP DWORD PTR OPR

条件转移指令

根据上一条指令所设置的标志位来判别测试条件,满足条件则转移到由指令指定的转向地址去执行,不满足条件则顺序执行下一条指令

a. 目标地址应在本条转移指令下一条指令地址的-128~+127个字节的范围之内
b. 条件转移指令都不影响标志位

1. 以单个标志位为条件
JO	opr	;	溢出转移,OF=1
JNO	opr	;	不溢出转移,OF=0
JS	opr	;	结果为负转移,SF=1
JNS	opr	;	结果为正转移,SF=0
JC	opr	;	进位转移,CF=1
JNC	opr	;	无进位转移,CF=0
JE/JZ	opr	;	相等或为零转移,ZF=1
JNE/JNZ	opr	;	不相等或不为零转移,ZF=0
JP/JPE	opr	;	奇偶校验为偶转移,PF=1
JNP/JPO opr	;	奇偶校验为奇转移,PF=0 
2. 无符号数比较

ZF和CF的值

JA/JNBE opr	;	大于时转移,CF=0∧ZF=0 
JAE/JNB opr	;	大于等于时移,CF=0∨ZF=1
JB/JNAE opr	;	小于时转移,CF=1∧ZF=0
JBE/JNA opr	;	小于等于时移,CF=1∨ZF=1
3 有符号数比较

ZF和(SF XOR OF)的值

JG/JNLE	opr	;	大于时转移,SF=OF∧ZF=0
JGE/JNL	opr	;	大于等于时移,SF=OF∨ZF=1
JL/JNGE	opr	;	小于时转移,SF≠OF∧ZF=0
JLE/JNG	opr	;	小于等于时移,SF≠OF∨ZF=1 

循环指令

循环指令不影响标志位

1 .LOOP opr

执行(CX)←(CX)-1,若(CX)≠0则转移至符号地址opr

2. LOOPZ/LOOPE opr

执行(CX)←(CX)-1,若(CX)≠0且ZF=1则转移至opr

3. LOOPNZ/LOOPNE opr

执行时,(CX)←(CX)-1,若(CX)≠0且ZF=0则转移至opr

子程序(subroutine)

在汇编语言中将某些具有独立功能的部分编写成独立的程序模块,称之为子程序。

CALL	;	调用    将断点(返回地址)进栈操作
RET		;	返回    将断点出栈的操作

直接/间接 段内/段间(CS也要进栈)

中断指令和系统功能调用

当一种特殊事件发生时,CPU停止正在运行的程序,转去执行该事件的处理程序,处理完该事件后,再返回原程序继续正确地执行下去,这个过程就称为中断
引起中断的事件称为中断源。中断源可能来自外设的输入/输出请求,也可能是计算机的一些异常故障或其他内部原因。

8086可以响应256种中断,每种中断对应的中断类型号为0~255。这些中断又分为为硬件中断软件中断两种。
硬件中断又称外部中断,是外部的硬件设备引起的,如I/O设备或其他处理机等,以完全随机的方式中断现行程序而转向中断处理程序。
硬件中断又分为非屏蔽中断(引脚NMI接入)和可屏蔽中断(引脚INTR接入) 。
软件中断又称内部中断,由如下3种情况引起:
1 由指令引起的中断。
2 处理CPU某些错误的中断:如除法错中断(除数为0或商超过了寄存器表达范围时产生,中断类型码为0)和溢出中断(当OF=1时执行指令INTO产生,执行后会返回操作系统,中断类型码为4)。
3 调试程序设置的中断:如单步中断(当TF=1时,每条指令执行后,CPU自动产生一个中断类型码为1的中断) 和断点中断(通过在程序中加入令INT 3完成,CPU每执行到此处便产生一个中断)。

中断向量
中断服务程序的入口地址又称中断向量,为两个16位地址4个字节,前2个单元存放中断服务程序的入口地址的偏移量(IP),后2个单元是段地址(CS)。
中断向量按中断号的大小依次存放在内存中从0000H-03FFH的连续地址空间内,共占用1K存储空间。
微处理器响应某个中断后,取得该中断的类型号N,将N乘以4,得到了该中断服务程序入口地址的指针0000:4*N,取出连续的4个字节,得到对应中断服务程序的入口地址。

1. 中断指令 INT N

N为中断类型号,隐含的类型号为3。

2. 溢出中断指令 INTO

溢出标志OF=1时使用,类型号是04H,一般放在有符号数的加减运算后面。

3. 中断返回指令 IRET

必须放在中断处理程序的末尾。

0号中断为除数为0中断,1号中断为单步中断,2号中断为非屏蔽中断。
断点Int 3: 调试程序设置断点时使用。

DOS系统功能调用

DOS系统功能调用 INT 21H
可以完成设备管理及磁盘文件管理等近90个子功能,子功能是通过DX寄存器和AH寄存器预先设置参数达到的,AH用于存放调用功能号
键盘单字符输入 01H
键盘多字符输入 0AH
单字符显示器输出 02H
字符串显示器输出 09H
检测键盘有无键入 0BH
返回操作系统 4CH

处理机控制类指令

控制处理机状态,不影响标识位

NOP无操作指令

该指令不执行任何操作,其机器码占有一个字节单元。

HLT停机指令

该指令可使机器暂停工作,使处理机处于停机状态以等待一次外部中断的到来,中断结束后可继续执行下面的程序。

ESC换码指令:
ESC  op, reg/mem

这条指令在使用协处理机时,可以指定由协处理器执行的指令。指令的第一个操作数即指定其操作码,第二个操作数即指定其操作数。

WAIT等待指令

该指令使处理机处于空转状态,它也可以用来等待外部中断发生,但中断结束后仍返回 WAIT指令继续等待。它也可以与ESC指令配合等待协处理机的执行结果。

LOCK封锁指令

与其他指令联合,以维持总线的锁存信号直到与其联合的指令执行完为止。当 CPU与其他处理机协同工作时,该指令可避免破坏有用信息



处身寒夜,把握星光。