You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

64位Intel汇编:用寄存器作偏移访问数组创建共享库失败求解

问题原因与解决方案

这是因为创建共享库需要生成位置无关代码(PIC),而你使用的[rel array + rax]寻址方式在x86-64的PIC规则下是不合法的,具体原因和解决方法如下:

核心原因

x86-64平台的共享库依赖位置无关代码来实现动态加载(可以被映射到内存的任意地址),这类代码主要通过RIP相对寻址来访问全局数据。但RIP相对寻址仅支持固定偏移量,不能直接和寄存器偏移组合成单一的内存寻址指令:

  • 当你写mov al, BYTE [rel array + 3]时,nasm可以计算出当前指令到array+3的固定偏移,生成合法的RIP相对寻址指令,链接器能正常处理这种固定偏移的重定位。
  • 而[rel array + rax]试图把RIP相对的基址和寄存器偏移结合,x86-64指令集本身没有这种寻址模式的直接支持,nasm编译时不会报错,但链接器无法为这种动态偏移生成合适的重定位条目,导致链接失败。

正确的代码实现

要实现寄存器偏移访问全局数组,你需要先通过lea指令把数组的RIP相对地址加载到一个通用寄存器,再用寄存器基址+寄存器偏移的方式访问:

BITS 64
SECTION .text
GLOBAL test
test:
    push rbp
    mov rbp, rsp
    mov rax, 3
    ; 先获取array的RIP相对地址到rbx寄存器
    lea rbx, [rel array]
    ; 用寄存器基址+寄存器偏移访问数组元素
    mov al, BYTE [rbx + rax]
    pop rbp
    ret
SECTION .data
array times 256 db 0

编译链接命令

确保编译时生成PIC代码,链接时生成共享库:

# 编译成64位ELF格式的PIC目标文件
nasm -f elf64 -fPIC your_file.asm -o your_file.o
# 链接成共享库
ld -shared your_file.o -o libtest.so

内容的提问来源于stack exchange,提问作者Michael Vouriz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:07:48