我必须从汇编中对C语言中的switch语句进行逆向工程。当我使用-S标志编译来获取汇编代码从C写入时,它是不正确的。关于我做错了什么的任何见解?
提前致谢!
这是程序集
.file "switch_prob-soln.c"
.text
.globl switch_prob
.type switch_prob, @function
switch_prob:
.LFB0:
.cfi_startproc
subq $50, %rsi
cmpq $5, %rsi
ja .L2
jmp *.L7(,%rsi,8)
.section .rodata
.align 8
.align 4
.L7:
.quad .L3
.quad .L2
.quad .L3
.quad .L4
.quad .L5
.quad .L6
.text
.L3:
leaq 0(,%rdi,4), %rax
ret
.L4:
movq %rdi, %rax
sarq $2, %rax
ret
.L5:
leaq (%rdi,%rdi,2), %rdi
.L6:
imulq %rdi, %rdi
.L2:
leaq 10(%rdi), %rax
ret
.cfi_endproc
.LFE0:
.size switch_prob, .-switch_prob
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
这是我写的C
long switch_prob(long x, long n){
long result = x;
switch(n){
case 50:
case 51:
result + 4;
break;
case 52:
result >> 2;
break;
case 53:
result + result + 2;
merge:
result * result
break;
default:
result * 10;
break;
}
return result;
}
答案 0 :(得分:0)
按照汇编代码的逻辑,我猜是这样的:
int switch_prob(int x, int n) {
int result = x;
switch (n - 50) {
case 0:
case 2:
result += 4;
break;
case 3:
result >>= 2;
break;
case 4:
result += 2;
case 5:
result *= result;
break;
default:
result += 10;
}
return result;
}
您可以测试解决方案的一种方法是编写一个驱动程序,如:
<强> test.c的强>
#include <stdio.h>
int switch_prob(int x, int n);
int main() {
printf("%d\n", switch_prob(1, 54));
return 0;
}
然后使用您的驱动程序编译汇编代码(如果它与您的系统兼容):
gcc -Wall test.c switch_prob-soln.s
然后编辑test.c文件,将参数更改为switch_prob()
以查看您的假设是否成立。我猜测跳转表告诉我们一些关于案例的事情:
.quad .L3 # case 0: addition (LEA)
.quad .L2 # default: (no case 1:) addition (LEA)
.quad .L3 # case 2: is case 0: again
.quad .L4 # case 3: right shift (SAR)
.quad .L5 # case 4: addition (LEA)
.quad .L6 # case 5: multiplication (IMUL)