X86汇编:复杂逻辑判断_针对性扫盲

1. IF体系_基础复习

1.1 IF

1.1.1 C语言代码

1.1.2 单IF执行流程

1.1.3 反汇编代码

  • 入口判断:

    • 不跳转 (Fall through): 代表条件满足,进入 IF 内部(此为真)。

    • 跳转 (Jump): 代表条件不满足,跳过 IF 内部(此为假)。

  • 出口行为:

    • 如果是 IF...ELSE: IF 结尾必须有 JMP(为了跳过 Else)。

    • 如果是 单 IF (且无 return): IF 结尾通常没有 JMP,大家殊途同归,汇合继续往下走。

    • 如果是 单 IF (有 return): 需要JMP跳过。


1.2 IF...ELSE

1.2.1 C语言代码

1.2.2 IF...ELSE执行流程

1.2.3 反汇编代码

  • 入口判断:

    • 不跳转:代表为真,进入IF部分。

    • 跳转:代表为假,进入ELSE部分 。

  • IF...ELSE 的核心特征 = "两条路,一个墙,终点见"

    • 两条路: 入口处的 JCC (条件跳转) 决定走红路还是走不跳的路。

    • 一个墙: IF 代码块结束时的那个 JMP (绿线),就是隔离墙。这是识别 IF...ELSE 最硬的铁证! 只要看到这个跳过中间一段代码的 JMP,它就是 ELSE 结构。

    • 终点见: IF 跳去的地方,和 ELSE 跑去的地方,永远是同一个汇合点(函数出口)。


1.3 IF...ELSE_IF

1.3.1 C语言代码

1.3.2 IF...ELSE_IF执行流程

1.3.3 反汇编代码

  • 入口判断:

    • IF...ELSE 的跳转是跳去"干活的代码"(ELSE块)。

    • ELSE IF 的跳转是跳去"另一个 CMP"(下一轮面试)。

    • 判定金标准:落地即 CMP = ELSE IF

  • 核心特征:

    • 红线 (False): 负责像下台阶一样,一级一级往下传。

    • 绿线 (True): 负责像坐滑梯一样,直接滑到最底部的出口。


1.4 IF...ELSE_IF...ELSE_IF

1.4.1 C语言代码

1.4.2 反汇编代码


1.5 IF...ELSE_IF...ELSE

1.5.1 C语言代码

1.5.2 执行流程

1.5.3 反汇编代码


1.6 终极总结:汇编逻辑的"四种形态"


2. 趁热打铁_巩固练习

2.1 第一题

c 复制代码
; [开始判断]
CMP EAX, 10
JNE Label_Target_B    ; (红线:如果不满足,跳去 Label_Target_B)

    ; [Block_1 区域]
    MOV EBX, 1        ; 干活...
    JMP Label_Exit    ; (绿线:干完活,直接跳去出口!)

Label_Target_B:       ; <--- 红线落脚点
    ; [Block_2 区域]
    MOV EBX, 2        ; 干活...
    ; (干完活自然滑落到 Exit)

Label_Exit:           ; <--- 所有人汇合

你的判断是:

A. 单 IF

B. IF...ELSE

C. IF...ELSE IF

第一题答案:B

  • A不对,如果是单IF的话,不会跳这么远,中间还跳过了好多汇编代码,这是铁证。

  • C不对如果是if...else_if框架的话,那么第一个执行完以后,跳转刀第二个label_b需要继续判断这也是else_if和else的最大区别。


2.2 第二题

c 复制代码
; [第一次判断]
CMP EAX, 10
JNE Label_Next_Check  ; (红线:如果不满足,跳去 Label_Next_Check)

    ; [Block_1 区域]
    MOV EBX, 1
    JMP Label_Exit    ; (绿线:赢了直接走)

Label_Next_Check:     ; <--- 红线落脚点
    ; [第二次判断]
    CMP EAX, 20       ; <--- 🚨 注意这里!落地就是 CMP
    JNE Label_Exit    ; (如果不满足,直接走了)

    ; [Block_2 区域]
    MOV EBX, 2
    ; (干完活自然滑落)

