IA-32指令集详解
一、引言
IA - 32指令集是一组常用的指令集合,不过它不涵盖系统模式指令,也不包含那些通常仅在操作系统内核代码或保护模式设备驱动程序中使用的指令。
1.1 标志位
在指令描述中,会有一系列的框来描述指令对CPU状态标志位的影响。每个标志位由一个字母标识:
| 标志位 | 含义 |
| ---- | ---- |
| O | 溢出标志(Overflow) |
| S | 符号标志(Sign) |
| P | 奇偶标志(Parity) |
| D | 方向标志(Direction) |
| Z | 零标志(Zero) |
| C | 进位标志(Carry) |
| I | 中断标志(Interrupt) |
| A | 辅助进位标志(Auxiliary Carry) |
框内使用以下符号表示指令对标志位的影响:
-
:设置标志位
-
O
:清除标志位
-
?
:可能将标志位更改为未确定的值
- (空白):标志位不变
-
*
:根据与标志位相关的特定规则更改标志位
例如,对于CPU标志位的图示:
O D I S Z A P C
? ? ? *
从这个图示可以看出,溢出、符号、零和奇偶标志位将被更改为未知值;辅助进位和进位标志位将根据相关规则进行修改;方向和中断标志位不变。
1.2 指令描述和格式
在提及源操作数和目的操作数时,遵循所有Intel 80x86指令中操作数的自然顺序,即第一个操作数是目的操作数,第二个是源操作数。例如在
MOV
指令中:
MOV destination, source
目的操作数将被赋予源操作数数据的副本。
一条指令可能有多种格式,以下是指令格式中使用的符号列表:
| 符号 | 描述 |
| ---- | ---- |
| reg | 8位、16位或32位通用寄存器,如AR、AL、BL等 |
| reg8, reg16, reg32 | 根据位数标识的通用寄存器 |
| segreg | 16位段寄存器(CS、DS、ES、SS、FS、GS) |
| accum | AL、AX或EAX |
| mem | 使用任何标准内存寻址模式的内存操作数 |
| mem8, mem16, mem32 | 根据位数标识的内存操作数 |
| shortlabel | 代码段中距离当前位置 -128 到 +127 字节范围内的位置 |
| nearlabel | 当前代码段中由标签标识的位置 |
| farlabel | 外部代码段中由标签标识的位置 |
| imm | 立即操作数 |
| imm8, imm16, imm32 | 根据位数标识的立即操作数 |
| instruction | 80x86汇编语言指令 |
使用
(IA - 32)
表示该指令或其变体仅适用于IA - 32系列处理器(从Intel 386开始);
(80286)
表示至少需要使用80286处理器。像
(E)CX
、
(E)SI
等寄存器符号用于区分使用32位寄存器的IA - 32处理器和使用16位寄存器的早期处理器。
二、非浮点指令集详情
2.1 ASCII调整指令
-
AAA(ASCII Adjust After Addition)
- 功能:在两个ASCII数字相加后,调整AL中的结果。如果AL > 9,结果的高位数字将放入AH中,并设置进位和辅助进位标志位。
- 标志位影响:
O D I S Z A P C
? ? * ? *
- 指令格式:`AAA`
-
AAD(ASCII Adjust Before Division)
-
功能:将AH和AL中的未压缩BCD数字转换为单个二进制值,为
DIV指令做准备。 - 标志位影响:
-
功能:将AH和AL中的未压缩BCD数字转换为单个二进制值,为
O D I S Z A P C
* * * 1
- 指令格式:`AAD`
-
AAM(ASCII Adjust After Multiply)
- 功能:在两个未压缩BCD数字相乘后,调整AX中的结果。
- 标志位影响:
O D I S Z A P C
* * ? * ?
- 指令格式:`AAM`
-
AAS(ASCII Adjust After Subtraction)
- 功能:在减法操作后,调整AX中的结果。如果AL > 9,AAS会递减AH并设置进位和辅助进位标志位。
- 标志位影响:
O D I S Z A P C
? ? ? * ? *
- 指令格式:`AAS`
2.2 算术运算指令
-
ADC(Add Carry)
- 功能:将源操作数和进位标志位的值加到目的操作数上,操作数必须大小相同。
- 标志位影响:
O D I S Z A P C
* * * * * *
- 指令格式:
ADC reg, reg
ADC reg, imm
ADC mem, reg
ADC mem, imm
ADC reg, mem
ADC accum, imm
-
ADD(Add)
- 功能:将源操作数加到目的操作数上,和存储在目的操作数中,操作数必须大小相同。
- 标志位影响:
O D I S Z A P C
* * * * * *
- 指令格式:
ADD reg, reg
ADD reg, imm
ADD mem, reg
ADD mem, imm
ADD reg, mem
ADD accum, imm
2.3 逻辑运算指令
-
AND(Logical AND)
- 功能:将目的操作数的每一位与源操作数的对应位进行逻辑与运算。
- 标志位影响:
O D I S Z A P C
O * * ? * 0
- 指令格式:
AND reg, reg
AND reg, imm
AND mem, reg
AND mem, imm
AND reg, mem
AND accum, imm
2.4 其他常见指令
-
CALL(Call a Procedure)
- 功能:将下一条指令的位置压入栈中,并转移到目的位置。如果过程是近过程(在同一代码段),则仅压入下一条指令的偏移量;否则,段和偏移量都将被压入。
- 标志位影响:
O D I S Z A P C
- 指令格式:
CALL nearlabel
CALL mem16
CALL farlabel
CALL mem32
CALL reg
-
CBW(Convert Byte to Word)
- 功能:将AL中的符号位扩展到AH寄存器。
- 标志位影响:
O D I S Z A P C
- 指令格式:`CBW`
以下是部分指令的执行流程mermaid流程图:
graph TD;
A[开始] --> B{是否执行CALL指令};
B -- 是 --> C[压入下一条指令位置到栈];
C --> D[转移到目的位置];
D --> E[结束];
B -- 否 --> F{是否执行CBW指令};
F -- 是 --> G[扩展AL符号位到AH];
G --> E;
F -- 否 --> E;
2.5 字符串操作指令
-
MOVS(Move String)
- 功能:将DS:(E)SI所指向的内存中的字节或字复制到ES:(E)DI所指向的内存中。
- 标志位影响:
O D I S Z A P C
* * * * * *
- 指令格式:
MOVSB
MOVSW
MOVSD
MOVS dest, source
MOVS ES:dest, segreg:source
-
LODS(Load Accumulator from String)
- 功能:将DS:(E)S1所指向的内存中的字节或字加载到累加器(AL、AX或EAX)中。
- 标志位影响:
O D I S Z A P C
- 指令格式:
LODSB
LODSW
LODSD
LODS mem
LODS segreg:mem
2.6 条件跳转指令
条件跳转指令根据指定的标志位条件跳转到标签位置。在IA - 32处理器之前,标签必须在距离当前位置 -128 到 +127 字节的范围内;在IA - 32处理器上,标签的偏移量可以是一个正负32位的值。以下是部分条件跳转助记符:
| 助记符 | 注释 |
| ---- | ---- |
| JA | 若高于则跳转 |
| JE | 若相等则跳转 |
| JNA | 若不高于则跳转 |
| JNE | 若不相等则跳转 |
| JAE | 若高于或等于则跳转 |
| JZ | 若为零则跳转 |
指令格式:
Jcondition label
2.7 栈操作指令
-
PUSH(Push on Stack)
- 功能:从(E)SP中减去2,并将源操作数复制到(E)SP所指向的栈位置。从80186开始,可以将立即值压入栈中。
- 标志位影响:
O D I S Z A P C
- 指令格式:
PUSH reg16/reg32
PUSH segreg
PUSH mem16/mem32
PUSH imm16/imm32
-
POP(Pop from Stack)
- 功能:将当前栈指针位置的字或双字复制到目的操作数中,并将(E)SP加2(或4)。
- 标志位影响:
O D I S Z A P C
- 指令格式:
POP reg16/r32
POP segreg
POP mem16/mem32
2.8 移位和旋转指令
-
RCL(Rotate Carry Left)
-
功能:将目的操作数向左旋转,使用源操作数确定旋转的次数。进位标志位复制到最低位,最高位复制到进位标志位。在使用8086/8088处理器时,
imm8操作数必须为1。 - 标志位影响:
-
功能:将目的操作数向左旋转,使用源操作数确定旋转的次数。进位标志位复制到最低位,最高位复制到进位标志位。在使用8086/8088处理器时,
O D I S Z A P C
* *
- 指令格式:
RCL reg, imm8
RCL mem, imm8
RCL reg, CL
RCL mem, CL
-
RCR(Rotate Carry Right)
-
功能:将目的操作数向右旋转,使用源操作数确定旋转的次数。进位标志位复制到最高位,最低位复制到进位标志位。在使用8086/8088处理器时,
imm8操作数必须为1。 - 标志位影响:
-
功能:将目的操作数向右旋转,使用源操作数确定旋转的次数。进位标志位复制到最高位,最低位复制到进位标志位。在使用8086/8088处理器时,
O D I S Z A P C
* *
- 指令格式:
RCR reg, imm8
RCR mem, imm8
RCR reg, CL
RCR mem, CL
-
ROL(Rotate Left)
-
功能:将目的操作数向左旋转,使用源操作数确定旋转的次数。最高位复制到进位标志位并移动到最低位。在使用8086/8088处理器时,
imm8操作数必须为1。 - 标志位影响:
-
功能:将目的操作数向左旋转,使用源操作数确定旋转的次数。最高位复制到进位标志位并移动到最低位。在使用8086/8088处理器时,
O D I S Z A P C
* *
- 指令格式:
ROL reg, imm8
ROL mem, imm8
ROL reg, CL
ROL mem, CL
-
ROR(Rotate Right)
-
功能:将目的操作数向右旋转,使用源操作数确定旋转的次数。最低位复制到进位标志位和最高位。在使用8086/8088处理器时,
imm8操作数必须为1。 - 标志位影响:
-
功能:将目的操作数向右旋转,使用源操作数确定旋转的次数。最低位复制到进位标志位和最高位。在使用8086/8088处理器时,
O D I S Z A P C
* *
- 指令格式:
ROR reg, imm8
ROR mem, imm8
ROR reg, CL
ROR mem, CL
2.9 位操作指令
-
BT(Bit Tests)
- 功能:将指定的位(n)复制到进位标志位。目的操作数包含位所在的值,源操作数指示该位在目的操作数中的位置。
- 标志位影响:
O D I S Z A P C
? ? ? *
- 指令格式:
BT r/m16, imm8
BT r/m16, r16
BT r/m32, imm8
BT r/m32, r32
-
BTC(Bit Tests and Complement)
- 功能:将指定的位(n)复制到进位标志位,并对目的操作数中的该位取反。
- 标志位影响:同BT指令。
- 指令格式:同BT指令。
-
BTR(Bit Tests and Clear)
- 功能:将指定的位(n)复制到进位标志位,并清除目的操作数中的该位。
- 标志位影响:同BT指令。
- 指令格式:同BT指令。
-
BTS(Bit Tests and Set)
- 功能:将指定的位(n)复制到进位标志位,并设置目的操作数中的该位。
- 标志位影响:同BT指令。
- 指令格式:同BT指令。
2.10 浮点指令集
2.10.1 浮点指令概述
浮点指令用于处理浮点数的运算和操作。以下是一些常见的浮点指令及其功能和格式。
2.10.2 浮点算术运算指令
-
FADD(Add floating - point)
- 功能:将目的操作数和源操作数相加,结果存储在目的操作数中。
- 指令格式:
FADD ST(0), ST(1), and pop stack
FADD m32fp
FADD m64fp
FADD ST(0), ST(i)
FADD ST(i), ST(0)
-
FADDP(Add floating - point and pop)
- 功能:执行与FADD相同的操作,然后弹出栈。
- 指令格式:
FADDP ST(i), ST(0)
-
FDIV(Divide floating - point and pop)
- 功能:将目的操作数除以源操作数,结果存储在目的操作数中。
- 指令格式:
FDIV ST(1) = ST(1) / ST(0), and pop stack
FDIV m32fp
FDIV m64fp
FDIV ST(0), ST(i)
FDIV ST(i), ST(0)
-
FDIVP(Divide floating - point and pop)
- 功能:执行与FDIV相同的操作,然后弹出栈。
- 指令格式:
FDIVP ST(i), ST(0)
2.10.3 浮点加载和存储指令
-
FLD(Load floating - point value onto register stack)
- 功能:将浮点值加载到寄存器栈中。
- 指令格式:
FLD m32fp
FLD m64fp
FLD m80fp
FLD ST(i)
-
FST(Store floating - point value)
- 功能:将寄存器栈中的浮点值存储到内存中。
- 指令格式:
FST m32fp
FST m64fp
FST ST(i)
-
FSTP(Store floating - point value and pop)
- 功能:执行与FST相同的操作,然后弹出栈。
- 指令格式:
FSTP m80fp
2.10.4 浮点比较指令
-
FCOM(Compare floating - point values)
- 功能:比较ST(0)和源操作数,根据结果设置FPU状态字中的条件码标志位。
- 指令格式:
FCOM m32fp
FCOM m64fp
FCOM ST(i)
FCOM
-
FCOMP(Compare floating - point values and pop)
- 功能:执行与FCOM相同的操作,然后弹出栈。
- 指令格式:同FCOM相关操作格式。
-
FCOMI(Compare floating - point values and set EFLAGS)
- 功能:比较ST(0)和ST(i),根据结果设置EFLAGS寄存器中的状态标志位。
- 指令格式:
FCOMI ST(0), ST(i)
以下是浮点指令执行流程的mermaid流程图:
graph TD;
A[开始] --> B{是否执行FADD指令};
B -- 是 --> C[执行加法操作];
C --> D[存储结果];
D --> E{是否需要弹出栈};
E -- 是 --> F[弹出栈];
F --> G[结束];
E -- 否 --> G;
B -- 否 --> H{是否执行FCOM指令};
H -- 是 --> I[执行比较操作];
I --> J[设置标志位];
J --> G;
H -- 否 --> G;
2.11 指令使用示例
2.11.1 加法运算示例
MOV AX, 10 ; 将10赋值给AX
MOV BX, 20 ; 将20赋值给BX
ADD AX, BX ; AX = AX + BX,此时AX的值为30
2.11.2 浮点加载和加法示例
FLD m32fp ; 将m32fp中的浮点值加载到ST(0)
FADD m64fp ; 将m64fp中的浮点值加到ST(0)
2.12 指令总结
| 指令类型 | 常见指令 | 功能概述 |
|---|---|---|
| ASCII调整指令 | AAA、AAD、AAM、AAS | 用于ASCII和BCD数字的调整 |
| 算术运算指令 | ADC、ADD | 执行加法和带进位加法 |
| 逻辑运算指令 | AND | 执行逻辑与运算 |
| 字符串操作指令 | MOVS、LODS | 进行字符串的移动和加载 |
| 条件跳转指令 | JA、JE等 | 根据标志位条件跳转 |
| 栈操作指令 | PUSH、POP | 进行栈的压入和弹出操作 |
| 移位和旋转指令 | RCL、RCR等 | 进行移位和旋转操作 |
| 位操作指令 | BT、BTC等 | 进行位测试和修改 |
| 浮点指令 | FADD、FCOM等 | 进行浮点数的运算和比较 |
通过对IA - 32指令集的详细了解,开发者可以更好地进行汇编语言编程,实现各种复杂的功能。在实际应用中,需要根据具体的需求选择合适的指令,并注意指令对标志位的影响,以确保程序的正确性和高效性。
超级会员免费看

被折叠的 条评论
为什么被折叠?



