我不熟悉汇编编程和使用简单示例和gdb进行实验。这是我写的程序:
1.asm
section .text
global _start
extern _print_func
_start:
push str
movzx rdx, byte [str_len]
push dx ; <--- typo here, should be rdx
call _print_func
mov rax, 60
syscall
section .data
str: db 'Some data',0x0A,0x0D
str_len: db $ - str
2.asm
section .text
global _print_func
_print_func:
pop rbx
pop rdx
pop rsi
mov rax, 0x01
mov rdi, 0x01
syscall
push rbx
ret
section .data
str: db 'Some string',0x0A,0x0D
str_len: db $ - str
编译完成后,链接(使用ld
)并运行程序,它只是打印出来。所以我在syscall
之前检查了寄存器的内容。
(gdb) info registers
rax 0x1 1
rbx 0x4000c5 4194501
rcx 0x0 0
rdx 0x6000e4000b 412331802635 ; <-- obviously wrong
rsi 0x10000 65536
rdi 0x1 1
rbp 0x0 0x0
rsp 0x7fffffffdcc6 0x7fffffffdcc6
因此系统调用应该尝试从412331802635
开始读取0x10000
字节,我认为这应该导致分段错误,因为不允许程序访问所有字节。
但它默默无声地打印出来。为什么?为什么没有提出Segmantation Fault?这是某种未定义的行为吗?我在Ubuntu 16.04 LTS
下使用intel core i5
。