汇编函数中的参数传递
在 Xtensa 架构中,函数的参数传递通常遵循一定的约定。通常情况下,前几个参数通过寄存器传递,其余参数则通过堆栈传递。具体的参数传递规则可能会因编译器的不同而略有差异,但大多数情况下遵循以下规则:
参数传递规则
-
前几个参数:
- 最初的几个参数通常通过通用寄存器传递。
- 对于 Xtensa 架构,前四个参数通常通过寄存器传递。
- 具体而言,参数通常通过
a0、a1、a2和a3寄存器传递。
-
剩余参数:
- 如果有超过四个参数,额外的参数通常通过堆栈传递。
- 调用者负责在调用函数前将这些参数压入堆栈,并在返回后清理堆栈。
-
返回值:
- 单个的返回值通常通过寄存器
a0传递。 - 如果返回值较大(例如超过 32 位),则可能通过多个寄存器或堆栈传递。
- 单个的返回值通常通过寄存器
示例
假设我们有一个函数 I2C_IRQHandler,它接受一个 u8 类型的参数 id。下面是使用 Xtensa 汇编实现该函数的一个示例,其中 a1 寄存器用于传递 id 的值。
asm
深色版本
1.globl I2C_IRQHandler
2I2C_IRQHandler:
3 // 加载 gIICDev 地址
4 movi.n a2, gIICDev ; 假设 gIICDev 的地址存储在一个全局变量中
5
6 // 计算 dev 的地址
7 const16 a3, 0 ; 用于偏移量计算
8 const16 a3, sizeof(I2C_DEV)
9 muli a3, a3, a1 ; a3 = id * sizeof(I2C_DEV)
10 addi a2, a2, a3 ; a2 = gIICDev + id * sizeof(I2C_DEV)
11
12 // 加载 dev->instance->idr
13 l32i.n a3, a2, offsetof(I2C_DEV, instance.idr)
14 movi.n a4, IRQ_MASK ; 假设 IRQ_MASK 是一个已知的常量
15 s32i.n a4, a3, 0
16
17 // 检查 dev->mode
18 l32i.n a3, a2, offsetof(I2C_DEV, mode)
19 cmpi.n a3, I2C_SLAVE
20 beqz a3, .end
21
22 // 调用 I2C_Slave_IRQHandle
23 movi.n a4, a2 ; 传递 dev 地址
24 call I2C_Slave_IRQHandle, a4
25
26 // 加载 dev->instance->ier
27 l32i.n a3, a2, offsetof(I2C_DEV, instance.ier)
28 s32i.n a4, a3, 0
29
30.end:
31 ret
参数传递详解
假设函数原型
c
深色版本
1void I2C_IRQHandler(u8 id);
汇编实现
asm
深色版本
1.globl I2C_IRQHandler
2I2C_IRQHandler:
3 // a1 寄存器中已经包含了 id 的值
4 // 加载 gIICDev 地址
5 movi.n a2, gIICDev ; 假设 gIICDev 的地址存储在一个全局变量中
6
7 // 计算 dev 的地址
8 const16 a3, 0 ; 用于偏移量计算
9 const16 a3, sizeof(I2C_DEV)
10 muli a3, a3, a1 ; a3 = id * sizeof(I2C_DEV)
11 addi a2, a2, a3 ; a2 = gIICDev + id * sizeof(I2C_DEV)
12
13 // 加载 dev->instance->idr
14 l32i.n a3, a2, offsetof(I2C_DEV, instance.idr)
15 movi.n a4, IRQ_MASK ; 假设 IRQ_MASK 是一个已知的常量
16 s32i.n a4, a3, 0
17
18 // 检查 dev->mode
19 l32i.n a3, a2, offsetof(I2C_DEV, mode)
20 cmpi.n a3, I2C_SLAVE
21 beqz a3, .end
22
23 // 调用 I2C_Slave_IRQHandle
24 movi.n a4, a2 ; 传递 dev 地址
25 call I2C_Slave_IRQHandle, a4
26
27 // 加载 dev->instance->ier
28 l32i.n a3, a2, offsetof(I2C_DEV, instance.ier)
29 s32i.n a4, a3, 0
30
31.end:
32 ret

5399

被折叠的 条评论
为什么被折叠?



