1、指令
指令:操作码和操作数组成(不定有操作数);
操作码:执行操作,用一个唯一的助记符表示,对应着机器指令的一个二进制编码;
操作数:操作对象,可以是数值,寄存器或存储器地址;
助记符格式:
操作码 目的操作数,源操作数;注释
指令操作数:
r8:任一8位通用寄存器;
r16:任一16位通用寄存器;
reg:r8 或 r16;
seg:段寄存器(CS/SS/DS/ES);
m8:8位存储器操作数单元;
m16::16位存储器操作数单元;
mem:m8 或 m16;
i8:8位立即数;
i16:16位立即数;
imm:i8 或 i16;
dest:目的操作数;
src:源操作数;
同一寻址方式的不同表达:
MOV AX,[BX][SI] ;等同 MOV AX,[BX+SI]
MOV AX,15[SI] ;等同 MOV AX,[15+SI]
MOV AX,15[BX][SI] ;等同 MOV AX,15[BX+SI] 或 MOV AX,[15+BX+SI]
2、寻址方式
分为3种寻址方式:
立即数寻址:指令中操作数直接放在机器代码中,紧跟操作码之后,常用来给寄存器赋值;
寄存器寻址:操作数存放在寄存器中,可以是r8,r16,seg;
存储器寻址:指令中给出操作数的偏移地址,而段地址在默认的或段超越前缀指定的段寄存器中;
寻址方式:
a.直接寻址:有效地址在指令中直接给出,默认段地址在DS中,可使用段超越前缀改变;
b.寄存器间接寻址:有效地址存放在基址寄存器BX或变址寄存器SI、DI中,段地址同上;
c.寄存器相对寻址:有效地址是寄存器内容与i8或i16之和,寄存器可为BX、BP、SI、DI,
段地址对应BX/SI/DI寄存器默认是DS,对应BP寄存器默认为SS,可使用段超越前缀改变;
d.基址变址寻址:有效地址由基址寄存器(BX/BP)内容加上变址寄存器(SI/DI)内容构成,
段地址对应BX默认为DS,对应BP默认为SS,可使用段超越前缀改变;
e.相对基址变址寻址:有效地址由基址寄存器(BX/BP)、变址寄存器(SI/DI)与i8或i16构成,
段地址对应BX默认为DS,对应BP默认为SS,可使用段超越前缀改变;
栈:
主存区域,位于堆栈段中,逻辑上存在,遵循后进先出(LIFO) 或 先进后出(FILO),段地址在SS段寄存器中;
特征:
a.只有一个出口,即当前栈顶,用堆栈指针寄存器SP指定,SS:SP指向当前栈的栈顶;
b.栈顶是地址较小一端,栈底为高地址端;
c.栈操作均以字为单位进行;
d.字量数据从栈顶压入和弹出时,低地址送低字节,高地址送高字节;
e.每个函数均开辟属于自己的栈帧;
f.虽遵循先进后出原则,但也可用存储器寻址方式随机存取栈中的数据;
用途:
a.临时存放数据
b.传递参数
c.保存和恢复寄存器
操作:
PUSH:进栈指令先使堆栈指针SP减2,然后将一个字操作数放入堆栈顶部;
POP :出栈指令将栈顶的一个字传送到指定的目的操作数,然后堆栈指针SP加2;
PUSH r16/m16/reg
POP r16/m16/reg
3、汇编指令
数据传输指令:
MOV:移动数据
PUSH:入栈
POP:出栈
XCHG:交换
LEA:有效地址传送
PUSHF/POPF:标志寄存器进栈/出栈
PUSHA/POPA:寄存器状态压入/弹出堆栈
算数与逻辑运算指令:
ADD:加法
ADC:带进位加法(额外加上CF标志,上一条指令结果影响)
INC:加1(CF标志不变,其它状态标志均受影响)
SUB:减法
SBB:带借位减法(额外减去CF标志,上一条指令结果影响)
DEC:减1(CF标志状态不变)
MUL:无符号乘法(单操作数,目标操作数为AL、AX或EAX中的隐式操作数)
IMUL:有符号乘法(单操作数、双操作数、三操作数3种,任何一种都是两个操作数参与运算);
DIV:无符号除法(单操作数,目标操作数为AX/DX:AX/EDX/EAX);
IDIV:有符号除法(单操作数,目标操作数为AL/AX/EAX中的值,结果存入AX/DX:AX/EDX:EAX,防止溢出)
CMP:比较(实际上为减,不保存结果,根据结果设置EFLAGS中的状态标志);
AND:逻辑与(逐位与)
OR:逻辑或(逐位或)
XOR:逻辑异或(逐位异或)
NOT:逻辑非(逐位非)
TEST:逻辑比较(逐位与,根据结果设置SF、ZF、PF,丢弃结果)
串操作指令:
MOVS:串传送
STOS:存入串(STOSB/STOSW/STOSD,将AL/AX/EAX中的字节/字/双字存入目标操作数);
LODS:取出串(LODSB/LODSW/LODSD,将源操作数中的字节/字/双字加载到AL/AX/EAX);
CMPS:串比较(CMPB/CMPW/CMPD,比较操作数指定的字节/字/双字,根据结果设置EFLAGS中的状态标识);
REP:重复操作前缀(REP/REPE/REPNE,按CX指定的次数重复执行字符串指令,或是ZF标识不再满足指定的条件为止)
重复条件:
REP :CX!=0;
REPE :CX!=0 且 ZF==1;
REPNE :CX!=0 且 ZF!=1;
控制转移指令:
JMP :无条件转移,跳转到指定目标地址处,从目标地址处开始执行;
Jcc :有条件转移
LOOP:循环
CALL :函数调用(CS : IP入栈,跳转)
RET :返回(带一个立即数 i16,堆栈指针SP增加,清除执行CALL前入栈的参数,即平衡堆栈);
三种转移方式:
短转移(short):段内转移,在段内 -128~+127范围内转移,即在一个字节之内;
近转移(near):段内转移,在当前代码段64KB范围内转移,无需更改CS段地址,只需改变IP偏移地址;
远转移(far):段间转移,在1MB范围内,需要更改CS段地址和IP偏移地址;
目标地址必须用一个32位数表达,称为32位远指针,是一个逻辑地址;
实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移;
当然,我们也可以使用short/near ptr/far ptr 强制转移。