ABI包括了关于函数调用约定(参数传递,函数返回值等)、数据类型、对齐方式、字节序、 函数栈布局、系统调用等方面的规范。 具体来说,ABI定义了以下内容: 数据类型、对齐方式和字节序; 寄存器使用约定:哪些寄存器用于传递函数参数、返回值和保存临时变量; 函数调用约定:函数调用的具体步骤,包括参数传递、返回值处理等; ...
jr ra # 跳转到返回地址 ra(函数返回) 在调用函数f前,先做了一步将函数f的两个参数放入寄存器a1,a0中。这是因为寄存器a1,a0是调用者保存寄存器(a调用b的话,由a函数来管理调用者保存寄存器的内容) 调用函数f时,将保存着函数参数的a1,a0寄存器压入栈中。 这时我们可以发现,当一个参数寄存器(形式为ax)保存一...
Rocket是采用Chisel(Constructing Hardware in an Scala Embedded Language)编写的,这也是UCB设计的一种开源的硬件编程语言,是Scala语言的领域特定应用,可以充分利用Scala的优势,将面向对象(object orientation)、函数式编程(functional programming)、类型参数化(parameterized types)、类型推断(type inference)等概念引入硬件编...
RISC-V 的设计目标之一就是对 C/C++ 等高级语言提供硬件支持,并保持不同 处理器之间在 ABI 层面的相互兼容。RISC-V 的用户指令标准还对函数调用约定 (Calling Convention)做了标准化,也就是对函数调用时,哪些寄存器需要保存, 还对寄存器具体的职能分配做了规定(因为 RV32E 只有 16 个通用寄存器,所以RV32E 的...
这里的意思是,一个Caller Saved寄存器可能被其他函数重写。 假设我们在函数a中调用函数b,任何被函数a使用的并且是Caller Saved寄存器,调用函数b可能重写这些寄存器。 我认为一个比较好的例子就是Return address寄存器(注,保存的是函数返回的地址),你可以看到ra寄存器是Caller Saved,这一点很重要,它导致了当函数a调用函...
//所生成的汇编代码如下,从中可以看出,浮点数乘法操作直接使用了RISC-V的fmul.d指令进行支持,且函数的两个double类型的参数直接使用浮点通用寄存器fa0和fa1进行传递。这是因为: - -march选项指明了目标平台支持的模块化指令子集为imafdc,其中包含了F和D指令子集,即支持单精度和双精度浮点指令,因此可以直接使用RISC-...
本篇主要分析在函数调用时的栈帧管理,首先是利用objdump对c文件进行反汇编。基于bionic中的hello.c文件进行编译并进行反汇编,由于在编译bionic时,默认编译的是静态链接,反汇编出来的文件非常多,所以需要在Android.bp/home/user/codes/zhimo-aosp-d_art/bionic/libc/Android.bp中对hello.c的编译属性进行修改,修改如下...
RISC-V 没有多寄存器的 Load/Store 指令,所以压栈/出栈一个寄存器就是一条指令,而Cortex-M 有多寄存器的 Push/Pop 指令,一般情况下进入函数一条 Push,退出函数一条Pop,虽然在执行速度上没有什么区别,但是指令空间上 RISC-V 比 Cortex-M 占用更多,而 RISC-V 的设计则是简化了执行单元的设计。多寄存器的 Loa...
相反,当CPU读取一个vadd函数时会发生什么,就像我们在伪代码示例中所做的那样,它开始遍历这些大寄存器。这是一个代码示例: vsetlen r1 , 16, 120 ; 120 element vector. Each element 16-bit vload v1, 14 ; Load 120 elements start at address 14 ...
为了简单和一致,软件开发工具通常使用 ABI 名称。根据 ABI,额外的寄存器专用于 X0 到 X15 范围内的保存寄存器、函数参数和临时变量,主要用于 RV32E 基础 ISA,它只需要前 16 个寄存器来实现简单的嵌入式微控制器。但是 RV32I 基础 ISA 将拥有所有 32 个寄存器 X0 到 X31。