571
社区成员
发帖
与我相关
我的任务
分享实验环境ubuntu18.04
准备工作,在x64平台编译RISCV汇编代码需要交叉编译链:
首先通过gcc -v获得当前gcc版本,再通过sudo apt search riscv查找riscv,找到一个包的描述为"GNU C compiler (cross compiler for riscv64 architecture)",并且其版本号和gcc的版本号相同,那就是他没错了
$ sudo apt install gcc-7-riscv64-linux-gnu
安装该包及其自动下载的依赖包之后就可以开始编译了。
对于以下程序
int g(int x) { return x + 3; }
int f(int x) { return g(x); }
int main() { return f(8) + 1; }
在x64平台进行RISCV交叉汇编汇编,采用刚刚下载的交叉编译器
$ riscv64-linux-gnu-gcc-7 -S main.c -o main-riscv64.s
根据网上的相关资料





得到的汇编文件如下,三个函数做的事情基本相同,只解释了main中的语句。以及其中有些我认为无意义的语句
When you build without optimization the compilers priority is to generate code that's easy to debug and matches the original source code as closely as possible, not code that runs fast.
.file "main.c"
.option nopic
.text
.align 1
.globl g
.type g, @function
g:
add sp,sp,-32
sd s0,24(sp)
add s0,sp,32
mv a5,a0
sw a5,-20(s0)
lw a5,-20(s0)
addw a5,a5,3
sext.w a5,a5
mv a0,a5
ld s0,24(sp)
add sp,sp,32
jr ra
.size g, .-g
.align 1
.globl f
.type f, @function
f:
add sp,sp,-32
sd ra,24(sp)
sd s0,16(sp)
add s0,sp,32 以上同main,保存现场以及返回地址
mv a5,a0 以下四句推测是编译器在无优化状态下做的无意义操作
sw a5,-20(s0) 我尝试在O1 flag下进行编译,整个程序直接变成了返回立即数
lw a5,-20(s0)
mv a0,a5
call g
mv a5,a0
mv a0,a5
ld ra,24(sp)
ld s0,16(sp)
add sp,sp,32
jr ra
.size f, .-f
.align 1
.globl main
.type main, @function
main:
add sp,sp,-16 扩展栈空间
sd ra,8(sp) caller保存return address
sd s0,0(sp) main函数作为callee保存frame pointer
add s0,sp,16 逻辑空栈
li a0,8 caller存入函数参数
call f 调用f
mv a5,a0 将函数返回值存入a5
addw a5,a5,1 执行+1并存入a5
sext.w a5,a5 将其扩展到32位并进行符号扩展
mv a0,a5 存入a0等待返回
ld ra,8(sp) 获得最开始保存的返回地址
ld s0,0(sp) 恢复上个函数的栈底地址
add sp,sp,16 恢复栈顶
jr ra 回到上个函数
.size main, .-main
.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
Reference:
https://zhuanlan.zhihu.com/p/295439950
https://lgl88911.github.io/2021/02/28/RISC-V%E6%B1%87%E7%BC%96%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/