Macos 带pop/push-in x86/OSX的SEGFULT
我很难理解为什么这段x86汇编代码可以在OSX上用gcc 4.2.1(llvm)很好地编译,但在运行可执行文件时会出现分段错误:Macos 带pop/push-in x86/OSX的SEGFULT,macos,assembly,Macos,Assembly,我很难理解为什么这段x86汇编代码可以在OSX上用gcc 4.2.1(llvm)很好地编译,但在运行可执行文件时会出现分段错误: .globl _main _main: push %rbp mov %rsp, %rbp mov $1, %rbx push %rbx lea L_.str0(%rip), %rdi mov %rbx, %rsi
.globl _main
_main:
push %rbp
mov %rsp, %rbp
mov $1, %rbx
push %rbx
lea L_.str0(%rip), %rdi
mov %rbx, %rsi
call _printf
pop %rbx
pop %rbp
ret
.section __TEXT,__cstring,cstring_literals
L_.str0:
.asciz "%d \000"
我观察到,如果
pop%rbx
行在call\u printf
之前移动,则程序工作正常。但为什么它会以最初的形式失败呢?这个问题的详细答案是:和。在MacOSX上编程程序集时,这基本上是一个难题
总结如下:
- 此seg故障是由于堆栈未对准造成的李>
- 这仅在使用System V调用约定(包括MacOSX,但不包括Linux)的操作系统上发生,该约定坚持在进行函数调用之前堆栈指针为16的倍数(例如to
)printf
.globl _main
_main:
push %rbp
mov %rsp, %rbp
mov $1, %rbx
lea L_.str0(%rip), %rdi
mov %rbx, %rsi
push %rbx
mov %rsp, %rax ; Save copy of the stack pointer (SP)
and $-16, %rsp ; Align the SP to the nearest multiple of 16.
sub $8, %rsp ; Pad the SP by 8 bytes so that when we ...
push %rax ; push the saved SP (=8 bytes on a 64-bit OS),
; we remain aligned to 16 bytes (8+8 = 16).
call _printf
pop %rax ; retrieve the saved SP
mov %rax, %rsp ; restore SP using saved value.
pop %rbx
pop %rbp
ret
.section __TEXT,__cstring,cstring_literals
L_.str0:
.asciz "%d \000"
你需要对齐堆栈…@macmake是正确的,我相信-我编译并运行了你的代码,崩溃日志甚至说这是堆栈未对齐(不是16字节对齐)。@PaulR-谢谢。有没有办法通过指令来实现这一点?或者我必须喷洒代码才能手动对齐?同一问题可能重复。。。在我刚刚提到的帖子上看到我的答案,了解如何做到这一点。