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

RISC-V汇编插入符号地址字面量遇阻:C与汇编联调矩阵乘法问题

问题与解决方案

问题背景

现有C矩阵乘法程序,声明了外部指针类型的矩阵变量:

extern float* MATR_A;
extern float* MATR_B;
extern float* MATR_C;
extern int N; //矩阵维度大小

int mmult() {
  for(int i=0; i<N; i++) {
    for(int j=0; j<N; j++) {
      MATR_C[i*N + j] = 0;
      for(int k=0; k<N; k++) {
        MATR_C[i*N + j] += MATR_A[i*N + k] * MATR_B[k*N + j];
      }
    }
  }
}

配套的汇编文件直接将MATR_A标签指向矩阵数据,导致C代码把矩阵第一个元素的值当作地址使用,引发错误:

.globl _start
.globl MATR_A
.globl MATR_B
.globl MATR_C
.globl N

.section .text
_start:
  j mmult

halt:
  nop
  j halt

.section .data
MATR_A:
  .float 1.0
  .float 2.0
  .float 3.0
  .float 4.0

MATR_B:
  .float 4.0
  .float 3.0
  .float 2.0
  .float 1.0
  
MATR_C:
  .word 0 #预留空间
  .word 0
  .word 0
  .word 0

N:
  .word 2

从反汇编片段可见,代码错误地将MATR_A的第一个元素值加载到寄存器当作地址:

0001009c <mmult>:
   1009c:       86c1a883                lw      x17,-1940(x3) # 1119c <N>
   100a0:       09105463                blez    x17,10128 <mmult+0x8c>
   100a4:       000117b7                lui     x15,0x11
   100a8:       1307a303                lw      x6,304(x15) # 11130 <MATR_A> ; 此处读取的是MATR_A指向的float值,而非矩阵地址
   ...

仅用汇编的解决方案

核心思路是:让MATR_A、MATR_B、MATR_C这些符号对应存储矩阵地址的指针变量,而非矩阵数据本身。修改汇编代码如下:

.globl _start
.globl MATR_A
.globl MATR_B
.globl MATR_C
.globl N

.section .text
_start:
  j mmult

halt:
  nop
  j halt

.section .data
; 定义实际的矩阵数据,用内部标签(下划线前缀避免外部可见)
_MATR_A:
  .float 1.0
  .float 2.0
  .float 3.0
  .float 4.0

_MATR_B:
  .float 4.0
  .float 3.0
  .float 2.0
  .float 1.0
  
_MATR_C:
  .word 0 #预留空间
  .word 0
  .word 0
  .word 0

; 定义C中引用的指针变量,存储对应矩阵的地址
MATR_A:
  .word _MATR_A
MATR_B:
  .word _MATR_B
MATR_C:
  .word _MATR_C

N:
  .word 2

修改后,C代码读取MATR_A时,得到的是_MATR_A的地址(即矩阵数据的起始地址),而非矩阵第一个元素的值,完全符合float*类型的要求。

链接器方案(无需额外脚本)

如果不想修改汇编中的标签命名逻辑,也可以通过编译时的符号别名完成映射:
保持C代码不变,在编译命令中添加链接选项,将矩阵数据标签的地址赋值给C中引用的指针符号:

riscv64-unknown-elf-gcc -nostdlib -nostartfiles -march=rv32if -mabi=ilp32 -O3 -Wl,--defsym=MATR_A=_MATR_A -Wl,--defsym=MATR_B=_MATR_B -Wl,--defsym=MATR_C=_MATR_C mmult.S mmult.c -o mmult.elf

前提是汇编中把原矩阵数据标签改为_MATR_A、_MATR_B、_MATR_C,本质和第一种方案逻辑一致,只是通过链接器完成符号地址的映射。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:35:04