硬件:risc-v 开发板 (GD32VF103VBT6 最小系统板 )
软件环境:Linux X220 5.0.0-37-generic #40~18.04.1-Ubuntu SMP Thu
Nov 14 12:06:39 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
IDE:VSCode1.41.1 + platformio IDE+ gd32v
汇编文件:Add.S
(注意是大写S) 不然在VSCode里会编译错误:
riscv64-unknown-elf-as: unrecognized option '-x'
.file Add.S .section .text .globl Add .type Add,@function ;可选 Add: add a0,a0,a1 ;// a0对应参数1,a1对应参数2 ret ;且a0带返回值
图1-1
上述的汇编为叶文件(不调其它函数的文件)汇编函数格式,如果需要调用其它函数需要按 图2-1
在c/c++文件里调用汇编语言编写的函数
//先声明函数原型 int Add(int i,int j); int main(void) { //...other codes int rtn=Add(100,200); // a0对应参数1,a1对应参数2,...a7对应参数8(这里寄存器为接口名称:ABI Name) printf("%d",rtn); //...other codes return 0; }
图1-2
汇编调用汇编函数 calculate(int x,int y,int z) #计算x-(y+z)
文件:Sub.S
.section .text
.globl Sub
Sub:
sub a0,a0,a1
ret
文件:calculate.S #;函数调用模板
.section .text #";函数调用模板" .equ framesize,16 #"frameszie=ra+a0+a1+...an总字符数" .globl calculate #计算x-(y+z) .type calculate,@function calculate: #";calculate(a0,a1,a2)//这里3个参数 framesize=(3+1)*4 #假定每个参数4个字节" addi sp,sp,-framesize #";堆指针上浮增加堆空间" sw ra,framesize-4(sp) sw s0,framesize-8(sp) sw s1,framesize-12(sp) sw s2,framesize-16(sp) mv s2,a0 #"Add 参数1 x" mv s1,a1 #"Add 参数2 y" mv s0,a2 #"Add 参数3 z" #-----开始操作--------- add a1,s0,s1 #(y+z) mv a0,s2 # x jal Sub #x-(y+z) #------结束操作-------- lw ra,framesize-4(sp) ;"取回返回地址" lw s0,framesize-8(sp) lw s1,framesize-12(sp) lw s2,framesize-16(sp) addi sp,sp,framesize ;"返还堆空间" ret
calculatePrint.S
汇编调用汇编Sub函数及c/c++函数printf("%d-(%d+%d)=%d",x,y,z,r)
.section .text .equ framesize,16 #"frameszie=ra+a0+a2+...an总字符数" .globl calculatePrint #"计算x-(y+z)" .type calculatePrint,@function calculatePrint: #";calculate(a0,a1,a2)//这里3个参数 framesize=(3+1)*4 #假定每个参数4个字节" #";printf('%d-(%d+%d)=%d',a0,a1,a2,a3);" addi sp,sp,-framesize sw ra,framesize-4(sp) sw s0,framesize-8(sp) sw s1,framesize-12(sp) sw s2,framesize-16(sp) mv s2,a0 #"Add 参数1 x" mv s1,a1 #"Add 参数2 y" mv s0,a2 #"Add 参数3 z" #-----开始操作--------- add a1,s0,s1 #(y+z) mv a0,s2 # x jal Sub #x-(y+z) #"printf('%d-(%d+%d)=%d',x,y,z,r)" mv a4,a0 #"返回值" mv a3,s0 #x mv a2,s1 #y mv a1,s2 #z la a0,format #"format" jal printf #------结束操作-------- lw ra,framesize-4(sp) lw s0,framesize-8(sp) lw s1,framesize-12(sp) lw s2,framesize-16(sp) addi sp,sp,framesize ret .section .rodata format: .string "%d-(%d+%d)=%d"