x86组装,出现分段错误 [英] x86 Assembly, getting segmentation fault
问题描述
section .data
msg: db "hello!", 10, 0 ;my message
section .text
extern printf ;C printf function
global main
main:
push ebp
mov ebp, esp
call print_string
mov esp, ebp
pop ebp
ret ;end of program
print_string:
pusha
push msg
call printf ;should print "Hello"
popa
ret ;return back to main
运行此代码时,我得到:
你好!
分段错误(核心已转储)
When I run this code I get:
hello!
Segmentation fault (core dumped)
代码有什么问题?
推荐答案
print_string子例程正在修改堆栈指针而不恢复它.
子例程main
具有以下布局:
The print_string subroutine is modifying the stack pointer without restoring it.
The subroutine main
has the following layout:
push ebp ;save the stack frame of the caller
mov ebp, esp ;save the stack pointer
<code for subroutine>
mov esp, ebp ;restore the stack pointer
pop ebp ;restore the caller's stack frame
ret ;return to address pushed onto the stack by call
类似地,print_string子例程应该具有相同的布局,保存堆栈指针,然后在ret
之前恢复它.任何使用堆栈的子例程都应保存并恢复堆栈指针.
Similarly, the print_string subroutine should have that same layout, saving the stack pointer and then restoring it before ret
ing. Any subroutines that use the stack should save and restore the stack pointer.
push ebp
mov ebp, esp
pusha
push msg
call printf ;should print "Hello"
add esp, 4
popa
mov esp, ebp
pop ebp
ret
在不保存堆栈指针并对其进行恢复的情况下,被调用的子例程会修改堆栈指针,其中call
指令在其中保存了返回地址.因此,当遇到ret
时,执行将跳转到错误的返回地址,从而导致段错误.在汇编中的调用约定和函数上了解更多信息.
Without saving the stack pointer and restoring it, the called subroutine modifies the stackpointer, where the call
instruction saved the return address. Consequently, when ret
is encountered, execution jumps to the wrong return address, therefore segfaulting. Read more on calling conventions and functions in assembly.
这篇关于x86组装,出现分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!