la
RISC-V la 伪指令详解
汇编器伪指令加载地址伪指令,把符号地址放入寄存器。官方汇编手册规定它会随 .option nopic/pic 改变展开:非 PIC 通常是 AUIPC+ADDI,PIC 通常通过 GOT 间接加载。
你写下的是
la rd, symbol
常见真实展开
# .option nopic
.Lla:
auipc rd, %pcrel_hi(symbol)
addi rd, rd, %pcrel_lo(.Lla)
# .option pic
.Lla_got:
auipc rd, %got_pcrel_hi(symbol)
l{w|d} rd, %pcrel_lo(.Lla_got)(rd)
这条伪指令到底在帮你省什么
同一源码写法可覆盖本地地址和全局/PIC 地址。汇编器根据当前选项选择 lla 或 lga 形式,程序员不必手动判断是否需要 GOT。
la 的核心作用是“按代码模型加载符号地址”。它是汇编器层面的简写;调试、审计或阅读机器码时,应回到页面列出的真实展开指令和相关重定位语义来判断行为。
官方语义核对重点
官方汇编手册把 la 作为汇编器层面的伪指令/别名处理,硬件执行的是展开后的真实指令序列。
真实语义以 AUIPC 等展开指令的 ISA 定义为准;本页不把 la 当作独立硬件 opcode。
地址加载中的 %pcrel_hi/%pcrel_lo 或 %got_pcrel_hi 重定位必须按官方汇编手册和 psABI 的配对规则理解。
工具链与链接器边界
la 会随 .option pic/nopic 和代码模型选择 lla 或 lga 风格路径;最终形式还可能被链接器松弛。
涉及符号时,应结合重定位记录和最终反汇编阅读,而不是只看源代码中的 la。
展开过程怎么理解
步骤 1
非 PIC 路径:AUIPC 以 .Lla 处的 PC 为基准,生成符号地址的高位 PC 相对部分。
步骤 2
非 PIC 路径:ADDI 使用匹配 .Lla 的低 12 位重定位补齐地址。
步骤 3
PIC 路径:AUIPC 以 .Lla_got 处的 PC 为基准,生成 GOT 表项地址的高位部分。
步骤 4
PIC 路径:l{w|d} 使用匹配 .Lla_got 的低 12 位重定位,从 GOT 表项加载符号地址。
在 objdump / 反汇编里可能看到什么
非 PIC 对应 AUIPC+ADDI,PIC 对应 AUIPC+GOT 加载;反汇编可能显示 la,也可能显示 lla/lga 或真实指令序列。
官方依据与阅读顺序
本页把伪指令当作汇编器层面的别名或宏来解释:先看它会展开成哪些真实指令,再回到官方 ISA 手册理解真实指令的行为。涉及 ABI、重定位或链接器松弛时,以 psABI 文档为准。
什么时候优先想到它
获取全局变量或静态对象地址
加载字符串常量、跳转表或函数符号地址
写需要同时适配 PIC/nopic 的汇编源码
让工具链处理符号重定位和 GOT 选择
容易混淆 / 常见误区
la 加载的是地址,不是该地址处的内存值;取值还需要 lw/ld/flw 等加载指令
PIC 模式下可能通过 GOT 间接加载,不应假定总是 AUIPC+ADDI
低 12 位重定位必须配对到对应的 AUIPC 标签,手写展开时不要混用标签
最终序列可能被链接器松弛,调试时以重定位和最终反汇编为准
常见问题
la 是真实 RISC-V 指令吗?
la 是汇编器伪指令或别名,不是单独硬件 opcode。页面中的“常见真实展开”列出官方展开,真实行为由展开后的 ISA 指令决定。
使用 la 时最容易误解什么?
la 加载的是地址,不是该地址处的内存值;取值还需要 lw/ld/flw 等加载指令