1. 状态检测:EFLAGS 寄存器

CPU 不通过“思考”来做决定,而是通过“副作用”来标记状态。CMPTEST 指令不改变寄存器值,只改变条件码。

标志位名称含义 (Meaning)触发场景
ZFZero Flag结果为零a == b 或结果为 0
SFSign Flag结果为负a < 0 (有符号)
OFOverflow Flag有符号溢出正+正=负,负+负=正
CFCarry Flag无符号进位/借位无符号比较 a < b

2. 跳转指令 (JUMP)

汇编中的跳转分为直接跳转(Label)和间接跳转*Operand)。

  • 条件跳转: je (Equal), jne (Not Equal), jg (Greater), jle (Less or Equal).
    • 逆向直觉: 看到 cmp a, b 紧接 jge Target,意味着 if (a >= b) goto Target
  • 条件传送 (CMOV):
    • 逻辑: cmovg %rax, %rbx
    • 工程意义: 现代 CPU 讨厌分支预测失败。用数据流(计算两个结果选一个)代替控制流(跳转),流水线效率更高。

3. 循环机制 (Loops)

C 语言的 do-while, while, for 在汇编层殊途同归:

  1. Jump-to-Middle: 先跳到循环体末尾测试条件。
  2. Guarded-Do: 先测试初始条件,如果不成立直接跳过;否则进入 do-while 结构。

4. Switch 语句与跳转表 (Jump Table)

  • 机制: 当 case 数量较多且密集时,GCC 会生成一个跳转表(数组),里面存放着各个代码块的地址。
  • 寻址: jmp *Start(,%rdi,8)。利用索引直接查表跳转。
  • 优势: O(1) 时间复杂度,与 case 数量无关。
  • 逆向特征:.rodata 段看到一连串紧密的地址数据。