【发布时间】:2018-06-06 07:23:48
【问题描述】:
我是汇编编程的新手,并且正在使用简单的示例和 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
所以系统调用应该尝试从0x10000 开始读取412331802635 字节,我认为这应该导致分段错误,因为不允许程序访问所有字节。
但它默默地什么也没打印。为什么?为什么没有提出Segmantation Fault?那是某种未定义的行为吗?我在intel core i5 下使用Ubuntu 16.04 LTS。
【问题讨论】:
-
read不会导致段错误,它会返回错误。 -
在
strace下运行你的程序来解码系统调用的参数和返回值。另见stackoverflow.com/tags/x86/info底部了解更多asm调试技巧。
标签: linux assembly segmentation-fault x86-64