nasm - Undefined symbols for architecture x86_64:

I am running Catalina - 10.15.6. & all the needed development tools including Xcode. I am getting this error with a simple Mac assembly 'hello world' program hello.asm

I will appreciate any help


$ nasm -fmacho64 hello.asm && ld hello.o && ./a.out

Undefined symbols for architecture x8664:

  "
main", referenced from:

     implicit entry/start for main executable

ld: symbol(s) not found for architecture x86_64


;
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit macOS only.
; To assemble and run:
;
; nasm -fmacho64 hello.asm && ld hello.o && ./a.out
; ----------------------------------------------------------------------------------------
Code Block
global start

section .text
start: mov rax, 0x02000004 ; system call for write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, message ; address of string to output
mov rdx, 13 ; number of bytes
syscall ; invoke operating system to do the write
mov rax, 0x02000001 ; system call for exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exit
Code Block
section .data
message: db "Hello, World", 10 ; note the newline at the end


How were you planning to describe the program's entry point to the linker? If this is taken from a code sample for another operating system, is it relying on some implicit GCC behavior?
Mach-O uses a load command (LC_UNIXTHREAD before 10.8 Mountain Lion, LC_MAIN afterwards) which indicates the entry point of the executable. When using ld, the symbol can be specified with -e (the man page contains more details about default behavior).

Writes "Hello, World" to the console using only system calls.

I know that you’re only doing this for testing purposes but I want to stress that Apple platforms do not support binary compatibility at the system call layer. The only supported way to call the kernel is via the dynamically linked functions exported by the System framework.



As to your main issue, I suspect that your issue is with ld. Consider this snippet from its man page:

Code Block
-e symbol_name
Specifies the entry point of a main executable. By default the
entry name is `start` which is found in `crt1.o` which contains
the glue code need to set up and call `main`.


I suspect that ld is implicitly linking crt1.o (crt stands for C runtime) which provides start and expects you to provide main.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
nasm - Undefined symbols for architecture x86_64:
 
 
Q