【问题标题】:Segmentation fault when attempting to copy an address into a struct?尝试将地址复制到结构时出现分段错误?
【发布时间】: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,leamov指令如下:

(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/mapssmaps)。但它仍然以某种方式组装和链接。我不知道 NASM 中 sizeof() 的正确语法是什么;我从不使用它的结构语法。

标签: linux assembly nasm x86-64


【解决方案1】:

Peter Cordes 在评论中指出:

看起来 inst resb mystruct 在 BSS 中保留了 0 个字节,因此您的进程根本没有 BSS。但它仍然以某种方式组装和链接。我不知道 NASM 中 sizeof() 的正确语法是什么;我从不使用它的结构语法。

原来我需要做的是改变:

act resb mystruct

...到...

act resb mystruct_size

此符号由汇编程序自动定义,并设置为结构的大小(以字节为单位)。

程序不再在该部分代码上崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 2021-12-17
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多