esp c2 ble芯片模块上海乐鑫科技代理商RISC-V调用约定,调用约定规范函数时参数传递和函数返回结果的方式和数据类型。RISC-V gcc 编译器支持 ABI 调用约定。根据 ABI约定,RV32I 函数调用时使用a0~a7,共 8个通用寄存器传递参数,使用 ao 和al 两个通用存器返回函数结果。如果超过 8 个参数,则超出部分的参数通过栈传递。
在示例5.7中,当函数调用“maxvalue=max(a,b);”时,a=50 传入寄存器a0,b=150 传入寄存器 al。esp c2 ble芯片模块上海乐鑫科技代理商函数的结果通过寄存器 a0 返回。
示例 5.7 中的函数 max编译后生成的汇编程序如示例 5.10 所示。在第 6、7行中将传入的参数通过 a0 和 al 赋给变量,在第 16 行中将数结果存入寄存器a0。
示例5.10:max 汇编程序。
1 .section .text.max, "ax", @progbits
2 .global max
3 type max, @function
4 max: //在栈分配4 个整数空间
5 addisp,sp,- 16 //一个变量,int a
6 sw a0,12(sp) //第二个变量,int b
7 sw al,8(sp) //a4 = int a
8 lw a4,12(sp) //a5 = int b
9 lw a5,8(sp) //if(a4<a5) goto L2
10 lt a4,a5,.L2 //a5 = int a
11 lw a5,12(sp) //goto L3
12 j L3
13 L2:
14 lw a5,8(sp) //a5 = int b
15 L3:
16 mv a0,a5 //a0=a5,设置返回值
17 addisp,sp,16 //释放变量空间,恢复栈指针
18 jr ra //返回主程序
esp c2 ble芯片模块上海乐鑫科技代理商RISC-V ABI进一步规范了参数传递的一些细节:
1、寄存器所传递的标量参数的大字宽为处理器字宽(XLEN)。例如,RV321寄存器传递的大参数为 32 位,RV64I寄存器传递的大参数为 64 位。如果参数是比XLEN 窄的整数,则在写人寄存器或栈时,先根据其符号类型扩展到 32 位,然后符号扩展到 XLEN 位。
2、宽度是 2XXLEN 位的标量参数通过一对寄存器传递,低 XLEN 位在低位寄存器中,高 XLEN 位在高位寄存器中。如果没有可用的参数寄存器,则通过栈传递标量。如果只剩一个寄存器可用,则用寄存器传递低 XLEN 位,用栈传递高 XLEN位。
3、宽度大于 2XXLEN 的标量,通过引用(指针)传递,并在参数列表加入地址在示例5.7中,当函数调用“printf(“max= %d”,maxvalue)”时,一个参数的长度不确定,通过引用(指针)传递。
4、如果通过引用传递参数,调用者为返回数据分配内存,并将引用地址(指针作为调用函数时的一个参数传递给被调用者。
esp c2 ble芯片模块上海乐鑫科技代理商运行程序时,为了获得良好的性能,尽量将变量存放在寄存器而不是在内存中但同时也要避免频繁地保存和恢复寄存器。
esp c2 ble芯片模块上海乐鑫科技代理商RISC-V处理器的通用寄存器多,能够存放更多临时数据,减少保存和恢复青布器的次数,提高秘序运行性能。用 t0~t6 表示雨数调用过程中部分不需要备份赛存器,称为临时寄存器,用s0~s11表示在明数调用时需要备份的存器,称为存寄存器。表4.2列出了与a0~a7、t0~t6、s0~s11 对应的通用寄存器序号。
在函数调用过程中,如果实参类型与形参类型,或者实际返回值与声明的类型不一致,则需要对实参或返回值进行处理。
参数的传递方式可分为宽参数传递和窄参数传递。宽参数传递,被调用者把实参缩小到形参的范围;窄参数传递,调用者把实参缩小到形参的范围。
结果返回方式也分为宽返回和窄返回。宽返回,调用者把返回值缩小到函数原型所声明的类型;窄返回,被调用者把返回值缩小到函数原型声明的类型。esp c2 ble芯片模块上海乐鑫科技代理商gcc 编译器采用宽参数传递和宽返回方式。