连续的sys_write系统调用没有按预期工作,OS X上的NASM错误?

The*_*lph 4 macos 64-bit assembly x86-64 nasm

我正在尝试使用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    
Run Code Online (Sandbox Code Playgroud)

预期结果应该是:

$./hw
Hello,
World
$
Run Code Online (Sandbox Code Playgroud)

相反,我得到:

$./hw
Hello,
$
Run Code Online (Sandbox Code Playgroud)

我错过了什么?我如何解决它?

编辑:我正在使用以下命令编译和运行:

/usr/local/bin/nasm -f macho64 hw.asm
ld -macosx_version_min 10.7.0 -lSystem -o hw hw.o
./hw
Run Code Online (Sandbox Code Playgroud)

Mic*_*tch 7

NASM 2.11.08和2.13.02+有macho64输出错误.你在观察的东西似乎是我最近在使用绝对引用时专门用2.13.02+看到的东西.最终链接的程序应用了不正确的修正,因此引用str2不正确.错误的修复使我们打印出不是的内存str2.

NASM 在他们的系统中有关于此问题的错误报告.我已根据问题中的代码添加了此失败的具体示例.希望NASM开发人员能够重现故障并创建修复程序.

更新:截至2018年6月,我的观点是NASM中存在足够的反复出现的错误和回归,我现在不推荐NASM用于Macho-64开发.


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

在NASM中,您可以使用default rel文件中的指令将默认值从绝对更改为RIP相对地址.为此,您必须从使用更改mov register, variablelea 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
Run Code Online (Sandbox Code Playgroud)