将伪代码转换为程序集
问题描述:
我试图将一些C伪代码转换为i386汇编代码,但从来没有弄清楚。将伪代码转换为程序集
n=1;
s=50;
a=0;
while(n > 0) {
a=s/n;
n=n-1;
}
print a;
上面的代码是通过产生一个编译器被翻译成汇编代码:
.data
variables: .space 104
msg: .asciz "Message %d\n"
.text
.global main
main:
push $1
pop variables+52
push $50
pop variables+72
push $0
pop variables+0
L000:
push variables+52
push $0
pop %ebx
pop %eax
cmp %ebx,%eax
jl L001
push variables+72
push variables+52
pop %ebx
pop %eax
xor %edx,%edx
idivl %ebx
push %eax
pop variables+0
push variables+52
push $1
pop %ebx
pop %eax
sub %ebx,%eax
push %eax
pop variables+52
jmp L000
L001:
push variables+0
push $msg
call printf
add $8,%esp
leave
ret
我不能得到的代码正常运行。它导致分段错误。我得到的输出是:
Message 0
Segmentation fault (core dumped)
答
错误是一个“除以零”。 jl L001
如果(n < 0)离开循环,但它应该离开如果(n < = 0)。所以将它改为jle L001
(jle =如果小于或等于,则跳转)。
另外,leave
是错误的。没有任何序言需要扭转。去掉它。
+0
谢谢。我已经在这个编译器上工作了三天多了,我的脑袋开始变得有点乱。 – seb
+1
@seb:我建议使用_GCC_'-g3'选项编译添加调试信息。然后使用GNU Debugger(gdb)单步执行代码。查看代码出错和导致错误的方式要容易得多。 –
您知道有一个[mov指令](http://x86.renejeschke.de/html/file_module_x86_id_176.html),允许您将值从内存移入或移出寄存器。您使用一种效率较低的方法推送堆栈中的东西并将它们弹出到目标中。 –