mca*_*dre 3 macos assembly nasm argv
我想存储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
Run Code Online (Sandbox Code Playgroud)
脚本名.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
Run Code Online (Sandbox Code Playgroud)
眼镜:
分段错误来自错误的堆栈对齐( 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
Run Code Online (Sandbox Code Playgroud)
使用以下命令编译它:
nasm -f macho -o test.o test.asm
ld -o test test.o -arch i386 -lc -macosx_version_min 10.6
Run Code Online (Sandbox Code Playgroud)
解释:
我们首先在一些寄存器中存储argc和argv:
pop eax
pop ebx
Run Code Online (Sandbox Code Playgroud)
然后我们在 16 字节边界上对齐堆栈:
mov ebp, esp
and esp, 0xFFFFFFF0
Run Code Online (Sandbox Code Playgroud)
您只能在 开始时执行此操作start,假设您在为局部变量创建空间时保持堆栈对齐。
然后我们为局部变量创建必要的空间,确保堆栈保持对齐。
在这里,我们只需要 3 个堆栈参数的空间,但我们为 4 个创建了空间,以保持堆栈对齐。
sub esp, 16
Run Code Online (Sandbox Code Playgroud)
然后,您可以移动该空间上的值,为调用准备参数:
mov dword[ esp ], hello
mov dword[ esp + 4 ], ebx
mov dword[ esp + 8 ], eax
Run Code Online (Sandbox Code Playgroud)
然后只需调用 C 库函数,就可以了。
请注意,您还可以在此答案(Mac 上的 x86 程序集)中找到一些有用的信息。
| 归档时间: |
|
| 查看次数: |
3625 次 |
| 最近记录: |