gpt4 book ai didi

macos - x86/OSX 中弹出/推送的段错误

转载 作者:行者123 更新时间:2023-12-04 00:33:21 29 4
gpt4 key购买 nike

我很难理解为什么这个 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
call _printf
pop %rbx
pop %rbp
ret

.section __TEXT,__cstring,cstring_literals
L_.str0:
.asciz "%d \000"

我观察到,如果 pop %rbx 行移动到 call _printf 之前,则程序可以正常运行。但为什么它的原始形式会完全失败?

最佳答案

此问题由以下人员详细回答:How to print argv[0] in NASM?还有x86 Assembly on a Mac .在 MacOSX 上进行汇编编程时,它本质上是一个问题。

总结:

  • 此段错误是由于堆栈未对齐造成的。
  • 这只发生在使用 System V 调用约定的操作系统上(包括 MacOSX,但不包括 Linux),它坚持在进行函数调用之前堆栈指针必须是 16 的倍数(例如 printf).

一个简单的解决方案是在调用之前对齐堆栈指针(即,根据 Sys V 要求对齐 16 字节的倍数),并在调用之后恢复它:

.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"

关于macos - x86/OSX 中弹出/推送的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26883471/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com