文章目录
- 一、通用传送类指令
- 1、数据传送指令
- 2、堆栈操作指令
- 二、算术运算指令
- 1、总图
- 2、加减运算指令
- 2.1 例子
- 2.2 INC/DEC指令
- 3、比较指令
- 三、转移类指令
- 1、无条件转移
- 2、有条件转移
- 2.1 无符号数条件转移指令
- 2.2 有符号数条件转移指令
- 2.3 例题一
- 2.4 循环控制指令(循环一定要用间址)
- 2.5 例题二
- 2.6 子程序调用与返回类指令
- 2.6.1汇编语言的过程定义语句
- 2.6.2 段内调用CALL指令
- 2.6.3 段间调用CALL指令
- 2.6.4 段内/段间返回RET指令
一、通用传送类指令
前言:传送类指令执行后,不影响状态标志,主要包括通用传送类指令和堆栈操作指令。
1、数据传送指令
格式: MOV 目标操作数,源操作数
功能:源操作数----->目标操作数,源不变
说明:
- 立即数不能作为传送的目标。代码寄存器CS不能作为传送的目标。指令寄存器IP不能作为目标操作数和源操作数。
- 源、目操作数,不能同时为内存操作数。源、目操作数不能同时为段寄存器(CS\DS\SS\ES)。需要借助一个通用寄存器作为中间值。
- 源、目操作数要等长,即为两者类型属性要一样。
- 当目标操作数为间址、变址、基址、基址+变址的内存操作数时,而源操作数为单字节/双字节立即数,即目标操作数必须要用PTR说明。
例子:
(1)
(2)
(3)
(4)
2、堆栈操作指令
(1)堆栈:计算机中的堆栈是人为设置的一片连续内存区,用来存放数据,所存数据按先进后出规律存取。
- 栈顶:栈区的低地址
- 栈底:栈区的高地址
(2)
堆栈段寄存器SS:存放堆栈段段基址
堆栈指针ESP(SP):存放栈顶单元的偏移地址
SS、ESP(SP)初值,由程序员赋值或DOS系统自动赋值
注意:堆栈指针SP的初值决定了堆栈的大小,SP始终指向堆栈的顶部,即始终指向最后压入堆栈的信息所在的单元。
(3)进出栈指令
进栈指令格式:PUSH 源操作数
出栈指令格式:POP 目标操作数
数据进栈不改变原值。
注意:进栈时,SP向上移动,在堆栈区内,上面区域为低地址,因此SP要减去进栈的单元个数,相反出栈时,SP向下沉,SP需要加上出栈的个数。
二、算术运算指令
1、总图
2、加减运算指令
二进制加法:ADD 目标操作数,源操作数
二进制减法:SUB 目标操作数,源操作数
二进制加进位:ADC 目标操作数,源操作数
二进制减进位:SBB 目标操作数,源操作数
功能:
注意:
- 此四种操作都会影响A\C\O\P\S\Z标志
- 源、目操作数的属性长度要一致
2.1 例子
两种解法:
- 解一:用直接寻址,双字加法(只需三条指令)
MOV EAX FIRST
ADD EAX,SECOND
MOV SUM,EAX
2.解二:将后四位(十六进制)取出,进行相加,若有进位存放在C中,再将前四位就行相加,用ADC指令相加,因为这个指令会加上前面的进位位。
MOV AX,WORD PTR FIRST
ADD AX,WORD PTR SECOND
MOV WORD PTR SUM,AX
MOV AX,WORD PTR FIRST+2
ADC AX,WORD PTR SECOND+2
MOV WORD PTR SUM+2,AX
2.2 INC/DEC指令
二进制加1:INC 目标操作数
二进制减1:DEC 目标操作数
功能:相当于c++里面的自加自减功能
注意:对于非直接寻址的内存操作数,需要用PTR说明属性
例子:
3、比较指令
定义格式:CMP 目标操作数,源操作数
功能:将目标操作数减去源操作数,目标操作数不变,依据减法运算的情况设定六个状态标志。该指令,一般后面跟着条件转移指令。
三、转移类指令
大纲:
- 按找转移条件分:无条件转移和有条件转移
- 按照范围分:段内转移和段间转移
- 按照获取转移地址的方法分:直接转移和间接转移
1、无条件转移
需要事先将转移的目标指令的段基址和偏移地址放入内存单元的高位单元和地位单元中,在执行JMP指令时,放入操作数的段基址和偏移地址将被分别写入CS寄存器和IP寄存器中。
2、有条件转移
在下列代码段里面冒号表示注释
格式:操作码助记符 转移地址符号
应用:
CMP 目,源
条件指令
转移范围:转移到代码段任何位置
说明:操作码助记符隐含了转移的条件
JZ ;若A==B,则转移
JNZ ;若A!=B,则转移
2.1 无符号数条件转移指令
CMP X,Y
JA ;若 X > Y,则转移
JNA ;若 X <= Y,则转移
JC ;若X < Y,则转移
JNC ;若X >= Y,则转移
2.2 有符号数条件转移指令
CMP X,Y
JG ;若 X > Y,则转移
JGE ;X >= Y,则转移
JC ;若X < Y,则转移
JNC ;若 X <= Y,则转移
2.3 例题一
注:箭头处,大家可能会产生疑惑,JNC和JNG不是一个表示无符号数,一个表示有符号数吗?为什么两个可以同时成立?
答:AL表示八位二进制,即为2的八次方
无符号数值范围:0~255
有符号数值范围:-128~127
因此,这么来看,AL即在无符号中,又在有符号中,所以可以两种同时成立,若题中有明确规定,那就只能是一种情况。
2.4 循环控制指令(循环一定要用间址)
上述是所有循环控制语句,而我在这里只讲LOOP
这一种。
格式如下:
MOV CX,5 ;这里的数字5,表示循环5次
AGAIN: ... ;AGAIN表示每次循环的其实头部
.
.
LOOP AGAIN ;循环到CX==0为止,跳出循环
2.5 例题二
核心代码编写:
MOV BX,OFFSET SCORE
MOV CX,40
MOV DL,0
AGA:CMP BYPE PTR [BX],60
JC NEXT
INC DL
NEXT:INC BX
LOOP AGA
MOV OK,DL
2.6 子程序调用与返回类指令
CALL <调用地址>
RET
子程序:能完成一定功能的相对独立的程序段
调用:调用子程序,即无条件转到子程序的第一条指令
返回:返回断点,即返回到CALL的后继指令
2.6.1汇编语言的过程定义语句
格式:
过程名 PROC 属性
子程序实体
RET
过程名 ENDP
2.6.2 段内调用CALL指令
何为段内?主程序,与子程序在同一代码段里。
- 段内直接调用:CALL 过程名
- 段内间接调用:
CALL 寄存器操作数
CALL 内存操作数
功能:
(1)断点偏移地址—>堆栈
详细解释: - 调整堆栈指针(SP)-2–>SP,为了扩大空间,便于后边的工作
- 将CALL指令的下一条指令的地址,即为断点的偏移地址压入堆栈保存
- 将子程序的入口的偏移地址(子程序的第一指令的偏移地址)—>IP,同时CS保持不变
2.6.3 段间调用CALL指令
- 段间直接调用 CALL 过程名
- 段间直接调用 CALL 内存操作数
功能:
(SP)-4–>SP
(SP)+1,(SP)–>(IP)
(SP)+3,(SP)+2<----CS
2.6.4 段内/段间返回RET指令
- 段内RET指令,从栈顶弹出2字节—>IP
段间RET指令,从栈顶弹出4字节—>IP,CS - RET N指令,首先完成RET功能,再将堆栈指针再下调N个字节