问题描述
之前在 x86_64 Linux 上多次看到的基本 Hello World:
global my_start_symbol
section .my_section
my_start_symbol:
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msg_len
syscall
mov rax,60
xor rdi,rdi
syscall
section .rodata:
msg: db "Hello,world!",10
msg_len: equ $ - msg
我当前的 ld
链接脚本:
__linux_mmap_min_addr = 0x10000;
ENTRY(my_start_symbol)
MEMORY
{
rom (rx) : ORIGIN = 0,LENGTH = 512K
}
SECTIONS
{
. = __linux_mmap_min_addr;
.my_section :
{
*(.my_section*)
} > rom
.rodata :
{
*(.rodata*)
} > rom
}
调用方式:
nasm -f elf64 assembly.asm -o assembly.o
ld -T linker.ld assembly.o -o assembly
我目前遇到了段错误。检查 readelf -a
的输出,我可以看到 my_section
没有可执行权限。我相信这是导致段错误的原因。如果我用 .text : { *(.my_section*) } > rom
替换它,它仍然没有被设置为可执行文件。只有当我按照惯例在任何地方恢复使用 .text
时,它才会将其设置为可执行文件。
解决方法
我的评估(至少在带有 NASM 的 x86_64 Linux 上):
-
ld
MEMORY
定义中设置的标志与将部分设置为可执行文件无关。 NASM ELF Section extensions 很重要,即即使section .my_section exec
没有MEMORY
标志,x
也能工作(感谢 @peter-cordes)。 - 如果您有正在使用的特定
ld
MEMORY
定义,来源不能是0
,但必须至少是0x10000
(请参阅此 {{3} } 了解更多信息)在本节开头使用. = 0x10000;
是不够的。