Jim*_*one 2 assembly gnu-assembler riscv
我正在阅读RISC-V测试模式的源代码.在riscv-test.h中有一个宏定义,
我想知道1:这段代码意味着什么:
#define RVTEST_CODE_BEGIN \
.section .text.init; \
.align 6; \
.weak stvec_handler; \
.weak mtvec_handler; \
.globl _start; \
_start: \
/* reset vector */ \
j reset_vector; \
.align 2; \
trap_vector: \
/* test whether the test came from pass/fail */ \
csrr t5, mcause; \
li t6, CAUSE_USER_ECALL; \
beq t5, t6, write_tohost; \
li t6, CAUSE_SUPERVISOR_ECALL; \
beq t5, t6, write_tohost; \
li t6, CAUSE_MACHINE_ECALL; \
beq t5, t6, write_tohost; \
/* if an mtvec_handler is defined, jump to it */ \
la t5, mtvec_handler; \
beqz t5, 1f; \
jr t5; \
/* was it an interrupt or an exception? */ \
1: csrr t5, mcause; \
bgez t5, handle_exception; \
INTERRUPT_HANDLER; \
Run Code Online (Sandbox Code Playgroud)
这1:是一个本地符号名称; 它只是一个标签.从gas手册:
本地符号名称
本地符号可帮助编译器和程序员临时使用名称.它们创建的符号在输入源代码的整个范围内保证是唯一的,并且可以通过简单的符号来引用.要定义局部符号,请写入N:形式的标签:(其中N表示任何正整数).要引用该符号的最新先前定义,请使用与定义标签时相同的数字来写入Nb.要引用本地标签的下一个定义,请写入Nf - b代表"向后",f代表"向前".
对如何使用这些标签没有限制,您也可以重复使用它们.因此,可以重复定义相同的本地标签(使用相同的数字N),尽管您只能引用该数字的最近定义的本地标签(用于向后引用)或特定本地标签的下一个定义前瞻性参考.值得注意的是,前10个本地标签(0:... 9 :)的实现方式略高于其他标签.
这是一个例子:
Run Code Online (Sandbox Code Playgroud)1: jra 1f 2: jra 1b 1: jra 2f 2: jra 1b这相当于:
Run Code Online (Sandbox Code Playgroud)label_1: jra label_3 label_2: jra label_1 label_3: jra label_4 label_4: jra label_3本地符号名称只是一种符号设备.在汇编程序使用它们之前,它们会立即转换为更常规的符号名称....
在您的示例中,标签之前引用了一些指令:
beqz t5, 1f;
Run Code Online (Sandbox Code Playgroud)
在1f那里的意思是"下一个标签命名1",只是跳转到1:.
这是一种定义和引用本地标签的便捷方式,无需在任何地方考虑唯一名称.
这是另一个例子:
#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: la x6, 2f; \
TEST_INSERT_NOPS_ ## nop_cycles \
inst x6; \
bne x0, TESTNUM, fail; \
2: addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
Run Code Online (Sandbox Code Playgroud)
在那里,我们看到标签被引用的2f,1b等等.