x64指令参考:部分常用指令解析
1. ROL/ROR:循环左移/循环右移
1.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
ROL和ROR操作中,CF会在每次移位操作时被更新,ROL将最左位复制到CF,ROR将最右位复制到CF。OF仅在按1位移位的形式中被修改,按CL移位后,OF变为未定义。若移位位数为0,则所有标志位不受影响。
1.2 合法形式
- ROL/ROR r/m8,1
- ROL/ROR r/m16,1
- ROL/ROR r/m32,1 (386+)
- ROL/ROR r/m64,1 (x64+)
- ROL/ROR r/m8,CL
- ROL/ROR r/m16,CL
- ROL/ROR r/m32,CL (386+)
- ROL/ROR r/m64,CL (x64+)
- ROL/ROR r/m8,i8 (286+)
- ROL/ROR r/m16,i8 (286+)
- ROL/ROR r/m32,i8 (386+)
- ROL/ROR m/m64,i8 (x64+)
1.3 示例
ROL/ROR AX,1
ROL/ROR DWORD {EBX+ESI],9
ROL/ROR R14,17
ROL/ROR QWORD [BPI],CL
1.4 说明
ROL和ROR分别将目标操作数的位向左和向右循环移动。左移是向最高有效位(MSB)方向,右移是向最低有效位(LSB)方向。循环移位是一种会回绕的移位操作,ROL将操作数的最左位移到最右位,中间位都向左移一位;ROR则相反,将最右位移到最左位,其他位右移一位。
移位的位数可以指定为8位立即值或CL寄存器的值(不是CX/ECX/RCX)。虽然CL可以接受最大为255的值,但移位超过本机字长是无意义的。286及以后的处理器会将移位操作次数限制为本机字长,除非在虚拟86模式下运行。
1.5 流程图
graph TD;
A[开始] --> B{选择ROL或ROR};
B --> |ROL| C[确定移位位数];
B --> |ROR| D[确定移位位数];
C --> E[将最左位复制到CF];
D --> F[将最右位复制到CF];
E --> G[进行左循环移位];
F --> H[进行右循环移位];
G --> I{是否按1位移位};
H --> I;
I --> |是| J[修改OF];
I --> |否| K[OF未定义];
J --> L[结束];
K --> L;
2. SBB:带借位的算术减法
2.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
2.2 合法形式
- SBB r/m8,i8
- SBB r/m16,i16
- SBB r/m32,i32 (386+)
- SBB r/m64,i32 (x64+) 注意:SBB r/m64,i64 无效!
- SBB r/m16,i8
- SBB r/m32,i8 (386+)
- SBB r/m64,i8 (x64+)
- SBB r/m8,r8
- SBB r/m16,r16
- SBB r/m32,r32 (386+)
- SBB r/m64,r64 (x64+)
- SBB r8,r/m8
- SBB r16,r/m16
- SBB r32,r/m32 (386+)
- SBB r64,r/m64 (x64+)
- SBB AL,i8
- SBB AX,i16
- SBB EAX,i32 (386+)
- SBB RAX,i32 (x64+) 注意:SBB RAX,i64 无效!
2.3 示例
SBB DX,DI
SBB AX,04B2FH
SBB AL,CBH
SBB BP,19H
SBB DWORD [ESI],EAX
SBB QWORD [RAX],7BH
2.4 说明
SBB执行带借位的减法操作,从目标操作数中减去源操作数,然后再减去进位标志CF的值,结果替换目标操作数。若结果为负,则进位标志CF被设置。若要进行无借位的减法,可使用SUB指令。
在64位模式下,32位源操作数在减法操作前会被符号扩展为64位。
2.5 操作步骤
- 确定目标操作数和源操作数。
- 从目标操作数中减去源操作数。
- 从上述结果中减去CF的值。
- 将最终结果存储到目标操作数中。
- 根据结果设置标志位。
3. SHL/SHR:逻辑左移/逻辑右移
3.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
SHL和SHR操作后,AF变为未定义。OF仅在按1位移位的形式中被修改,按CL移位后,OF变为未定义。
3.2 合法形式
- SHL/SHR r/m8,1
- SHL/SHR r/m16,1
- SHL/SHR r/m32,1 (386+)
- SHL/SHR r/m64,1 (x64+)
- SHL/SHR r/m8,CL
- SHL/SHR r/m16,CL
- SHL/SHR r/m32,CL (386+)
- SHL/SHR r/m64,CL (x64+)
- SHL/SHR r/m8,i8 (286+)
- SHL/SHR r/m16,i8 (286+)
- SHL/SHR r/m32,i8 (386+)
- SHL/SHR m/m64,i8 (x64+)
3.3 示例
SHL/SHR AX,1
SHL/SHR DWORD {EDX+ESI],4
SHL/SHR R12,15
SHL/SHR QWORD [RDI],CL
3.4 说明
SHL和SHR根据源操作数指定的位数对目标操作数进行移位。SHL将目标操作数的位向左移,向最高有效位(MSB)方向;SHR将位向右移,向最低有效位(LSB)方向。
移位的位数可以指定为8位立即值或CL寄存器的值(不是CX/ECX/RCX)。286及以后的处理器会将移位操作次数限制为本机字长,除非在虚拟86模式下运行。
SHL操作中,最左位被移到CF,最右位清0;SHR操作中,最右位移到CF,最左位清0。
3.5 流程图
graph TD;
A[开始] --> B{选择SHL或SHR};
B --> |SHL| C[确定移位位数];
B --> |SHR| D[确定移位位数];
C --> E[将最左位移到CF];
D --> F[将最右位移到CF];
E --> G[进行左移位,最右位清0];
F --> H[进行右移位,最左位清0];
G --> I{是否按1位移位};
H --> I;
I --> |是| J[修改OF];
I --> |否| K[OF未定义];
J --> L[结束];
K --> L;
4. STC:设置进位标志(CF)
4.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志(被设置为1) |
4.2 合法形式
- STC
4.3 示例
STC
4.4 说明
STC将进位标志CF设置为已知的置位状态(1)。在需要使用进位标志位的任务之前可以使用该指令。与之类似的CLC指令会将CF清0。
4.5 操作步骤
执行STC指令,将CF标志位设置为1。
5. STD:设置方向标志(DF)
5.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志(被设置为1) |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
5.2 合法形式
- STD
5.3 示例
STD
5.4 说明
STD将方向标志DF设置为置位状态(1),这会影响重复字符串指令(如STOS、SCAS和MOVS)的调整操作。通常,当DF = 0时,目标指针递增;当DF = 1时,目标指针递减。CLD指令可将DF清0。
5.5 操作步骤
执行STD指令,将DF标志位设置为1。
6. STOS/B/W/D/Q:存储字符串
6.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
| 无标志位受影响 |
6.2 合法形式
- STOS m8
- STOS m16
- STOS m32
- STOS m64
- STOSB ; 用于8位操作
- STOSW ; 用于16位操作
- STOSD ; 用于32位操作
- STOSQ ; 用于64位操作
6.3 示例
STOSB ; 存储AL到 [EDI/RDI]
REP STOSB ; 存储AL到 [EDI/RDI] 及后续位置,重复 ECX/RCX 次
STOSW ; 存储AX到 [EDI/RDI]
STOSD ; 存储EAX到 [EDI/RDI]
REP STOSQ ; 存储RAX到 [EDI/RDI] 及后续位置,重复 ECX/RCX 次
6.4 说明
STOS将AL(8位存储操作)、AX(16位操作)、EAX(32位操作)或RAX(64位操作)存储到 [EDI] / [RDI] 指向的位置。在16位传统模式下,ES必须包含目标段地址且不能被覆盖;在32位和x64保护模式下,所有段都是一致的,因此不需要显式指定ES。同样,DI、EDI或RDI必须始终包含目标偏移量。
STOS形式必须有一个指定内存位置和大小的操作数,而STOSB、STOSW、STOSD和STOSQ形式在助记符中包含操作大小,其操作数是隐式的,存储操作指向EDI或RDI中的内存地址。
通过在CX/ECX/RCX中放置操作重复计数(不是字节计数),并在助记符前加上REP前缀,STOS可以自动将AL/AX/EAX/RAX存储到从 [DI]、[EDI] 或 [RDI] 开始的连续内存位置。每次存储后,DI/EDI/RDI寄存器会根据操作大小(8位操作加1,16位操作加2,32位操作加4,64位操作加8)进行调整,CX/ECX/RCX减1。
6.5 操作步骤
- 确定存储的数据(AL/AX/EAX/RAX)。
- 确保EDI/RDI包含目标偏移量。
- 若使用REP前缀,在CX/ECX/RCX中设置重复计数。
- 执行STOS指令。
- 根据DF的值和操作大小调整EDI/RDI。
- CX/ECX/RCX减1。
- 若CX/ECX/RCX不为0,重复步骤4 - 6。
6.6 流程图
graph TD;
A[开始] --> B{是否使用REP前缀};
B --> |是| C[设置CX/ECX/RCX重复计数];
B --> |否| D[跳过重复计数设置];
C --> E[执行STOS指令];
D --> E;
E --> F[根据DF和操作大小调整EDI/RDI];
F --> G[CX/ECX/RCX减1];
G --> H{CX/ECX/RCX是否为0};
H --> |否| E;
H --> |是| I[结束];
7. SUB:算术减法
7.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
7.2 合法形式
- SUB r/m8,i8
- SUB r/m16,i16
- SUB r/m32,i32 (386+)
- SUB r/m64,i32 (x64+) 注意:SUB r/m64,i64 无效!
- SUB r/m16,i8
- SUB r/m32,i8 (386+)
- SUB r/m64,i8 (x64+)
- SUB r/m8,r8
- SUB r/m16,r16
- SUB r/m32,r32 (386+)
- SUB r/m64,r64 (x64+)
- SUB r8,r/m8
- SUB r16,r/m16
- SUB r32,r/m32 (386+)
- SUB r64,r/m64 (x64+)
- SUB AL,i8
- SUB AX,i16
- SUB EAX,i32 (386+)
- SUB RAX,i32 (x64+) 注意:SUB RAX,i64 无效!
7.3 示例
SUB AX,DX
SUB AL,DL
SUB EBP,17
SUB RAX,0FFFBH ; 32位值在操作前符号扩展为64位
SUB DWORD [EDI],EAX
AND QWORD [RAX],7BH ; 32位值在操作前符号扩展为64位
7.4 说明
SUB执行无借位的减法操作,从目标操作数中减去源操作数,结果替换目标操作数。若结果为负,则进位标志CF被设置。
在64位模式下,32位源操作数在减法操作前会被符号扩展为64位。多精度减法可以通过先执行SUB,再执行SBB(带借位减法)来实现。
7.5 操作步骤
- 确定目标操作数和源操作数。
- 若为64位模式且源操作数为32位,将其符号扩展为64位。
- 从目标操作数中减去源操作数。
- 将结果存储到目标操作数中。
- 根据结果设置标志位。
8. SYSCALL:快速系统调用到Linux
8.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
| 无标志位受影响 |
8.2 合法形式
- SYSCALL
8.3 示例
SYSCALL
8.4 说明
SYSCALL用于快速调用预定义的操作系统服务例程(不包括调用C库),仅在64位模式下可用。目前有335个这样的服务例程,这些例程没有名称,通过编号选择。通常,在执行SYSCALL之前,需要在寄存器中加载所需服务例程的编号和适合该服务例程的值。
SYSCALL会破坏RCX和R11寄存器,其他寄存器会被保留。可参考以下网站获取可用的x64 Linux系统调用列表:
- https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64
- https://hackeradam.com/x86-64-linux-syscalls
SYSCALL取代了32位Linux中的INT 80调用协议,注意x64系统调用的编号与32位x86 Linux不同。
8.5 操作步骤
- 确定所需的系统服务例程编号。
- 在相应寄存器中加载适合该服务例程的值。
- 执行SYSCALL指令。
- 处理返回结果。
9. XCHG:交换操作数
9.1 受影响的标志位
| 标志位 | 含义 |
|---|---|
| OF | 溢出标志 |
| TF | 陷阱标志 |
| AF | 辅助进位标志 |
| DF | 方向标志 |
| SF | 符号标志 |
| PF | 奇偶标志 |
| IF | 中断标志 |
| ZF | 零标志 |
| CF | 进位标志 |
| 无标志位受影响 |
9.2 合法形式
- XCHG r/m8,r8
- XCHG r/m16,r16
- XCHG r/m32,r32 (386+)
- XCHG r/m64,r64 (x64+)
- XCHG r8,r/m8
- XCHG r16,r/m16
- XCHG r32,r/m32 (386+)
- XCHG r64,r/m64 (x64+)
- XCHG AX,r16
- XCHG EAX,r32 (386+)
- XCHG RAX,r64 (x64+)
- XCHG r16,AX
- XCHG r32,EAX (386+)
- XCHG r64,RAX (x64+)
9.3 示例
XCHG AL,AH
XCHG EAX,EBX
XCHG R12,[RSI+Offset]
XCHG [RDI],RDX
9.4 说明
XCHG用于交换两个操作数的内容,两个操作数必须大小相同。
9.5 操作步骤
- 确定要交换的两个操作数。
- 交换两个操作数的内容。
超级会员免费看
84万+

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



