NASM 的尴尬数据部分行为
Awkward data section behavior with NASM
我正在用汇编编写一些基本程序,其中我只是进行一些函数调用。我在 OS X 上,使用 Mach-O 64 位格式。但是,我对数据部分的理解似乎存在缺陷。我了解到data段是用来存放初始化数据的,所以决定初始化两块内存,如下图:
default rel
global _main
extern _puts
section .data
first db "Message A", 0 ; null terminator
second db "Message B", 0
section .text
_main:
push rbp ; alignment
mov rbp, rsp
sub rsp, 0x10
lea rdi, [second]
call _puts
lea rdi, [first]
call _puts
add rsp, 0x10
pop rbp
ret
(显然我链接的是 libc)
我的理解是,根据 System V ABI 规范,堆栈必须是 16 字节对齐的。此外,rdi 应该包含函数调用的第一个参数。
上面的代码会打印"Message B",但是后面直接打印"Message A"就失败了。好像 "Message A" 在某处被覆盖了。
同样有趣的是,当我在 .text
部分输入两个字符串时,代码按预期工作。由于 .text
是只读的,我几乎可以肯定 "Message A" 在初始化后的某个时间被覆盖。无论我在 .data
部分输入多少个字符串,我只能打印最后一个,其他的都被覆盖。为什么最后一个初始化的字符串是唯一没有被覆盖的?
目前,似乎没有太多解决办法。这是 2.11.08 中的一个错误,我想有些人也报告了 2.11.06 的问题,所以去 2.11.05 可能是你最好的选择,或者等待 2.11.09。
我正在用汇编编写一些基本程序,其中我只是进行一些函数调用。我在 OS X 上,使用 Mach-O 64 位格式。但是,我对数据部分的理解似乎存在缺陷。我了解到data段是用来存放初始化数据的,所以决定初始化两块内存,如下图:
default rel
global _main
extern _puts
section .data
first db "Message A", 0 ; null terminator
second db "Message B", 0
section .text
_main:
push rbp ; alignment
mov rbp, rsp
sub rsp, 0x10
lea rdi, [second]
call _puts
lea rdi, [first]
call _puts
add rsp, 0x10
pop rbp
ret
(显然我链接的是 libc)
我的理解是,根据 System V ABI 规范,堆栈必须是 16 字节对齐的。此外,rdi 应该包含函数调用的第一个参数。
上面的代码会打印"Message B",但是后面直接打印"Message A"就失败了。好像 "Message A" 在某处被覆盖了。
同样有趣的是,当我在 .text
部分输入两个字符串时,代码按预期工作。由于 .text
是只读的,我几乎可以肯定 "Message A" 在初始化后的某个时间被覆盖。无论我在 .data
部分输入多少个字符串,我只能打印最后一个,其他的都被覆盖。为什么最后一个初始化的字符串是唯一没有被覆盖的?
目前,似乎没有太多解决办法。这是 2.11.08 中的一个错误,我想有些人也报告了 2.11.06 的问题,所以去 2.11.05 可能是你最好的选择,或者等待 2.11.09。