我正在与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的其他定义的情况下使用泛型定义
我希望泛型定义被custom.S定义覆盖(如果存在),并希望generic.S中的vector_table中的reset_handler加载该
使用“全局”的
之后继续使用jal x0, ...
使用“本地”的
编辑:对不起,我错过了重置处理程序反汇编的日志。
发布于 2022-08-13 06:01:00
程序集
weak
符号不像我预期的那样工作
weak
的工作方式与您想象的不同:
如果符号不存在于另一个对象文件中,并且它使符号本身(!),则weak
生成一个符号全局。如果它存在于另一个对象文件中,则消失。
示例(对不起,我的示例是x86,因为我不知道riscv32):
.weak some_irq_handler
.weak some_other_irq_handler
vector_table:
jmp some_irq_handler
jmp some_other_irq_handler
some_irq_handler:
iret
some_other_irq_handler:
iret
如果没有其他对象文件包含.global some_irq_handler
或.global some_other_irq_handler
,则.weak
行几乎与.global
行具有相同的效果。
但是,如果另一个对象文件包含这两个符号,则上面的示例或多或少等于:
vector_table:
# This symbol is defined in another object file
jmp some_irq_handler
# This symbol is defined in another object file
jmp some_other_irq_handler
# The code of "some_irq_handler" is still
# present; only the label "some_irq_handler:"
# has been removed by the linker!
iret
iret
# -- Another object file --
some_irq_handler:
...
我希望通用定义被custom.S定义覆盖,如果它存在的话.
Case 1:vector_table
需要而不是位于内存中的某个地址:
在本例中,您可以通过以下方式完成此操作:
.weak vector_table
vector_table:
jmp no_interrupt
jmp no_interrupt
...
如果项目中存在另一个向量表,则生成的代码(链接后)如下所示:
# -- "weak" object file --
# vector_table: - Label removed by the linker
# but the table itself is still there
jmp no_interrupt
jmp no_interrupt
...
# -- "overwriting" object file --
vector_table:
jmp interrupt1
jmp interrupt2
...
Case 2:vector_table
需要将定位在内存中的某个地址:
在本例中,您可以通过以下方式完成该操作:
.weak interrupt1
.weak interrupt2
...
vector_table:
jmp interrupt1
jmp interrupt2
...
__no_irq_handler:
interrupt1:
interrupt2:
...
interrupt256:
iret
您将永远不会用另一个中断向量表覆盖“泛型”中断向量表,但只覆盖符号interrupt<n>
。
.global interrupt2
interrupt2:
mov al, 0x1234
out 0xE4, ax
mov al, 0x20
out 0x20, al
iret
(这也适用于C编写的代码。因为C编译器默认使函数为.global
而不是.weak
,所以C写函数覆盖.weak
函数。)
生成的代码将如下所示:
# -- "weak" object file --
vector_table:
jmp interrupt1
jmp interrupt2
...
__no_irq_handler:
interrupt1:
# interrupt2: - Label removed by the linker
interrupt3:
...
interrupt256:
iret
# -- "overwriting" object file --
interrupt2:
mov al, 0x1234
out 0xE4, ax
mov al, 0x20
out 0x20, al
iret
https://stackoverflow.com/questions/73336063
复制相似问题