我正在尝试模仿以下代码,它应该在汇编中打印1 2:
a=1
switch(a) {
default: print 1;
case 2: print 2;
}
这就是我所拥有的:
movq $1, a
pushq a
popq %rdx
cmp $1, %rdx
jne if_0
jmp if_1
if_0:
movq $1, %rsi
pushq %rsi
movq $format, %rdi
popq %rsi
pushq %rbp
call printf
movq %rbp, %rsp
popq %rbp
jmp if_2
if_1:
movq $2, %rsi
pushq %rsi
popq %r11
cmpq %rdx, %r11
je if_2
jne if_3
if_2:
movq $2, %rsi
pushq %rsi
movq $format, %rdi
popq %rsi
pushq %rbp
call printf
movq %rbp, %rsp
popq %rbp
jmp if_4
if_3:
if_4:
jmp switch_0
在顶部,我只是将变量与1进行比较,因为我不确定该怎么做。在进行默认情况之前,我如何向前看并看到a不等于2?
答案 0 :(得分:2)
您正在充当编译器,因此您可以在所有情况下“向前看”,如果交换机不 default
,则会看到2
案例
或者,如果你是一个更精简的“编译器”,你可以看到代码始终打印1 2
而不进行任何比较。
答案 1 :(得分:2)
您的代码似乎过于复杂。
查看C代码和相应的ASM代码
int printer(int a)
{
switch(a)
{
default: printf("%s","1");
case 2: printf("%s","2");
}
}
是的 - 我知道你设置了= 1 - 但是如果你事先知道结果,那么比较没有任何意义。在非优化的ASM结果下面 - 有putchar因为字符串是一个字母 - 但是这可以根据需要更改为printf。
printer(int):
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
cmp eax, 2
je .L5
mov edi, 49
call putchar
.L5:
mov edi, 50
call putchar
nop
leave
ret
通过优化,它甚至更简单
printer(int):
cmp edi, 2
jne .L13
mov edi, 50
jmp putchar
.L13:
sub rsp, 8
mov edi, 49
call putchar
mov edi, 50
add rsp, 8
jmp putchar
你可能已经注意到了gcc技巧 - 它完全删除了堆栈帧和ret指令。