我正在编写一个嵌入式C程序来测试我在一块FPGA板上开发的硬件IP.我在玩RISC-V GCC ASM语法时,发现了这个奇怪的问题.
这是我在C程序中编写的代码.write_target
和base_addr
都声明为易失性uint32_t.
// write_target = 0x1F9
asm volatile (
"li %0, 0x1F9\n"
: "=r"(write_target)
);
// base_addr = 0x1040_6000
asm volatile (
"lui %0, %1"
: "=r" (base_addr)
: "i" (66566)
);
// base_addr = 0x1040_6000 + 0x0
asm volatile (
"addi %0, %1, %2\n"
: "=r"(base_addr)
: "r"(base_addr), "i"(0)
);
// mem[base_addr] = write_target
asm volatile (
"sh %0, 0(%1)\n"
: "=r"(write_target)
: "r"(base_addr)
);
当我查看编译后的转储时,我看到它已编译为以下代码:
800031e6: 1f900793 li a5,505 // a5 = 0x1F9 = d'505
800031ea: f6f42423 sw a5,-152(s0) // mem[s0-152] = 505
800031ee: 104067b7 lui a5,0x10406 // a5 = 0x10406 = d'66566
800031f2: f6f42623 sw a5,-148(s0) // mem[s0-148] = 0x10406
800031f6: f6c42783 lw a5,-148(s0) // a5 = mem[s0-148]
800031fa: 00078793 mv a5,a5 // a5 = a5
800031fe: f6f42623 sw a5,-148(s0) // mem[s0-148] = 0x10406
80003202: f6c42783 lw a5,-148(s0) // a5 = mem[s0-148]
80003206: 00f79023 sh a5,0(a5) # 10406000 <_tbss_end+0x10406000>
// mem[a5] = a5
我不明白为何会这样.我对RISC-V GCC交叉编译器的内部工作原理不是很熟悉,所以我不知道我做错了什么.我反复判断了语法,据我所知是正确的.我正在使用-03优化标志运行.
我真的很感激你们所有人可能有的任何指导.
谢谢!
更新:我使用的是来自riscv-gnu-工具链Gitrepo的NewlibGCC编译器.
我遇到的问题是,我想将write_target
的值存储到base_addr
中.但编译后的代码似乎将base_addr
存储到base_addr
中.