汇编常用指令
1.1 通用数据传送指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
MOV | 向寄存器或内存写入数据 | mov eax,1 mov ecx,eax mov byte ptr ds:[0xFFFFFFFF],1 |
其中,数据类型有byte ,word ,dword ,qword 内存地址有多种写法 ds:[0x10000000] ds:[0x10000000+4] ds:[eax] ds:[eax+4] |
MOVSX | 先符号扩展,再传送 | mov BL,0x80 movsx AX,BL |
运行完以上汇编语句之后,AX 的值为 0xFF80 。由于 BL 为 0x80 == 1000 0000 ,最高位也即符号位为 1 ,在进行带符号扩展时,其扩展的高 8 位均为 1 ,故赋值 AX 为 1111 1111 1000 0000 ,即 AX == 0xFF80 。 |
MOVZX | 先零扩展,再传送 | movzx eax,ax movzx eax,ah |
令 eax=0x00304000 执行 movzx eax,ax 后 eax == 0x00004000 执行 movzx eax,ah 后 eax == 0x00000040 。 |
PUSH | 把字压入堆栈 | push eax push [eax] push 0xffffffff |
push OPRD 的操作过程是:第一步, SP = SP - 4 (32位操作系统是 SP - 2 )第二步,将 OPRD 的值保存至 SP 寄存器中 |
POP | 把字弹出堆栈 | pop AX pop DS pop [0] |
格式:pop 寄存器 pop 段寄存器 (注:除 CS 之外的段寄存器才可)pop 内存地址 操作过程: 第一步,将堆栈段中当前 SS:SP 所指的字内容弹出到某个寄存器或段寄存器或内存单元第二步, SP = SP + 2 |
PUSHA | 把 AX,CX,DX,BX,SP,BP,SI,DI 依次压入堆栈 | ||
POPA | 把 DI,SI,BP,SP,BX,DX,CX,AX 依次弹出堆栈 | ||
PUSHAD | 把 EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI 依次压入堆栈 | ||
POPAD | 把 EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX 依次弹出堆栈 | ||
BSWAP | 交换 32 位寄存器里字节的顺序 | BSWAP EAX |
例:EAX == 0x9668 8368 执行指令后变成 EAX == 0x6883 6896 。 |
XCHG | 交换字或字节 | xchg CH,AL xchg BX,SI xchg [SI],CX |
只能是两个寄存器,寄存器和内存变量之间内容的交换 不能同时都为内存操作数 任何一个操作数都不能为段寄存器 任何一个操作数不能为立即数 两个操作数的长度不能不相等 |
CMPXCHG | 比较并交换操作数 | cmpxchg CX,DX |
这条指令将 al/ax/eax/rax 中的值与首操作数比较:1. 如果相等,第 2 操作数的值装载到首操作数, zf = 1 。2. 如果不等,首操作数的值装载到 al\ax\eax\rax ,并将 zf 清 0 。 |
XADD | 先将两个数交换,再将二者之和传给第一个数 | xadd [ecx],eax |
先交换 [ecx] 与 eax 的值, 然后[ecx]=[ecx]+eax |
XLAT | 字节查表转换 |
1.2 输入输出端口存送指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
IN | I/O端口输入 | in AX,0x21 mov DX,379H in AL,DX |
in AX,0x21 表示:从端口地址 0x21 读取 1 字节数据到 AL 从端口地址 0x22 读取 1 字节到AH |
OUT | I/O端口输出 | out 0x21,AX mov DX,0x378 out DX,AX |
out 0x21,AX 表示:将 AX 的值写入端口地址 0x21 开始的连续两个字节。 |
注:
-
输入输出端口由立即方式指定时, 其范围是 0-255;
-
由寄存器 DX 指定时,其范围是 0-65535。
1.3 目的地址传送指令。
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
LEA | 装入有效地址。 | LEA DX,string ;把偏移地址存到DX。 | |
LDS | 传送目标指针,把指针内容装入DS。 | LDS SI,string ;把段地址:偏移地址存到DS:SI。 | |
LES | 传送目标指针,把指针内容装入ES。 | LES DI,string ;把段地址:偏移地址存到ES:DI。 | |
LFS | 传送目标指针,把指针内容装入FS。 | LFS DI,string ;把段地址:偏移地址存到FS:DI。 | |
LGS | 传送目标指针,把指针内容装入GS。 | LGS DI,string ;把段地址:偏移地址存到GS:DI。 | |
LSS | 传送目标指针,把指针内容装入SS。 | LSS DI,string ;把段地址:偏移地址存到SS:DI。 |
1.4 标志传送指令。
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
LAHF | 标志寄存器传送,把标志装入AH。 | ||
SAHF | 标志寄存器传送,把AH内容装入标志寄存器。 | ||
PUSHF | 标志入栈。 | ||
POPF | 标志出栈。 | ||
PUSHD | 32位标志入栈。 | ||
POPD | 32位标志出栈。 |
2 算术运算指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
ADD | 将两数相加和装入首操作数 | add bx,0x5 |
add bx,0x5 的作用是:bx = bx + 5 允许以下五种形式: add reg,reg add reg,memory add memory,reg add reg,constant add memory,constant |
ADC | 带进位加法 | mov ax,2 mov bx,1 sub bx,ax adc ax,1 |
示例的运算结果为 ax == 4 adc ax,cx 的作用是:将两数相加再加低位进位,结果送入首操作数,即 ax = ax + cx + cf 受影响的标志位: AF、CF、OF、PF、SF 和 ZF 。 |
INC | 加 1 | inc ax inc al inc byte ptr [bx] |
INC 指令只有 1 个操作数,它将指定的操作数的内容加 1,再将结果送回到该操作数。 INC 指令将影响 SF,AF,ZF,PF,OF 标志位,但是不影响 CF 标志位。 INC 指令的操作数的类型可以是通用寄存器或存储单元,但不可以是段寄存器。 对于存储单元,需要用 BYTE PTR 或者 WORD PTR 说明是字节还是字操作 |
AAA | 加法的ASCII码调整 | ||
DAA | 加法的十进制调整 | ||
SUB | 将两数相减差装入首操作数 | sub ax,bx |
|
SBB | 带借位减法 | ||
DEC | 减 1 | ||
NEG | 求反 | neg eax |
求补指令,对操作数执行求补运算:用 0 减去操作数,然后结果返回操作数。 求补运算也可以表达成:将操作数按位取反后加 1 。 (OPR) = - (OPR) 或 (OPR) = 0xFFFF - (OPR) + 1 |
CMP | 比较两个操作数的大小 | cmp eax,ecx |
如果比较的是两个无符号数:如果比较的是两个有符号数:
|
AAS | 减法的ASCII码调整 | ||
DAS | 减法的十进制调整 | ||
MUL | 无符号乘法 | mov ax,0x2 mov bx,0x3 mul bx |
mul reg/memory 的作用是:将 al / ax / eax 与 reg/memory 相乘,并将答案回送到 ax / dx:ax / edx:eax |
IMUL | 整数乘法 | 与 mul 类似 |
imul 会保留乘积的符号 |
AAM | 乘法的ASCII码调整 | ||
DIV | 无符号除法 | mov dx,0x1 mov ax,0x86a1 mov bx,0x100 div bx |
div reg/memory 的作用是:将 ax / dx:ax / edx:eax 与 reg/memory 相乘,并将商回送到 al / ax / eax ,将余数回送到 ah / dx / edx |
IDIV | 整数除法 | 与 idiv 类似 |
idiv 为有符号的除法 |
AAD | 除法的 ASCII 码调整 | ||
CBW | 字节转换为字 | cwb |
把 AL 中字节的符号扩展到 AH 中去: 如果 AL 的最高有效位是 0 ,则 AH = 0x00 ;如果 AL 的最高有效位为 1 ,则 AH = 0xff 。AL 不变。(也就是将 AL 的符号位移至 AH ) |
CWD | 字转换为双字 | cwd |
把 AX 中的字的符号扩展到 DX 中去 |
CWDE | 字转换为双字 | cwde |
把 AX 中的字符号扩展到 EAX 中去 |
CDQ | 双字扩展 | cdq |
把 EAX 中的字的符号扩展到 EDX 中去 |
3 逻辑运算指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
AND | 与运算 | mov eax,0x0000ffff and eax,0x0000000f |
用法:and reg,imm/reg/mem and mem,imm/reg 该指令会置 CF = OF = 0 ,其结果影响 SF , ZF , PF ,而对于 AF 无定义 。 |
OR | 或运算 | 与 and 类似 |
与 and 类似 |
XOR | 异或运算 | 与 and 类似 |
与 and 类似 |
NOT | 取反 | not reg/mem |
反转操作数的所有位。 不影响标志位。 |
TEST | 测试 | test ax,bx |
两操作数作与运算,仅修改标志位,不回送结果 具体操作流程如下: 将两个操作数进行按位 AND ,设结果是 TEMP 。 将结果的最高位赋给 SF 标志位。比如结果最高位是 1 ,SF 就为 1 。 如果 TEMP == 0 ,ZF = 1 ,如果 TEMP != 0 ,ZF = 0 。PF = 将 TEMP 的低 8 位,从第 0 位开始,逐位取同或。也就是第 0 位与第 1 位的同或结果,去和第 2 位同或,结果再去和第 3 位同或……直到和第 7 位同或。CF 位置 0 ,OF 位置 0 ,AF 位是未定的,鬼知道是什么 |
SHL | 逻辑左移。 | ||
SAL | 算术左移。(=SHL) | ||
SHR | 逻辑右移。 | ||
SAR | 算术右移。(=SHR) | ||
ROL | 循环左移。 | ||
ROR | 循环右移。 | ||
RCL | 通过进位的循环左移。 | ||
RCR | 通过进位的循环右移。 |
以上八种移位指令,其移位次数可达255次。 移位一次时, 可直接用操作码。 如 SHL AX,1。 移位>1次时, 则由寄存器CL给出移位次数。 如 MOV CL,04 SHL AX,CL
4 串指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
DS:SI | 源串段寄存器 :源串变址。 | ||
ES:DI | 目标串段寄存器:目标串变址。 | ||
CX | 重复次数计数器。 | ||
AL/AX | 扫描值。 |
(以下部分看不懂还没整理) D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量。 Z标志 用来控制扫描或比较操作的结束。 MOVS 串传送。 ( MOVSB 传送字符。 MOVSW 传送字。 MOVSD 传送双字。 ) CMPS 串比较。 ( CMPSB 比较字符。 CMPSW 比较字。 ) SCAS 串扫描。 把AL或AX的内容与目标串作比较,比较结果反映在标志位。 LODS 装入串。 把源串中的元素(字或字节)逐一装入AL或AX中。 ( LODSB 传送字符。 LODSW 传送字。 LODSD 传送双字。 ) STOS 保存串。 是LODS的逆过程。 REP 当CX/ECX<>0时重复。 REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复。 REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复。 REPC 当CF=1且CX/ECX<>0时重复。 REPNC 当CF=0且CX/ECX<>0时重复。
5 程序转移指令
5.1 无条件转移指令 (长转移)
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
JMP | 无条件转移指令 | ||
CALL | 过程调用 |
RET/RETF过程返回。
5.2 条件转移指令(短转移,-128 到 +127 的距离内)
(当且仅当 (SF XOR OF)=1
时,OP1)
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
JA/JNBE | 不小于或不等于时转移。 | ||
JAE/JNB | 大于或等于转移。 | ||
JB/JNAE | 小于转移。 | ||
JBE/JNA | 小于或等于转移。 | 以上四条,测试无符号整数运算的结果(标志C和Z)。 | |
JG/JNLE | 大于转移。 | ||
JGE/JNL | 大于或等于转移。 | ||
JL/JNGE | 小于转移。 | ||
JLE/JNG | 小于或等于转移。 | 以上四条,测试带符号整数运算的结果(标志S,O和Z)。 | |
JE/JZ | 等于转移。 | ||
JNE/JNZ | 不等于时转移。 | ||
JC | 有进位时转移。 | ||
JNC | 无进位时转移。 | ||
JNO | 不溢出时转移。 | ||
JNP/JPO | 奇偶性为奇数时转移。 | ||
JNS | 符号位为 "0" 时转移。 | ||
JO | 溢出转移。 | ||
JP/JPE | 奇偶性为偶数时转移。 | ||
JS | 符号位为 "1" 时转移。 |
5.3 循环控制指令(短转移)
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
LOOP | CX不为零时循环。 | ||
LOOPE/LOOPZ | CX不为零且标志Z=1时循环。 | ||
LOOPNE/LOOPNZ | CX不为零且标志Z=0时循环。 | ||
JCXZ | CX为零时转移。 | ||
JECXZ | ECX为零时转移。 |
5.4 中断指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
INT | 中断指令 | ||
INTO | 溢出中断 | ||
IRET | 中断返回 |
5.5 处理器控制指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
HLT | 处理器暂停, 直到出现中断或复位信号才继续。 | ||
WAIT | 当芯片引线TEST为高电平时使CPU进入等待状态。 | ||
ESC | 转换到外处理器。 | ||
LOCK | 封锁总线。 | ||
NOP | 空操作。 | ||
STC | 置进位标志位。 | ||
CLC | 清进位标志位。 | ||
CMC | 进位标志取反。 | ||
STD | 置方向标志位。 | ||
CLD | 清方向标志位。 | ||
STI | 置中断允许位。 | ||
CLI | 清中断允许位。 |
5.6 伪指令
指令 | 作用 | 用法示例 | 备注 |
---|---|---|---|
DW | 定义字(2字节)。 | ||
PROC | 定义过程。 | ||
ENDP | 过程结束。 | ||
SEGMENT | 定义段。 | ||
ASSUME | 建立段寄存器寻址。 | ||
ENDS | 段结束。 | ||
END | 程序结束。 |
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.