Assembly 我不断地犯错误。如何使用AT&;在IA-32中使用堆栈;T
对于家庭作业,我们被要求扫描一个数字,递增一,然后打印答案。然而,代码往往会给出一个分段错误Assembly 我不断地犯错误。如何使用AT&;在IA-32中使用堆栈;T,assembly,att,x86,Assembly,Att,X86,对于家庭作业,我们被要求扫描一个数字,递增一,然后打印答案。然而,代码往往会给出一个分段错误 .global main mystring: .asciz "Assignment 3: inout\n" string: .asciz "%d" main: pushl $mystring call printf jmp inout end: pushl $0 call exit 这基本上就是我们正在做的。在没有跳转的情况下运行这样的
.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
这似乎不起作用。我也不知道开头(减号,地址)是什么意思,更多信息请参见注释。提前谢谢 部分答案,但这可能会帮助您找到问题:
subl$0,%esp
将在常量不为零的情况下增加堆栈。堆栈的顶部通常位于x86中的最低内存地址,即堆栈向下增长
leal-4(%ebp),%eax
将绝对地址%ebp-4
加载到%eax
中。这是指向存储scanf
d整数的内存位置的指针
为什么要推送基本指针,这确实是一个相关的问题。你通常是这样做的,因为你在事后修改它,做一些事情,然后在完成后pop
。它通常与您调用的函数一起使用。这很可能就是这里的问题所在,您调用inout
一个方法,但只将其用作jmp
的标签。您发布的代码现在没有机会返回到它原来的位置jmp
ed-from
对x86堆栈帧有一个相当简洁的介绍。此外,
scanf
返回在%eax
中读取的项目数,而不是scanf
ed的数字。递增%eax
不会给出您想要的结果。