Последовательные системные вызовы sys_write не работают должным образом, ошибка NASM в OS X?

Я пытаюсь изучить сборку MacOS с помощью NASM и не могу заставить работать тривиальную программу. Я пробую вариант "Hello, World", где два слова независимо вызываются макросом. Мой исходный код выглядит так:

%macro printString 2
    mov     rax, 0x2000004 ; write
    mov     rdi, 1 ; stdout
    mov     rsi, %1
    mov     rdx, %2
    syscall
%endmacro     

global start    

section .text    

start:
    printString str1,str1.len    

    printString str2,str2.len    

    mov     rax, 0x2000001 ; exit
    mov     rdi, 0
    syscall    


section .data    

str1:   db      "Hello,",10,
.len:  equ       $ - str1    

str2:   db      "world",10
.len:  equ       $ - str2    

Ожидаемый результат должен быть:

$./hw
Hello,
World
$

Вместо этого я получаю:

$./hw
Hello,
$

Что мне не хватает? Как мне это исправить?

РЕДАКТИРОВАТЬ: я собираю и работаю со следующими командами:

/usr/local/bin/nasm -f macho64 hw.asm
ld -macosx_version_min 10.7.0 -lSystem -o hw hw.o
./hw

1 ответ

Решение

У NASM 2.11.08 и 2.13.02+ есть ошибки с macho64 выход. То, что вы наблюдаете, кажется, что-то, что я видел специально с 2.13.02+ недавно, когда использовал абсолютные ссылки. В последней связанной программе применены неверные исправления, поэтому ссылка на str2 это неверно. Неправильное исправление заставляет нас печатать память, которая не str2,

NASM имеет отчет об ошибке в своей системе. Я добавил конкретный пример этой ошибки на основе кода в вопросе. Надеемся, что разработчики NASM смогут воспроизвести ошибку и создать исправление.

Обновление: по состоянию на июнь 2018 года, я считаю, что в NASM достаточно много повторяющихся ошибок и регрессий, поэтому я не рекомендую NASM на данный момент для разработки Macho-64.


Еще одна рекомендация, которую я имею для разработки Macho-64, - использовать относительную адресацию RIP, а не абсолютную. Относительная RIP-адресация используется по умолчанию для 64-битных программ в более поздних версиях MacOS.

В NASM вы можете использовать default rel в вашем файле указание изменить адрес по умолчанию с абсолютного на относительный адрес RIP. Чтобы это работало, вам придется отказаться от использования mov register, variable в lea register, [variable] при попытке переместить адрес переменной в регистр. Ваш исправленный код может выглядеть так:

default rel

%macro printString 2
    mov     rax, 0x2000004 ; write
    mov     rdi, 1 ; stdout
    lea     rsi, [%1]
    mov     rdx, %2
    syscall
%endmacro

global start

section .text

start:
    printString str1,str1.len

    printString str2,str2.len

    mov     rax, 0x2000001 ; exit
    mov     rdi, 0
    syscall


section .data

str1:   db      "Hello,",10
.len:  equ       $ - str1

str2:   db      "world",10
.len:  equ       $ - str2
Другие вопросы по тегам