我正在与NASM建立共享库.在该库中的某些函数中,我需要在C中称为静态变量的东西.基本上,我认为它在.data节中有一些空间:

    SECTION .data
last_tok:       dq 0 ; Define a QWORD

当我尝试在函数中访问last\_tok时,就会出现问题.

我读了NASM Manual: 8.2 Writing Linux/ELF Shared Libraries,它解释了问题并给出了解决方案.

    SECTION .data
last_tok:              dq 0     ; Define a QWORD

    SECTION .text
    EXTERN _GLOBAL_OFFSET_TABLE_
    GLOBAL strtok:function
strtok:
    enter    0, 0
    push     rbx
    call     .get_GOT
.get_GOT:
    pop      rbx
    add      rbx, _GLOBAL_OFFSET_TABLE_ + $$- .get_GOT wrt ..gotpc

    mov      [rbx + last_tok wrt ..gotoff], rdi ; Store the contents of RDI at last_tok

    mov      rbx, [rbp - 8]
    leave
    ret

它可能与ELF32一起使用,但与ELF64一起出现以下错误:


nasm -f elf64  -o strtok.o strtok.s
strtok:15: error: ELF64 requires ..gotoff references to be qword
<builtin>: recipe for target 'strtok.o' failed
make: *** [strtok.o] Error 1

我究竟做错了什么?

解决方法:

有效地址格式仅允许32位位移,并将其符号扩展为64位.根据错误消息,您需要完整的64位.您可以通过寄存器添加它,例如:

mov      rax,  last_tok wrt ..gotoff
mov      [rbx + rax], rdi 

另外,调用.get\_GOT是32位解决方案,在64位模式下,您可以在其中使用rip相对寻址.虽然以上可能会编译,但是我不确定它是否会工作.幸运的是,简单的解决方案是使用提及的rip相对地址来访问变量,从而:

    SECTION .data
    GLOBAL last_tok
last_tok:              dq 0     ; Define a QWORD

    SECTION .text
    GLOBAL strtok:function
strtok:
    mov      [rel last_tok wrt ..gotpc], rdi ; Store the contents of RDI at last_tok
    ret

请注意,对于私有(静态)变量,您可以只使用[rel last\_tok]而不用完全搞定get方法.

标签: linux, assembly, x86-64, elf, nasm

相关文章推荐

添加新评论,含*的栏目为必填