如何让这个简单的程序集运行?

时间:2015-12-09 23:23:01

标签: macos assembly nasm x86-64

这是我第一次尝试使用汇编进行编程。我使用的是64位Mac OS。我也在使用NASM。我已经做了很多寻找解决方案,但我找不到适用于我的机器的任何东西。

任何人都可以帮我解决这个问题吗?这是代码和错误,谢谢!

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

我尝试执行:

nasm -f macho64 hello.asm -o hello.o
ld -arch i386 -o hello hello.o
./hello

错误

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

1 个答案:

答案 0 :(得分:3)

链接器错误的原因是您使用 NASM 创建了一个64位的强壮对象,但随后将i386作为可执行文件的目标。您可能追求的是64位可执行文件,可以通过删除-arch这样完成:

ld -o hello hello.o

至于运行程序时的段错误,似乎您可能会遵循可能是为Linux设计的教程。 OS / X不是基于Linux,它是从BSD派生的,所以Syscalls是不同的。我们可以告诉你正在使用Linux Syscalls,因为 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

您还会观察到我明确声明了.data部分并将您的变量放入其中。在某些环境中,如果将数据变量放在代码中,则可能会出现问题。

如果在OS / X上创建32位代码(在这种情况下你不是这样),则Syscalls从每个代码中减去0x20000000。所以在32位OS / X代码中, sys_exit 是eax = 0x1而 sys_write 是eax = 0x4。

可在此Apple information中找到OS / X上所有Syscalls(及其参数)的参考。只需为图表的第一列中的每个数字添加0x20000000即可获得64位汇编代码。

您可能希望找到有关Syscalls的64位OS / X教程。这是simple one