Label_Exit:

你的判断是:

A. IF...ELSE

B. 两个顺序的 IF (if ... if ...)

C. IF...ELSE IF

第二题答案是:C

  • 原因如下:第一个条件失败跳转到lebel_next_check以后又继续进行判断,这是证据一,排除else。

  • 第一个条件下,我们执行完核心代码JMP到label_exit,跳过去了第二个条件,这是排除双重if的铁证。


2.3 第三题

c 复制代码
; [第一次判断]
CMP EAX, 10
JNE Label_Check_2     ; (红线:如果不满足,跳去 Label_Check_2)

    ; [Block_1 区域]
    MOV EBX, 1
    ; <--- 🚨 警报:这里没有 JMP 指令!

Label_Check_2:        ; <--- 红线落脚点
    ; [第二次判断]
    CMP EAX, 20       ; 再次判断
    JNE Label_Exit

    ; [Block_2 区域]
    MOV EBX, 2

Label_Exit:

你的判断是:

A. IF...ELSE IF (梯子)

B. 两个顺序的 IF (if ... if ...)

C. IF...ELSE

题目三的答案是:B

  • 如果在两个连续cmp中不存在JMP核心指令只能说明这两个cmp是分开的。

  • 理由如下:如果存在JMP代表互斥性,说明是强分支关系,这也是IF...ELSE_IF...ELSE的核心特征之一。但是上面不存在JMP所以不是IF多分枝体系,而是两条IF体系。


3. 逻辑符号理论复习

3.1 逻辑与 && (And) ------ "同生共死"

  • 场景: if (A && B)

  • 红线 (False): A 挂了去出口,B 挂了也去同一个出口。

  • 绿线 (True): A 过了查 B,B 过了才能进核心房间。

  • 本质: 就是连环单 IF(或嵌套 IF),中间通常没别的代码。

3.2 逻辑或 || (Or) ------ "殊途同归"

  • 场景: if (A || B)

  • 红线 (False): A 挂了去查 B(给第二次机会)。

  • 绿线 (True): A 成了去VIP房,B 成了也去同一个VIP房。

  • 核心特征: 两个入口,一个房间。

3.3 阶梯结构 Else If (Ladder) ------ "各回各家"

  • 场景: if (A) ... else if (B) ...

  • 红线 (False): A 挂了去查 B(给第二次机会)。

  • 绿线 (True): A 成了去房间 1,B 成了去房间 2。

  • 核心特征: 两个入口,两个房间(且中间有 JMP 隔离)。


4. 基础逻辑符号

4.1 A && B

4.1.1 C语言代码

4.1.2 A && B 执行流程

4.1.3 反汇编代码

4.2 A || B

4.2.1 C语言代码

4.2.2 A || B 执行流程

4.2.3 反汇编代码

5. && 以及 or 阶段性总结

5.1 逻辑或 vs if...else_if混淆点

  • 逻辑或: 两个条件共有一个执行体,一个为真则直接跳转执行体。

  • if...else_if: 两个条件各自存在自己的房间,成立直接进行,但是执行完会被JMP强制弹出判断体系。

  • 如果都没有成立,则直接顺滑跳出判断体系。

5.2 逻辑与 vs 嵌套if

  • 逻辑与: 两个条件共有一个房间,两个条件都需要成立才能进入执行体。

  • 嵌套IF: 在汇编角度与逻辑与基本没有差别,但是需要注意的是中间是否夹带私货,如果存在变量等的创建,则需要用嵌套IF体系。

