x86_64环境nasm+ld编译最简汇编程序运行段错误问题排查
x86_64汇编极简退出程序触发段错误问题排查
问题复现
编写仅实现进程退出功能的极简汇编程序:
SECTION .TEXT GLOBAL _start _start: mov rax, 60 mov rdi, 0 syscall
执行以下命令编译链接生成64位ELF可执行文件:
nasm -f elf64 -o test.o test.asm ld -o test test.o
运行生成的可执行文件直接触发段错误:
./test Segmentation fault (core dumped)
初步排查
- 网上同逻辑汇编示例可正常运行,初步判断问题出在编译/链接参数环节
- 使用
readelf -a test查看ELF结构,未发现直观异常,输出如下:
ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x401000 Start of program headers: 64 (bytes into file) Start of section headers: 4352 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 1 Size of section headers: 64 (bytes) Number of section headers: 5 Section header string table index: 4 Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .TEXT PROGBITS 0000000000401000 00001000 000000000000000c 0000000000000000 A 0 0 1 [ 2] .symtab SYMTAB 0000000000000000 00001010 00000000000000a8 0000000000000018 3 3 8 [ 3] .strtab STRTAB 0000000000000000 000010b8 0000000000000022 0000000000000000 0 0 1 [ 4] .shstrtab STRTAB 0000000000000000 000010da 0000000000000021 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), D (mbind), l (large), p (processor specific) There are no section groups in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x000000000000100c 0x000000000000100c R 0x1000 Section to Segment mapping: Segment Sections... 00 .TEXT There is no dynamic section in this file. There are no relocations in this file. No processor specific unwind information to decode Symbol table '.symtab' contains 7 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.asm 2: 000000000040100c 0 NOTYPE LOCAL DEFAULT 1 _end 3: 0000000000401000 0 NOTYPE GLOBAL DEFAULT 1 _start 4: 000000000040200c 0 NOTYPE GLOBAL DEFAULT 1 __bss_start 5: 000000000040200c 0 NOTYPE GLOBAL DEFAULT 1 _edata 6: 0000000000402010 0 NOTYPE GLOBAL DEFAULT 1 _end No version information found in this file.
- 使用
objdump -D test.o反汇编目标文件,指令逻辑无异常,输出如下:
test.o: file format elf64-x86-64 Disassembly of section .TEXT: 0000000000000000 <_start>: 0: b8 3c 00 00 00 mov $0x3c,%eax 5: bf 00 00 00 00 mov $0x0,%edi a: 0f 05 syscall
根因分析
段错误由段名大小写不匹配导致:
汇编代码中定义的代码段名为大写.TEXT,但ld默认链接脚本仅识别小写.text为标准代码段,最终生成的可执行文件中,存放代码的LOAD段仅被标记为*可读(R)权限,未标记可执行(X)*权限。CPU跳转到入口地址尝试执行指令时,会因内存页无执行权限触发保护故障,直接抛出段错误。
解决方案
将汇编代码中的段名从大写.TEXT修改为小写.text即可,修正后代码如下:
SECTION .text GLOBAL _start _start: mov rax, 60 mov rdi, 0 syscall
重新执行编译链接命令后,生成的可执行文件可正常运行,无段错误。
内容的提问来源于stack exchange,提问作者ElvisResurrected
相关产品推荐
相关产品推荐

