Writing a compiler in school, last milestone is generating assembly code. Trying to learn NASM. Starting at the beginning, http://www.cs.lmu.edu/~ray/notes/nasmexamples/, trying to compile a Hello World.
; ----------------------------------------------------------------------------
; helloworld.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits. It needs to be linked with a C library.
; ----------------------------------------------------------------------------
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
To assemble, link and run this program under Windows:
nasm -fwin32 helloworld.asm
gcc helloworld.obj
a
Under Linux, you'll need to remove the leading underscores from function names, and execute
nasm -felf helloworld.asm
gcc helloworld.o
./a.out
But I'm on OSX. Found this little resource: http://salahuddin66.blogspot.com/2009/08/nasm-in-mac-os-x.html. In Mac OS X we should use format macho...
nasm -f macho -o hello.o hello.asm
...and for the linker (we need to specify the entry point)...
ld -e main -o hello hello.o
But when I do this...
Undefined symbols:
"printf", referenced from:
_main in hello.o
ld: symbol(s) not found for inferred architecture i386
Sorry, I know it's a lot to read. And I doubt there are many NASM coders around these parts, but worth a try right? I'd appreciate any help I can get.
Install nasm on macOS with MacPorts.
The program in your example is a 32-bit Windows program. These days, it's probably better to write a 64-bit program.
To covert this to 64-bit macOS program, you should make sure you have a recent version of nasm, and have gcc installed.
The program should now look like this:
; ----------------------------------------------------------------------------------------
; This is an macOS console program that writes "Hola, mundo" on one line and then exits.
; It uses puts from the C library. To assemble and run:
;
; nasm -fmacho64 hola.asm && gcc hola.o && ./a.out
; ----------------------------------------------------------------------------------------
global _main
extern _puts
section .text
_main: push rbx ; Call stack must be aligned
lea rdi, [rel message] ; First argument is address of message
call _puts ; puts(message)
pop rbx ; Fix up stack before returning
ret
section .data
message: db "Hola, mundo", 0 ; C strings need a zero byte at the end
You'll note a few differences:
rbx
before calling puts
serves to get the stack realigned.rel
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With