我正在使用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
我做错了什么?
答案 0 :(得分:4)
有效地址格式仅允许32位位移,符号扩展为64位。根据错误消息,您需要完整的64位。您可以通过寄存器添加它,例如:
mov rax, last_tok wrt ..gotoff
mov [rbx + rax], rdi
此外,call .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]
,而不必弄乱它。