我有一个问题要求将汇编代码转换为C代码。
我已经尝试过转换代码,但我认为我基本上是正确的,但是我对leaq指令感到困惑。
looper:
movl $o, %eax
movl $o, %edx
jmp .L2
.L4:
movq (%rsi, %rdx, 8), %rcx
cmpq %rcx, %rax
jl .L3
movq %rax, %rcx
.L3:
leaq 1(%rcx), %rax
addq $1, %rdx
.L2:
cmpq %rdi, %rdx
jl .L4
rep ret
Run Code Online (Sandbox Code Playgroud)
这是我得到的C代码:
long looper(long n, long *a) {
long i;
long x = 0;
for (i = 0; i < n; i++) {
if (x < a[i]) {
x = a[i] + 1;
}
x = a[i];
}
return x;
}
Run Code Online (Sandbox Code Playgroud)
首先,您的程序集中似乎有一个错误:看起来$o应该是$0(零)。
您的C代码几乎是正确的,存在一些错误:
jl .L3实际上,如果%rax < %rcx采用分支,而指令movq %rax, %rcx被忽略,则指令生成的分支的顺序非常重要。另一方面,如果未采用分支,则在进入之前执行该移动.L3。因此,您基本上交换了C代码中的两个分支。
的值a[i]并非每次都直接使用,而是在使用%rcx前先保存在寄存器中。二者movq %rax, %rcx并movq (%rsi, %rdx, 8), %rcx分配到%rcx,则该值是从传递%rcx到%rax,因此%rcx应被视为一个不同的变量。这意味着写作x = a[i] + 1;是错误的。它应该是:
tmp = a[i];
/* ... */
x = tmp + 1;
Run Code Online (Sandbox Code Playgroud)生成的C代码应如下所示:
int64_t looper(int64_t n, int64_t *arr) {
int64_t result; // rax
int64_t tmp; // rcx
int64_t i; // rdx
result = 0;
for (i = 0; i < n; i++) {
tmp = arr[i];
if (result >= tmp)
tmp = result;
result = tmp + 1;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
另外,使用as -o prog prog.sRadare2 编译二进制文件然后将其反汇编,可以得到以下相当简单的控制流程图:
tmp = a[i];
/* ... */
x = tmp + 1;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |