我正在交叉编译riscv-corev32-elf-gcc
。
在第一个文件'generic.S'中我有下面的代码:
.section .text.handlers
.weak u_sw_irq_handler
.weak __no_irq_handler
.section .vectors, "ax"
vector_table:
jal x0, u_sw_irq_handler
jal x0, __no_irq_handler
jal x0, __no_irq_handler
...
.section .text
reset_handler:
la t0, vector_table
csrw mtvec, t0
在第二个文件'custom.s'中我有下面的代码:
.section .text.handlers
.<x> u_sw_irq_handler
.<x> __no_irq_handler
.section .vectors, "ax"
vector_table:
jal x0, u_sw_irq_handler
jal x0, ISR_1_handler
jal x0, ISR_2_handler
...
其中<x>
为global
或local
当global
时,这是反汇编的(部分)结果:
00001000 <vector_table>:
1000: 7760d06f j e776 <u_sw_irq_handler>
1004: 1880706f j 81cc <ISR_1_handler>
1008: 1e40706f j 822c <ISR_2_handler>
...
1084: 7760d06f j e776 <u_sw_irq_handler>
1088: 7320d06f j e736 <__no_irq_handler>
108c: 72e0d06f j e736 <__no_irq_handler>
...
00001108 <reset_handler>:
1108: 00000297 auipc t0,0x0
110c: f7c28293 addi t0,t0,-264 # 1000 <vector_table>
1110: 30529073 csrw mtvec,t0
当local
时,这是反汇编的(部分)结果:
00001000 <vector_table>:
1000: 7760d06f j e776 <u_sw_irq_handler>
1004: 1880706f j 81cc <ISR_1_handler>
1008: 1e40706f j 822c <ISR_2_handler>
...
00001084 <vector_table>:
1084: 7760d06f j e776 <u_sw_irq_handler>
1088: 7320d06f j e736 <__no_irq_handler>
108c: 72e0d06f j e736 <__no_irq_handler>
...
00001108 <reset_handler>:
1108: 00000297 auipc t0,0x0
110c: f7c28293 addi t0,t0,-132 # 1084 <vector_table>
1110: 30529073 csrw mtvec,t0
但这不是我想要的:
- 如果vector_table没有其他定义,我希望采用泛型定义
- 我希望泛型定义被自定义.S定义(如果存在)覆盖,并希望泛型.S中的reset_handler加载vector_table的自定义地址
- 使用“global”更接近我的要求,但vector_table在最后一个向量之后继续
jal x0, ...
- 使用'local',reset_handler中调用的vector_table将是通用的而不是定制的。
编辑:对不起,我错过了重置处理程序反汇编的匹配日志
1条答案
按热度按时间yvfmudvl1#
程序集
weak
符号未按预期工作weak
的工作方式与您想象的不同:如果符号不存在于另一个目的档中,
weak
会使符号成为全域符号;如果符号存在于另一个目的档中,则会使符号本身(!)消失。示例(抱歉,我的示例是x86,因为我不知道riscv 32):
如果没有其他目标文件包含
.global some_irq_handler
或.global some_other_irq_handler
,则.weak
行几乎与.global
行具有相同的效果。但是,如果另一个目标文件包含这两个符号,则上面的示例大致等于:
我希望通用定义被自定义.S定义(如果存在)覆盖...
情况1:
vector_table
不需要位于内存中的某个地址:在这种情况下,您可以通过以下方式执行此操作:
如果项目中存在另一个向量表,则生成的代码(链接后)将如下所示:
情况2:
vector_table
需要位于内存中的某个地址:在这种情况下,可以通过以下方式执行此操作:
您永远不会用另一个“通用”中断向量表覆盖“通用”中断向量表,而只覆盖符号
interrupt<n>
:(This也适用于C语言编写的代码。因为C编译器默认情况下使函数为
.global
而不是.weak
,所以C语言编写的函数会覆盖.weak
。)产生的程式码将如下所示: