连续 sys_write 个系统调用未按预期工作,NASM OS X 上的错误?
Successive sys_write syscalls not working as expected, NASM bug on OS X?
我正在尝试使用 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+ 在 macho64
输出中存在错误。您所观察到的似乎是我最近在使用绝对引用时在 2.13.02+ 中特别看到的。最终链接的程序应用了不正确的修正,因此对 str2
的引用不正确。不正确的修复导致我们打印出不是 str2
.
的内存
NASM 在他们的系统中有关于此问题的 bug report。我根据问题中的代码添加了此失败的具体示例。希望 NASM 开发人员能够重现故障并创建修复程序。
更新:截至 2018 年 6 月,我的观点是 NASM 中有足够多的反复出现的错误和回归,我不建议 NASM Macho-64 开发的时间点。
我对 Macho-64 开发的另一个建议是使用 RIP 相对寻址而不是绝对寻址。 RIP 相对寻址是更高版本 MacOS 上 64 位程序的默认设置。
在 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
我正在尝试使用 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+ 在 macho64
输出中存在错误。您所观察到的似乎是我最近在使用绝对引用时在 2.13.02+ 中特别看到的。最终链接的程序应用了不正确的修正,因此对 str2
的引用不正确。不正确的修复导致我们打印出不是 str2
.
NASM 在他们的系统中有关于此问题的 bug report。我根据问题中的代码添加了此失败的具体示例。希望 NASM 开发人员能够重现故障并创建修复程序。
更新:截至 2018 年 6 月,我的观点是 NASM 中有足够多的反复出现的错误和回归,我不建议 NASM Macho-64 开发的时间点。
我对 Macho-64 开发的另一个建议是使用 RIP 相对寻址而不是绝对寻址。 RIP 相对寻址是更高版本 MacOS 上 64 位程序的默认设置。
在 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