You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac OSX下无法编译NASM Hello World程序问题求助

Hey Liam, let's get that NASM Hello World up and running on macOS! Making the jump from MASM/Irvine to NASM on a Unix-like system can throw you for a loop with different calling conventions, executable formats, and syscall rules—so let's break this down step by step.

First, Let's Fix Your Hello World Code

The most common issues here are incorrect entry points, wrong syscall numbers, or missing stack setup. Here's a working 64-bit Mach-O version that uses direct syscalls (no libc dependency):

; hello.asm
section .data
    msg db  "Hello, World!", 0x0A  ; 0x0A adds a newline at the end
    len equ $ - msg                 ; Calculate length of our string automatically

section .text
    global _main                    ; macOS requires the entry point to be _main (not _start like Linux)

_main:
    ; Syscall: write(1, msg, len)
    mov     rax, 0x2000004          ; macOS syscall number for write (0x4 + 0x2000000 prefix)
    mov     rdi, 1                  ; File descriptor 1 = stdout
    mov     rsi, msg                ; Pointer to our message string
    mov     rdx, len                ; Length of the string
    syscall                         ; Invoke the syscall

    ; Syscall: exit(0)
    mov     rax, 0x2000001          ; macOS syscall number for exit
    mov     rdi, 0                  ; Exit code 0 (success)
    syscall

Your initial compile command is actually right—you just missed the linking step to turn the object file into a runnable executable:

  1. Compile the assembly to a Mach-O object file:
    nasm -f macho64 -o hello.o hello.asm
    
  2. Link the object file into an executable (we need to specify the macOS version and link against the system library):
    ld -macosx_version_min 10.14 -o hello hello.o -lSystem
    
  3. Run it:
    ./hello
    

If You Prefer Using Libc (Like printf)

If you want to use standard library functions instead of raw syscalls, here's a version that uses printf—and we can use gcc to handle linking more easily:

; hello-printf.asm
section .data
    msg db  "Hello, World!", 0x0A, 0  ; Null-terminated string (required for printf)

section .text
    extern _printf                  ; Declare we're using printf from libc
    global _main

_main:
    push    rbp                     ; Set up a stack frame (required for calling libc functions)
    mov     rbp, rsp

    lea     rdi, [rel msg]          ; First argument to printf: pointer to our string
    call    _printf                 ; Call the printf function

    mov     eax, 0                  ; Return 0 from main (success)
    leave
    ret

Compile and link with gcc (it handles all the system library and version stuff automatically):

nasm -f macho64 -o hello-printf.o hello-printf.asm
gcc -o hello-printf hello-printf.o
./hello-printf

Common Pitfalls You Might Have Hit

  • Wrong entry point: Unlike Linux (which uses _start), macOS Mach-O executables require _main as the entry point.
  • Incorrect syscall numbers: macOS adds a 0x2000000 prefix to all syscall numbers (e.g., write is 0x2000004 instead of just 0x4 like Linux).
  • Skipping the link step: Compiling with nasm only creates an object file—you need ld or gcc to turn it into a runnable program.
  • Malformed strings: For printf, your string must be null-terminated (add a 0 at the end), or you'll get garbage output.

内容的提问来源于stack exchange,提问作者Liam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:21:05