【发布时间】:2016-06-28 02:30:53
【问题描述】:
更新:果然,这是最新版本的 nasm 中的一个错误。我“降级”并按照我接受的答案所示修复了我的代码后,一切正常。谢谢大家!
我在使用 OS X 上的 32 位汇编器中应该是一个非常简单的程序时遇到问题。
一、代码:
section .data
hello db "Hello, world", 0x0a, 0x00
section .text
default rel
global _main
extern _printf, _exit
_main:
sub esp, 12 ; 16-byte align stack
push hello
call _printf
push 0
call _exit
它会组装和链接,但是当我运行可执行文件时,它会因分段错误而崩溃:11。
汇编和链接的命令行是:
nasm -f macho32 hello32x.asm -o hello32x.o
我知道 -o 不是 100% 必要的
链接:
ld -lc -arch i386 hello32x.o -o hello32x
当我将它运行到 lldb 中进行调试时,一切都很好,直到它进入对 _printf 的调用,它崩溃了,如下所示:
(lldb) s
Process 1029 stopped
* thread #1: tid = 0x97a4, 0x00001fac hello32x`main + 8, queue = 'com.apple.main-thread', stop reason = instruction step into
frame #0: 0x00001fac hello32x`main + 8
hello32x`main:
-> 0x1fac <+8>: calll 0xffffffff991e381e
0x1fb1 <+13>: pushl $0x0
0x1fb3 <+15>: calll 0xffffffff991fec84
0x1fb8: addl %eax, (%eax)
(lldb) s
Process 1029 stopped
* thread #1: tid = 0x97a4, 0x991e381e libsystem_c.dylib`vfprintf + 49, queue = 'com.apple.main-thread', stop reason = instruction step into
frame #0: 0x991e381e libsystem_c.dylib`vfprintf + 49
libsystem_c.dylib`vfprintf:
-> 0x991e381e <+49>: xchgb %ah, -0x76f58008
0x991e3824 <+55>: popl %esp
0x991e3825 <+56>: andb $0x14, %al
0x991e3827 <+58>: movl 0xc(%ebp), %ecx
(lldb) s
Process 1029 stopped
* thread #1: tid = 0x97a4, 0x991e381e libsystem_c.dylib`vfprintf + 49, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x890a7ff8)
frame #0: 0x991e381e libsystem_c.dylib`vfprintf + 49
libsystem_c.dylib`vfprintf:
-> 0x991e381e <+49>: xchgb %ah, -0x76f58008
0x991e3824 <+55>: popl %esp
0x991e3825 <+56>: andb $0x14, %al
0x991e3827 <+58>: movl 0xc(%ebp), %ecx
正如您在底部看到的那样,由于访问错误而停止。
【问题讨论】:
-
我很确定您在链接期间至少也会收到警告。无论如何,这看起来像是不让 C 库初始化的常见情况。使用
gcc链接。 -
嗨@Jester。是的,我收到一个错误:ld:警告:PIE 已禁用。在代码签名的 PIE 中不允许使用绝对寻址(可能是 -mdynamic-no-pic),但在 hello32x.o 的 _main 中使用。要解决此警告,请不要使用 -mdynamic-no-pic 进行编译或使用 -Wl,-no_pie 进行链接,但如果我使用 gcc 进行链接,则会出现相同的错误。
-
我在我的代码中推断出一个错误 - 我应该只完成 sub esp, 8,因为将字符串的地址推入堆栈会将其带到 12,然后将返回地址推入该调用将其变为 16,使 OS X 需要 16 字节的堆栈对齐。
标签: macos assembly x86 32-bit libc