汇编语言 学习笔记(二)

本贴最后更新于 2601 天前,其中的信息可能已经天翻地覆

汇编语言学习笔记

三、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) :left_right_arrow: (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 与其他处理机协同工作时,该指令可避免破坏有用信息

  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖
  • 汇编
    9 引用 • 1 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...