use*_*993 5 macos assembly linker x86-64 nasm
这是我第一次尝试用汇编编程。我使用的是 64 位 Mac 操作系统。我也在使用 NASM。我已经做了很多寻找解决方案的工作,但我找不到任何适合我的机器的东西。
谁能帮我解决这个问题?这是代码和错误,谢谢!
你好.asm
global start
section .text
start:
mov rax, 1
mov rdi, 1
mov rsi, message
mov rdx, 13
syscall
mov eax, 60
xor rdi, rdi
syscall
message:
db "Hello, World", 10
Run Code Online (Sandbox Code Playgroud)
我尝试执行:
nasm -f macho64 hello.asm -o hello.o
ld -arch i386 -o hello hello.o
./hello
Run Code Online (Sandbox Code Playgroud)
错误
ld: warning: -macosx_version_min not specified, assuming 10.10
ld: warning: ignoring file hello.o, file was built for unsupported file format ( 0xCF 0xFA 0xED 0xFE 0x07 0x00 0x00 0x01 0x03 0x00 0x00 0x00 0x01 0x00 0x00 0x00 ) which is not the architecture being linked (i386): hello.o
Undefined symbols for architecture i386:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture i386
Run Code Online (Sandbox Code Playgroud)
您的链接器错误的原因是您使用NASM创建了一个 64 位 macho 对象,但随后将 i386 定位为可执行文件。您可能想要的是 64 位可执行文件,可以通过如下方式删除-arch:
ld -o hello hello.o
Run Code Online (Sandbox Code Playgroud)
至于运行程序时的段错误,您似乎遵循了可能是为 Linux 设计的教程。OS/X 不是基于 Linux,它是从 BSD 派生的,所以系统调用是不同的。我们可以告诉您正在使用 Linux系统调用,因为syscall 1 是sys_write并且sys_exit是 rax = 60。不幸的是,这与 OS/X 不同。在 64 位 OS/X 代码中sys_exit是 rax=0x20000001 并且sys_write是 rax=0x20000004 。
您的代码必须更改为:
global start
section .data
message: db "Hello, World", 10
section .text
start:
mov rax, 0x20000004
mov rdi, 1
mov rsi, message
mov rdx, 13
syscall
mov rax, 0x20000001
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud)
您还将观察到我明确声明了一个.data部分并将您的变量放入其中。在某些环境中,如果将数据变量放在代码中可能会导致问题。
如果在 OS/X 上创建 32 位代码(你不是在这种情况下)系统调用将从每个中减去 0x20000000。所以在 32 位 OS/X 代码中sys_exit是 eax=0x1 并且sys_write是 eax=0x4 。
可以在此Apple 信息中找到 OS/X 上所有系统调用(及其参数)的参考。对于 64 位汇编代码,只需将 0x20000000 添加到图表第一列中的每个数字。
您可能想找到有关 Syscalls 的 64 位 OS/X 教程。这是一个简单的