Компиляция NASM на Mac OSX - PullRequest
       42

Компиляция NASM на Mac OSX

3 голосов
/ 10 декабря 2011

Написание компилятора в школе, последний этап - генерация ассемблерного кода. Пытаюсь выучить NASM. Начиная с самого начала, http://www.cs.lmu.edu/~ray/notes/nasmexamples/, пытается скомпилировать 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

Чтобы собрать, связать и запустить эту программу под Windows:

nasm -fwin32 helloworld.asm
gcc helloworld.obj
a

В Linux вам нужно удалить начальные подчеркивания из имен функций и выполнить

nasm -felf helloworld.asm
gcc helloworld.o
./a.out

Но я на OSX. Нашел этот маленький ресурс: http://salahuddin66.blogspot.com/2009/08/nasm-in-mac-os-x.html. В Mac OS X мы должны использовать формат macho ...

nasm -f macho -o hello.o hello.asm

... и для компоновщика (нам нужно указать точку входа) ...

ld -e main -o hello hello.o

Но когда я это сделаю ...

Undefined symbols:
    "printf", referenced from:
        _main in hello.o
ld: symbol(s) not found for inferred architecture i386

Извините, я знаю, что много читать. И я сомневаюсь, что есть много кодеров NASM вокруг этих частей, но стоит попробовать, верно? Буду признателен за любую помощь.

Ответы [ 2 ]

3 голосов
/ 10 декабря 2011

Функция printf определена в некоторой библиотеке C (в Linux это будет, например, в /lib/libc.so.6 или /lib/x86_64-linux-gnu/libc.so.6), поэтому вам нужно связаться с этой библиотекой (я не знаю, что это за MacOSX)

Вы могли бы делать системные вызовы напрямую , т. Е. системные вызовы (я не знаю деталей для MacOSX и не знаю, доступны ли они публично). В Linux Linux Assembly Howto дает подробности. Вам необходимо найти эквивалентные данные для вашей операционной системы.

(Кстати, использование совершенно свободных программ определенно проще для таких задач, потому что их спецификация и исходный код доступны; при использовании проприетарного программного обеспечения, такого как, например, MacOSX, вам нужно получить его у поставщика программного обеспечения, иногда это очень и очень дорого )

2 голосов
/ 28 января 2018

Программа в вашем примере - это 32-битная программа для Windows. В наши дни, вероятно, лучше написать 64-битную программу.

Чтобы преобразовать это в 64-битную программу macOS, вы должны убедиться, что у вас установлена ​​последняя версия nasm и установлен gcc.

Программа должна выглядеть следующим образом:

; ----------------------------------------------------------------------------------------
; 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

Вы заметите несколько отличий:

  • В 64-битной земле первый параметр находится в RDI, а не в стеке
  • Стек должен быть выровнен по 16-байтовой границе перед вызовом. Когда вводится main, операционная система помещает (8-байтовый) адрес возврата main в стек, поэтому нажатие rbx перед вызовом puts служит для выравнивания стека.
  • Кроме того, nasm на macOS нуждается rel.
...