课程
1906 字
约 6 分钟
大二上
GPT
计算机系统基础exercises/Homework/RainClass/chapter03·更新于 2026-09-15
CSAPP P.163
int sw(int x){
int v = 0;
switch (x) {
/* ... ... */
}
return v;
}
1 movl 8(%ebp), %eax
2 addl $3, %eax
3 cmpl $7, %eax
4 ja .L7
5 jmp *.L8(,%eax,4)
6 .L7 :
7 ...
8 ...
1 .L8 :
2 .long .L7
3 .long .L2
4 .long .L2
5 .long .L3
6 .long .L4
7 .long .L5
8 .long .L7
9 .long .L6
(1)取值0和6对应.L7 取值为1和2对应.L2 取值3对应.L3 取值4对应.L4 取值为5对应.L5 取值为7对应.L6
(2).L7是default分支,根据符号表,取值为0和6时会执行default
(3).L2,当取值为1和2时会执行相同的分支.L2
GPT
1. 函数 sw 中的 switch 语句处理部分标号的取值情况:
汇编代码分析:
1 movl 8(%ebp), %eax // 将函数参数 x(从栈中偏移8的位置)加载到 %eax 寄存器中
2 addl $3, %eax // 将 %eax 寄存器中的值加 3
3 cmpl $7, %eax // 比较 %eax 与 7
4 ja .L7 // 如果 %eax > 7(即x + 3 > 7),跳转到 .L7 标签(default 分支)
5 jmp *.L8(,%eax,4) // 根据 %eax 的值跳转到一个跳表地址,L8 是一个跳表的起始地址
6 .L7 :
7 ... // default 分支代码
8 ... // 其他代码
第1到第5行是 switch 语句的核心逻辑:
- 第 1 行:将
x传递的参数加载到eax寄存器。 - 第 2 行:
x加 3。注意到这一点,意味着x可能会被偏移。 - 第 3 行:比较
eax的值与 7。 - 第 4 行:如果
eax > 7(即x + 3 > 7),则跳转到标签.L7,即进入default分支。 - 第 5 行:如果
eax <= 7,则根据eax的值选择一个跳转地址,这个地址由.L8标签后面的跳表来决定。
跳表地址(从 .L8 开始):
6 .L8 :
2 .long .L7
3 .long .L2
4 .long .L2
5 .long .L3
6 .long .L4
7 .long .L5
8 .long .L7
9 .long .L6
从 .L8 开始的指令是一个跳表,其中每个 .long 指令指定一个跳转地址。具体来说:
-
eax的值从 0 到 7,跳表的值依次对应着这些情况:eax == 0跳转到.L7(这应该是default分支)eax == 1跳转到.L2eax == 2跳转到.L2eax == 3跳转到.L3eax == 4跳转到.L4eax == 5跳转到.L5eax == 6跳转到.L7(这也会跳到default分支)eax == 7跳转到.L6
2. 标号的取值在什么情况下执行 default 分支?
-
标号执行
default分支的条件:- 如果
x + 3 > 7(即x > 4),则跳转到.L7,执行default分支。 - 另外,
eax == 0或eax == 6时,也会跳转到.L7,因此这些情况下也会执行default分支。
- 如果
3. 哪些标号的取值会执行同一个 case 分支?
-
执行同一个
case分支的标号:eax == 1和eax == 2都会跳转到.L2,所以它们会执行相同的case逻辑。
其他的标号(
eax == 0、eax == 3eax == 4、eax == 5、eax == 6、eax == 7)分别跳转到不同的标签(.L7、.L3、.L4、.L5、.L7、.L6)。
总结:
- default 分支 会在
eax等于 0 或 6,或者x大于 4 时执行。 - 相同 case 分支:
eax == 1和eax == 2会跳转到.L2,即它们会执行相同的代码块。
Copilot
在函数 sw 中,switch 语句处理部分的标号取值情况如下:
-
标号的取值情况:
- 汇编代码中,
movl 8(%ebp), %eax将参数x的值加载到寄存器eax中。 addl $3, %eax将eax的值加3。cmpl $7, %eax比较eax的值与7。ja .L7如果eax的值大于7,则跳转到.L7,执行default分支。jmp *.L8(,%eax,4)根据eax的值跳转到对应的标签。
- 汇编代码中,
-
标号的取值在什么情况下执行 default 分支:
- 当
eax的值大于7时,跳转到.L7,执行default分支。 - 由于
eax的值是x + 3,所以当x + 3 > 7时,即x > 4时,执行default分支。
- 当
-
哪些标号的取值会执行同一个 case 分支:
-
.L8表中的值决定了跳转的目标标签:.long .L7对应eax为0或7,即x为-3或4,执行default分支。.long .L2对应eax为1或2,即x为-2或-1,执行相同的case分支。.long .L3对应eax为3,即x为0,执行case分支.L3。.long .L4对应eax为4,即x为1,执行case分支.L4。.long .L5对应eax为5,即x为2,执行case分支.L5。.long .L6对应eax为6,即x为3,执行case分支.L6。
-
总结:
default分支在x > 4或x == -3时执行。case分支.L2在x == -2或x == -1时执行。