5.3 复杂混合逻辑 (&& 混搭 ||)

  • 痛点: 长长的一串 a || b && c || d,不知道括号怎么加。

  • 破解心法: 数学法则(乘法优先,加法靠后)。

    • 口诀:&& 是乘法,|| 是加法。

    • 操作步骤:

      • 找加号 (||): 把它当做**"隔离墙"**,把长句子切开。

      • 算乘法 (&&): 墙与墙之间的部分,必须内部先抱团(加括号)。

      • 看短路:

        • 遇到 ||: 前面的成了,直接跳终点(后面全不看)。

        • 遇到 &&: 前面的废了,直接跳下一段(本段后面全不看)。

  • 实战案例: a || b && c || d

    • 大脑自动加括号: a || (b && c) || d

    • 汇编执行流:

      • A 岛: 成了直接赢,输了去 B 岛。

      • BC 岛: B 和 C 必须同时成,才算赢;否则去 D 岛。

      • D 岛: 最后的防线。

5.4 短路求值 (Short-Circuit) 的红绿线铁律

  • 这是汇编优化的核心,也是你画图的依据:

  • 对于 || (或):

    • 只要有一个绿线 (True) →\rightarrow→ 立即触发大跳跃,飞向执行体 (VIP房)。
  • 对于 && (与):

    • 只要有一个红线 (False) →\rightarrow→ 立即触发大清洗,飞向失败区 (Else/Exit)。

6. 逻辑与(&&) vs 逻辑或(||) 的终极判定

6.1 为什么以前会混淆?(极简代码的陷阱)

  • 现象: 在极简代码(如单纯的 0/1 布尔判断)中,编译器会进行极致优化。

  • 后果: 此时逻辑结构被压缩,&& 和 || 的汇编形态几乎一模一样(仅体现为 JE 与 JNE 的指令差异)。跳转距离极短,肉眼很难通过"流向"来区分。

  • 结论: 极简状态下的"形似"是最大的迷惑来源。

6.2 真正的判据:复杂场景下的"流向拓扑"

  • 当代码恢复正常复杂度(逻辑判断且无变量穿插)时,"落脚点" (Destination) 才是唯一的真理。

6.3 一句话总结(笔记):

不看指令长得像不像,只看它们跳得一不一样。
两跳去同处,必是逻辑与;两跳分两路,定是逻辑或。

7. 复合逻辑嵌套组合

7.1 A && B || C

7.1.1 C语言代码

7.1.2 反汇编代码

7.1.3 逻辑梳理

7.2 A || B && C

7.2.1 C语言代码

7.2.2 反汇编代码

7.2.3 逻辑梳理

7.3 (A && B) || (C && D)

7.3.1 C语言代码

7.3.2 反汇编代码

7.3.3 逻辑梳理

7.4 (A || B)&&(C || D)

7.4.1 C语言代码

7.4.2 反汇编代码

7.4.3 逻辑梳理

7.5 (A || B) && (C || D) && (A != D)

7.5.1 C语言代码

7.5.2 反汇编代码

7.5.3 逻辑梳理

7.6 (A > 5 && B < 10) || (C == 0 && D != 3) && E

7.6.1 C语言代码

7.6.2 反汇编代码

7.6.3 逻辑梳理

7.7 ((a ^ b) && (c | d)) ? (e & a) : !(b && c)

7.7.1 C语言代码

7.7.2 反汇编代码

本章完~

相关推荐
技术不好的崎鸣同学3 小时前
x64汇编之用调试器进行程序分析:GDB
汇编
是星辰吖~5 小时前
X86反汇编_深度学习:从 C 指针到汇编逻辑
汇编
iCxhust1 天前
c#多串口重量采集上位机程序
开发语言·汇编·c#·微机原理·8088单板机
AI科技星1 天前
万有引力G与真空介电常数ε0全维度完整关系式汇编(基于v=c螺旋时空理论)
c语言·开发语言·前端·javascript·网络·汇编·electron
技术不好的崎鸣同学1 天前
x64汇编之GDB进阶与printf
汇编
是星辰吖~2 天前
X86反汇编:深度学习阶段_2
汇编
程序喵大人2 天前
从内存/汇编角度看C与C++:指针、引用、对象的底层差异
c语言·汇编·c++·指针·引用·对象
是星辰吖~2 天前
X86反汇编_深度学习阶段_1
汇编
say_fall2 天前
输入输出技术_接口到中断完全指南
汇编·微机原理·8086