我们可以读取here,interrupt属性关键字用于ARM, AVR, CR16, Epiphany, M32C, M32R/D, m68k, MeP, MIPS, RL78, RX and Xstormy16。它对使用riscv32-***-elf-gcc编译器的riscv编译有什么影响吗?
interrupt
ARM, AVR, CR16, Epiphany, M32C, M32R/D, m68k, MeP, MIPS, RL78, RX and Xstormy16
riscv32-***-elf-gcc
rlcwz9us1#
RISC-V有一个单独的页面声称它可以工作。你可以找到它here。你也可以通过编译代码来验证它是否有属性集。我没有安装riscv 32工具链,但是我设法用riscv 64工具链验证了它。你应该用riscv 32工具链重复同样的步骤,以确保它能正常工作。使用简单的test.c文件:
test.c
__attribute__((interrupt)) void test() {}
用riscv64-linux-gnu-gcc -c -o test.o test.c编译它,用riscv64-linux-gnu-objdump -D -j.text test.o反汇编它,我们可以看到它在函数的结尾生成mret指令:
riscv64-linux-gnu-gcc -c -o test.o test.c
riscv64-linux-gnu-objdump -D -j.text test.o
mret
0: 1141 addi sp,sp,-16 2: e422 sd s0,8(sp) 4: 0800 addi s0,sp,16 6: 0001 nop 8: 6422 ld s0,8(sp) a: 0141 addi sp,sp,16 c: 30200073 mret
删除interrupt属性后,指令变为常规的ret。根据this SO answer,这似乎是正确的行为。
ret
lb3vh1jj2#
通常,interrupt处理程序需要与正常函数不同的进入/退出序列。差异集中在中断中保存所有寄存器(通常,在正常函数调用中仅保留一些寄存器)和返回指令通常不同(例如,在ARM中,它必须更改处理器的操作模式,在RISCV处理器中可能也是如此)interrupt属性通知编译器例程的属性,以便编译器可以为其生成正确的代码。
2条答案
按热度按时间rlcwz9us1#
RISC-V有一个单独的页面声称它可以工作。你可以找到它here。你也可以通过编译代码来验证它是否有属性集。
我没有安装riscv 32工具链,但是我设法用riscv 64工具链验证了它。你应该用riscv 32工具链重复同样的步骤,以确保它能正常工作。
使用简单的
test.c
文件:用
riscv64-linux-gnu-gcc -c -o test.o test.c
编译它,用riscv64-linux-gnu-objdump -D -j.text test.o
反汇编它,我们可以看到它在函数的结尾生成mret
指令:删除
interrupt
属性后,指令变为常规的ret
。根据this SO answer,这似乎是正确的行为。lb3vh1jj2#
通常,
interrupt
处理程序需要与正常函数不同的进入/退出序列。差异集中在中断中保存所有寄存器(通常,在正常函数调用中仅保留一些寄存器)和返回指令通常不同(例如,在ARM中,它必须更改处理器的操作模式,在RISCV处理器中可能也是如此)interrupt属性通知编译器例程的属性,以便编译器可以为其生成正确的代码。