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

How to get this simple assembly to run?

这是我第一次尝试使用汇编编程。我使用的是 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

链接器错误的原因是您使用 NASM 创建了一个 64 位 macho 对象,但随后将 i386 定位为可执行文件。您可能想要的是一个 64 位可执行文件,可以通过像这样删除 -arch 来完成:

ld -o hello hello.o

至于 运行 您的程序出现的段错误,您似乎遵循了专为 Linux 设计的教程。 OS/X 不是基于 Linux,它源自 BSD,因此系统调用不同。我们可以告诉您正在使用 Linux 系统调用,因为 syscall 1 是 sys_writesys_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 位代码(在这种情况下您不是),系统调用会从每个系统调用中减去 0x20000000。所以在 32 位 OS/X 代码中 sys_exit 是 eax=0x1 而 sys_write 是 eax=0x4 .

OS/X 上的所有系统调用(及其参数)的参考可以在此 Apple information 中找到。对于 64 位汇编代码,只需将 0x20000000 添加到图表第一列中的每个数字即可。

您可能想要查找有关系统调用的 64 位 OS/X 教程。这是一个 simple one