gpt4 book ai didi

c - 开关盒 assembly 级代码

转载 作者:太空狗 更新时间:2023-10-29 16:33:37 24 4
gpt4 key购买 nike

我正在 cygwin 窗口上编写 C 语言。在完成了一些 C 编程并熟悉了该语言之后,我想深入了解一下编译器对我编写的代码做了什么。

所以我写下了一个包含 switch case 语句的代码块,并使用以下方法将它们转换为程序集:

gcc -S foo.c  

这是 C 源代码:

switch(i)
{
case 1:
{
printf("Case 1\n");
break;
}
case 2:
{ printf("Case 2\n");
break;
}
case 3:
{
printf("Case 3\n");
break;
}
case 4:
{
printf("Case 4\n");
break;
}
case 5:
{
printf("Case 5\n");
break;
}
case 6:
{
printf("Case 6\n");
break;
}
case 7:
{
printf("Case 7\n");
break;
}
case 8:
{
printf("Case 8\n");
break;
}
case 9:
{
printf("Case 9\n");
break;
}
case 10:
{
printf("Case 10\n");
break;
}
default:
{
printf("Nothing\n");
break;
}
}

现在生成的相同程序集是:

movl    $5, -4(%ebp)
cmpl $10, -4(%ebp)
ja L13
movl -4(%ebp), %eax
sall $2, %eax
movl L14(%eax), %eax
jmp *%eax
.section .rdata,"dr"
.align 4
L14:
.long L13
.long L3
.long L4
.long L5
.long L6
.long L7
.long L8
.long L9
.long L10
.long L11
.long L12
.text
L3:
movl $LC0, (%esp)
call _printf
jmp L2
L4:
movl $LC1, (%esp)
call _printf
jmp L2
L5:
movl $LC2, (%esp)
call _printf
jmp L2
L6:
movl $LC3, (%esp)
call _printf
jmp L2
L7:
movl $LC4, (%esp)
call _printf
jmp L2
L8:
movl $LC5, (%esp)
call _printf
jmp L2
L9:
movl $LC6, (%esp)
call _printf
jmp L2
L10:
movl $LC7, (%esp)
call _printf
jmp L2
L11:
movl $LC8, (%esp)
call _printf
jmp L2
L12:
movl $LC9, (%esp)
call _printf
jmp L2
L13:
movl $LC10, (%esp)
call _printf
L2:

现在,在程序集中,代码首先检查最后一个案例(即案例 10)。这很奇怪。然后它正在将“i”复制到“eax”中并做一些超出我的事情。

我听说编译器为 switch..case 实现了一些跳转表。这是这段代码在做什么吗?或者它在做什么,为什么?因为在案件数量较少的情况下,该代码与为 if...else 阶梯生成的代码非常相似,但是当案例数量增加时,就会看到这种看起来不寻常的实现。

提前致谢。

最佳答案

首先,代码将 i 与 10 进行比较,并在值大于 10 时跳转到默认情况(cmpl $10, -4(%ebp) 后跟 ja L13)。

下一段代码是将输入向左移动 2 (sall $2, %eax),这与乘以 4 的倍数相同,它会在跳转表中生成一个偏移量(因为每个表中的条目长 4 个字节)

然后它从跳转表 (movl L14(%eax), %eax) 加载一个地址并跳转到它 (jmp *%eax)。

跳转表只是一个地址列表(在汇编代码中用标签表示):

L14:
.long L13
.long L3
.long L4
...

需要注意的一件事是 L13 代表默认情况。它既是跳转表中的第一个条目(当 i 为 0 时),又在开始时被特殊处理(当 i > 10 时)。

关于c - 开关盒 assembly 级代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3012011/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com