2015-11-05 145 views
1

我试图将一些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) 
+2

您知道有一个[mov指令](http://x86.renejeschke.de/html/file_module_x86_id_176.html),允许您将值从内存移入或移出寄存器。您使用一种效率较低的方法推送堆栈中的东西并将它们弹出到目标中。 –

回答

4

错误是一个“除以零”。 jl L001如果(n < 0)离开循环,但它应该离开如果(n < = 0)。所以将它改为jle L001(jle =如果小于或等于,则跳转)。

另外,leave是错误的。没有任何序言需要扭转。去掉它。

+0

谢谢。我已经在这个编译器上工作了三天多了,我的脑袋开始变得有点乱。 – seb

+1

@seb:我建议使用_GCC_'-g3'选项编译添加调试信息。然后使用GNU Debugger(gdb)单步执行代码。查看代码出错和导致错误的方式要容易得多。 –