代码之家  ›  专栏  ›  技术社区  ›  Nathan Osman

试图将地址复制到结构时出现分段错误?

  •  2
  • Nathan Osman  · 技术社区  · 7 年前

    我有一个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
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Nathan Osman    7 年前

    Peter Cordes

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

    事实证明,我需要做的是改变:

    act resb mystruct
    

    ...到

    act resb mystruct_size
    

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

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