jmp loop #无条件
Instruction 指令 | Condition 条件 | Description 描述 |
---|---|---|
jz |
D = 0 |
目标等于零 |
jnz |
D != 0 |
目的地不等于零 |
js |
D < 0 |
目标为负数 |
jns |
D >= 0 |
目的地不是负数 (即 0 或正数) |
jg |
D > S |
目标大于 源 |
jge |
D >= S |
目标大于或等于 源 |
jl |
D < S |
目标小于 源 |
jle |
D <= S |
目标小于或等于 源 |
有关条件的完整列表,我们可以参考最新的英特尔 x86_64 手册
RFLAGS
寄存器与任何其他寄存器一样由 64 位组成。但是,该寄存器不保存值,而是保存标志位。每个位“或位集”根据最后一条指令的值变为 1
或 0
。
Bit(s) | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12-13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22-63 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Label (1 /0 ) |
CF (CY /NC ) |
1 |
PF (PE /PO ) |
0 |
AF (AC /NA ) |
0 |
ZF (ZR /NZ ) |
SF (NC /PL ) |
TF |
IF (EL /DI ) |
DF (DN /UP ) |
OF (OV /NV ) |
IOPL |
NT |
0 |
RF |
VM |
AC |
VIF |
VIP |
ID |
0 |
Description | Carry Flag | Reserved | Parity Flag | Reserved | Auxiliary Carry Flag | Reserved | Zero Flag | Sign Flag | Trap Flag | Interrupt Flag | Direction Flag | Overflow Flag | I/O Privilege Level | Nested Task | Reserved | Resume Flag | Virtual-x86 Mode | Alignment Check / Access Control | Virtual Interrupt Flag | Virtual Interrupt Pending | Identification Flag | Reserved |
常用标志:
CF:
指示我们是否有浮点。PF:
指示数字是奇数还是偶数。ZF
:指示数字是否为零。[1]SF:
指示寄存器是否为负数。cmp rax, rbx -> rax - rbx #(第一个操作数 - 第二个操作数)来设置 RFLAGS
注: 在 cmp
指令中,第一个操作数(即目标)必须是寄存器,而另一个可以是寄存器、变量或立即数。
https://academy.hackthebox.com/storage/modules/85/conditional.zip
附件中的汇编代码一直循环。请尝试修改 (mov rax, 5) 使其不再循环。哪个十六进制值可以避免循环?
global _start
section .text
_start:
mov rax, 2 ; 改为 2(十六进制 0x2)
imul rax, 5
loop:
cmp rax, 10
jnz loop
检测运算结果最低字节(低8位)中 1 的个数是否为偶数。
PF = 1:最低字节中 1 的个数为偶数(包括 0 个)
PF = 0:最低字节中 1 的个数为奇数
计算示例:
mov al, 0x07 ; al = 0000 0111(3个1)→ 奇数 → PF=0
mov al, 0x03 ; al = 0000 0011(2个1)→ 偶数 → PF=1
mov al, 0xFF ; al = 1111 1111(8个1)→ 偶数 → PF=1
mov al, 0x00 ; al = 0000 0000(0个1)→ 偶数 → PF=1↩︎