【发布时间】:2017-09-28 20:07:23
【问题描述】:
我有一个 NASM 程序因分段错误而崩溃。
在文件的开头,定义了以下结构:
struc mystruct
.myhandler resq 1
endstruc
结构的实例在.bss 部分中创建:
section .bss
inst resb mystruct
程序所做的第一件事是尝试将标签的地址存储在结构的唯一字段中:
section .text
global _start
_start:
lea rax, [handler]
mov [inst + mystruct.myhandler], rax
handler:
; ...
根据GDB,lea和mov指令如下:
(gdb) disassemble _start
Dump of assembler code for function _start:
=> 0x0000000000400080 <+0>: lea rax,ds:0x400090
0x0000000000400088 <+8>: mov QWORD PTR ds:0x601000,rax
...
但是,运行应用程序会导致分段错误:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400088 in _start ()
这是为什么?
编辑:附加信息:
$ nm -S app.o
0000000000000010 t handler
0000000000000000 b inst
0000000000000000 a mystruct
0000000000000000 a mystruct.myhandler
0000000000000008 a mystruct_size
0000000000000000 T _start
$ size -A app.o
app.o :
section size addr
.text 16 0
.bss 0 0
Total 16
【问题讨论】:
-
你能告诉我
nm -S object.o的输出,其中object.o是包含inst的目标文件吗? -
另外,
size -A object.o也可能有用。 -
@fuz 我已经添加了信息。
-
顺便说一句,NASM 的默认设置是绝对寻址,而不是相对于 RIP。
DEFAULT REL将使用更紧凑的 RIP 相对寻址。 (您使用lea而不是mov eax, handler的唯一原因是位置无关代码。或mov [inst + mystruct.myhandler], handler) -
看起来
inst resb mystruct在 BSS 中保留了 0 个字节,因此您的进程根本没有 BSS(您可以检查/proc/PID/maps或smaps)。但它仍然以某种方式组装和链接。我不知道 NASM 中sizeof()的正确语法是什么;我从不使用它的结构语法。
标签: linux assembly nasm x86-64