0

对于家庭作业,我们被要求扫描一个数字,将其加一并打印答案。但是,代码往往会产生分段错误。

.global main

mystring: .asciz "Assignment 3: inout\n"

string: .asciz "%d"

main:   pushl $mystring
        call printf
        jmp inout

end:    pushl $0
        call exit

这基本上就是我们正在做的事情。在没有跳转的情况下运行这样的代码。问题出在 inout 方法中

inout:  subl $0, %esp             ;what is happening here
        leal -4(%ebp), %eax       ;what am i doing here
        pushl %ebp                ;why do i need to push the base pointer
        movl %esp, %ebp
        pushl %eax
        pushl $string
        call scanf
        incl %eax
        pushl %eax
        pushl $string
        call printf

这似乎不起作用。我也不知道开头(减法,地址)是什么意思,请参阅评论以了解更多信息。提前致谢!

4

1 回答 1

0

部分答案,但也许这会帮助您找出问题所在:

subl $0, %esp 如果常数不为零,堆栈会增长。栈顶通常在x86中的最低内存地址,即栈向下增长。

leal -4(%ebp), %eax将绝对地址加载%ebp - 4%eax. scanf这是指向应该存储 d 整数的内存位置的指针。

为什么要使用push基本指针确实是一个相关问题。你通常这样做是因为你事后修改它,做一些事情,然后pop当你完成时——看起来你没有。它通常与您的功能一起使用call。这很可能是这里的问题,你调用inout了一个方法,但你只是将它用作标签jmp。您发布的代码现在没有机会返回到它原来jmp的位置。

Wikibooks对 x86 堆栈框架有相当简洁的介绍。

于 2013-09-30T10:39:38.030 回答