目标:获取此汇编代码:
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $16, %esp
movl $-559038737, -16(%ebp)
movl $0, -12(%ebp)
movl $1, -8(%ebp)
jmp .L2
.L3:
movl -8(%ebp), %eax
andl -16(%ebp), %eax
testl %eax, %eax
setne %al
movzbl %al, %eax
addl %eax, -12(%ebp)
sall -8(%ebp)
.L2:
cmpl $0, -8(%ebp)
jne .L3
addl $16, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
填空:
#include <stdio.h>
int main()
{
int x = 0x________;
int result = ______;
int mask;
for (mask = _________; mask _______; mask = ________) {
result += ________;
}
}
我得到了什么:
#include <stdio.h>
int main()
{
int x = 0xFFFFFFFFDEADBEEF;
int result = 0;
int mask;
for (mask = 1; mask != 0; mask = mask + 1)
{
result += x & mask;
}
}
我的汇编代码:
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $-559038737, -4(%ebp)
movl $0, -12(%ebp)
movl $1, -8(%ebp)
jmp .L2
.L3:
movl -8(%ebp), %eax
movl -4(%ebp), %edx
andl %edx, %eax
addl %eax, -12(%ebp)
sall -8(%ebp)
.L2:
cmpl $0, -8(%ebp)
jne .L3
leave
ret
我已经坚持了几个小时:如何添加此C代码以使其使用命令testl, setne, and movzbl
?我知道testl检查两个操作数是否为0,但我不确定它适合C程序的上下文。另外,主要做底部的addl $16, %esp
是什么?只是再次指向堆栈的停止?
答案 0 :(得分:0)
您是否使用生成示例汇编代码的相同编译器?首先,andl $ -16,%esp将esp向下舍入到16字节边界。编译器是否有编译时选项可以导致这种情况发生?
示例代码末尾附近的addl $ 16,%esp从代码开头附近的$ 16,%esp恢复堆栈。
实际堆栈指针+ 4保存在ecx中,然后ecx被推送到示例代码开头附近的堆栈上,并在结束时恢复。然后使用leal $ -4(%ecx),%esp。
恢复esp以上所有内容都与编译器处理函数序言和结尾的方式有关。
汇编代码示例的其余部分转换为C代码示例,您只需按要求填写空白。