Macos 连续的系统写入系统调用未按预期工作,OSX上的NASM错误?

Macos 连续的系统写入系统调用未按预期工作,OSX上的NASM错误?,macos,assembly,64-bit,nasm,x86-64,Macos,Assembly,64 Bit,Nasm,X86 64,我正在尝试使用NASM学习MacOS汇编,但我无法让一个简单的程序工作。我正在尝试“Hello,World”的一种变体,其中两个单词由宏独立调用。我的源代码如下所示: %macro printString 2 mov rax, 0x2000004 ; write mov rdi, 1 ; stdout mov rsi, %1 mov rdx, %2 syscall %endmacro global start

我正在尝试使用NASM学习MacOS汇编,但我无法让一个简单的程序工作。我正在尝试“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

NASM 2.11.08和2.13.02+在输出方面存在缺陷。您所观察到的似乎是我最近在使用绝对引用时在2.13.02+中特别看到的。最终链接的程序应用了不正确的修正,因此对str2的引用不正确。不正确的修正导致我们打印出不是str2的内存

NASM在他们的系统中对这一问题有自己的看法。根据问题中的代码,我添加了一个具体的失败示例。希望NASM开发人员能够重现故障并创建修复程序

更新:截至2018年6月,我的观点是NASM中有足够多的反复出现的错误和倒退,因此我不建议在此时将NASM用于Macho-64开发


我对Macho-64开发的另一个建议是使用RIP相对寻址而不是绝对寻址。RIP相对寻址是更高版本MacOS上64位程序的默认设置

在NASM中,您可以使用文件中的
default rel
指令将默认地址从绝对地址更改为相对地址。要使其起作用,您必须在尝试将变量地址移动到寄存器时,从使用
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

RIP相对寻址工作完美!谢谢@我可以问一下你使用的是什么版本的nasm吗。您可以使用
-v
选项来显示它。我很好奇人们使用的NASM的哪些版本不起作用。我使用的版本是NASM版本2.13.03,编译于2018年2月8日NASM 2.11.08错误。所以在所有NASM版本上都没有安全的便携方式!可能值得一提,以避免混淆。(当然,最好使用无bug的NASM版本。)