连续的 sys_write 系统调用没有按预期工作,OS X 上的 NASM 错误? [英] Successive sys_write syscalls not working as expected, NASM bug on OS X?
问题描述
我正在尝试使用 NASM 学习 MacOS 程序集,但我无法让一个简单的程序运行.我正在尝试Hello, World"的变体,其中两个词由宏独立调用.我的源代码如下所示:
I'm trying to learn MacOS assembly using NASM and I can't get a trivial program to work. I'm trying a variation of the "Hello, World" where the two words are independently called by a macro. My source code looks like this:
%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,
$
我错过了什么?我该如何解决?
What am I missing? How do I fix it?
编辑:我正在编译 &使用以下命令运行:
EDIT: I am compiling & running with the following commands:
/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 2.11.08 and 2.13.02+ have bugs with macho64
output. What you are observing seems to be something I saw specifically with 2.13.02+ recently when using absolute references. The final linked program has incorrect fixups applied so the reference to str2
is incorrect. The incorrect fixup causes us to print out memory that isn't str2
.
NASM 有一个关于他们系统中这个问题的错误报告.我根据问题中的代码添加了此失败的具体示例.希望 NASM 开发人员能够重现失败并创建修复程序.
NASM has a bug report about this issue in their system. I have added a specific example of this failure based on the code in the question. Hopefully the NASM developers will be able to reproduce the failure and create a fix.
更新:截至 2018 年 6 月,我认为 NASM 中有足够多的重复性错误和回归,因此我不建议在这个时间点使用 NASM 进行 Macho-64 开发.
Update: As of June 2018 my view is that there are enough recurring bugs and regressions in NASM that I do not recommend NASM at this point in time for Macho-64 development.
我对 Macho-64 开发的另一个建议是使用 RIP 相对寻址而不是绝对寻址.RIP 相对寻址是更高版本 MacOS 上 64 位程序的默认设置.
Another recommendation I have for Macho-64 development is to use RIP relative addressing rather than absolute. RIP relative addressing is the default for 64-bit programs on later versions of MacOS.
在 NASM 中,您可以使用文件中的 default rel
指令将默认地址从绝对地址更改为 RIP 相对地址.为此,在尝试将变量的地址移动到寄存器时,您必须从使用 mov register, variable
更改为 lea register, [variable]
.您修改后的代码可能如下所示:
In NASM you can use the default rel
directive in your file to change the default from absolute to RIP relative addresses. For this to work you will have to change from using mov register, variable
to lea register, [variable]
when trying to move the address of a variable to a register. Your revised code could look like:
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
这篇关于连续的 sys_write 系统调用没有按预期工作,OS X 上的 NASM 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!