Последовательные sys_write syscalls не работают должным образом, ошибка 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, $ 

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

EDIT : Я компилирую и запускаю следующие команды:

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

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 по 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 
Interesting Posts

Зачем создавать много разделов?

Невозможно включить заголовки C ++, такие как вектор в Android NDK

Принудительное gnu make для восстановления объектов, затронутых определением компилятора

Если профайлер не является ответом, какие у нас есть другие варианты?

Проблема с Youtube iframe wmode

Почему маски подсети имеют значение для отдельного компьютера в сети?

Как сортировать очень большие файлы

Работа над удаленным проектом с Eclipse через SSH

Как добавить знак процента в NSString

Как создать закрытый (круглый) ListView?

Невозможно корректно обрабатывать ошибку в ajax из rxjs

Получение нечетной / четной части последовательности с LINQ

java.lang.IllegalStateException: только непрозрачные действия в полноэкранном режиме могут запрашивать ориентацию

Не удалось загрузить файл или сборку HRESULT: 0x80131515 (При добавлении controllerа в проект MVC с ссылками на сборку на сетевом диске)

Выключение журнала событий Windows?

Давайте будем гением компьютера.