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 反汇编代码

本章完~