Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling NASM on Mac OSX

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.

like image 703
savinger Avatar asked Dec 09 '11 21:12

savinger


People also ask

Can you use nasm on Mac?

Install nasm on macOS with MacPorts.


1 Answers

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:

  • In 64 bit land, the first parameter is in RDI, not on the stack
  • The stack must be aligned on a 16-byte boundary before calling. When main is entered, the operating system has placed the (8 byte) return address of main on the stack, so pushing rbx before calling puts serves to get the stack realigned.
  • Also, nasm on macOS needs rel.
like image 200
Ray Toal Avatar answered Sep 24 '22 07:09

Ray Toal