gpt4 book ai didi

macos - 如何在 NASM 中打印 argv[0]?

转载 作者:行者123 更新时间:2023-12-03 04:58:50 24 4
gpt4 key购买 nike

我想将 argv[0] 存储在寄存器中,然后打印它,但是当我运行汇编程序时出现段错误。

追踪:

$ nasm -f macho -o scriptname.o --prefix _ scriptname.asm
$ ld -o scriptname scriptname.o -arch i386 -lc -macosx_version_min 10.6 -e _start -no_pie
$ ./scriptname
Segmentation fault: 11

脚本名称.asm:

[bits 32]

section .data

program: db "Program: %s", 0

section .text

global start
extern printf
extern exit

start:

; skip argc
add esp, 4

; ebx := argv[0]
pop ebx

push ebx
push program
call printf
add esp, 8

push 0
call exit

规范:

  • ld 64-134.9
  • nasm 0.98.40
  • Xcode 4.5
  • Mac OS X 10.8.2
  • MacBook Pro 2009

最佳答案

段错误来自错误的堆栈对齐 (misaligned_stack_error)。
当您遇到此类问题时,请始终尝试使用 GDB 运行您的程序。它通常会为您提供更多信息。

但是要恢复,当您从 C 库调用函数时,堆栈需要在 16 字节边界上对齐。
这是 Mac OS X 32 位 ABI 的要求(请注意,64 位 ABI 也是如此,它使用 SYS V 调用约定)。

这是程序的工作版本,它将打印可执行文件名称以及 CLI 参数的数量(解释就在后面):

[bits 32]

section .data

hello db "Program name: %s (%i CLI args)", 10, 0

section .text

global start
extern _exit
extern _printf

start:

; Store 'argc' into EAX
pop eax

; Store 'argv' into EBX
pop ebx

; Align stack on a 16 bytes boundary,
; as we'll use C library functions
mov ebp, esp
and esp, 0xFFFFFFF0

; Stack space for local variables
; A little more space than needed, but that will
; ensure the stack is still aligned
sub esp, 16

; Call 'printf': printf( hello, ebx, eax );
mov dword[ esp ], hello
mov dword[ esp + 4 ], ebx
mov dword[ esp + 8 ], eax
call _printf

; Call 'exit': exit( 0 );
mov dword[ esp ], 0
call _exit

编译它使用:

nasm -f macho -o test.o test.asm
ld -o test test.o -arch i386 -lc -macosx_version_min 10.6

说明:

我们首先将argcargv存储在一些寄存器中:

    pop     eax
pop ebx

然后我们将堆栈对齐 16 字节边界:

    mov     ebp,                esp
and esp, 0xFFFFFFF0

您只能在 start 开始时执行此操作一次,假设您在为局部变量创建空间时保持堆栈对齐

然后我们为局部变量创建必要的空间,确保堆栈保持对齐。
在这里,我们只需要 3 个堆栈参数的空间,但我们为 4 个堆栈参数创建了空间,以保持堆栈对齐。

    sub     esp,                16

然后您可以在该空间上移动值,为调用准备参数:

    mov     dword[ esp ],       hello
mov dword[ esp + 4 ], ebx
mov dword[ esp + 8 ], eax

然后只需调用C库函数就可以了。

请注意,您还可以在this answer (x86 Assembly on a Mac)中找到一些有用的信息。 .

关于macos - 如何在 NASM 中打印 argv[0]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12678230/

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