Как скомпилировать с помощью nasm на MacOSX

Я пытаюсь скомпилировать и связать свою первую программу с ассемблером. Я пытаюсь скомпилировать следующий код:

; %include "stud_io.inc"    
global _main     

section .text
_main: 
    xor eax, eax
again:
    ; PRINT "Hello"
    ; PUTCHAR 10
    inc eax     
    cmp eax, 5
    jl again

Ниже консольной команды для компиляции и компоновки программы:

-bash-3.2$ nasm -f macho main.asm -o main.o  && ld -e _main -macosx_version_min 10.8 -arch x86_64 main.o

Но результат:

ld: warning: ignoring file main.o, file was built for i386 which is not the architecture being linked (x86_64): main.o
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     -u command line option
ld: symbol(s) not found for architecture x86_64

Я думаю, что его необходимо скомпилировать файл main.asm для x86_64.. Как правильно скомпилировать программы для моей системы?

Ответ 1

Я бы порекомендовал сначала обновить NASM.

После этого попробуйте выполнить следующее:

nasm -f macho64 main.asm -o main.o  && ld -e _main -macosx_version_min 10.8 -arch x86_64 main.o -lSystem

Обратите внимание, что новая команда добавляет предложение JasonD выше (macho64), но также добавляет команду -lSystem в команду ld, чтобы остановить ld от бросания следующей ошибки:

ld: dynamic main executables must link with libSystem.dylib for architecture x86_64

Ответ 2

Я заметил, что большинство примеров демонстрируют автономные программы сборки, но, возможно, это более распространено для сборки, которые вызывают из C. Я создал простую программу на C, которая использует минимальную подобную функцию, такую ​​как:

extern unsigned cpuid(unsigned n);

/* ... */
        unsigned n = cpuid(1);

Сборка выглядит следующим образом:

section .text
    global _cpuid

_cpuid:
    push rbp
    mov rbp, rsp
    mov rax, rdi
    cpuid
    mov rax, rcx
    leave
    ret

Вы можете увидеть все это, включая опции nasm CLI в make файле, здесь:

https://github.com/ecashin/low/tree/master/cpuid

Он делает что-то мягко полезное, распечатывая доступность некоторых специфичных для процессора функций. (Но он делает это, используя CPUID, не проверяя, доступен ли он. Если процессор Intel и новее, чем i486, тем не менее, это нормально.)

Пример тестируется на Mac OS X Snow Leopard с nasm из коллекции портов. Удаление префикса подчеркивания - единственное изменение, необходимое для переноса на Linux x86_64.