Что означает 1: на языке ассемблера?

Я читал исходный код тестового шаблона 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;                                            \  

1 ответ

1: имя локального символа; это просто ярлык. От gas руководство:

Имена локальных символов

Локальные символы помогают компиляторам и программистам временно использовать имена. Они создают символы, которые гарантированно будут уникальными во всей области входного исходного кода и на которые можно ссылаться с помощью простой записи. Чтобы определить локальный символ, напишите метку в форме N: (где N представляет любое положительное целое число). Чтобы обратиться к самому последнему предыдущему определению этого символа, напишите Nb, используя тот же номер, что и при определении метки. Чтобы обратиться к следующему определению локальной метки, напишите Nf - b означает "назад", а f - "вперед".

Нет никаких ограничений на то, как вы можете использовать эти метки, и вы можете использовать их также. Таким образом, можно многократно определять одну и ту же локальную метку (используя одно и то же число N), хотя вы можете ссылаться только на самую последнюю определенную локальную метку этого номера (для обратной ссылки) или на следующее определение конкретной локальной метки для прямая ссылка. Стоит также отметить, что первые 10 локальных меток (0:...9:) реализованы несколько более эффективно, чем остальные.

Вот пример:

1:        jra 1f 
2:        jra 1b 
1:        jra 2f 
2:        jra 1b

Что является эквивалентом:

label_1:  jra label_3 
label_2:  jra label_1 
label_3:  jra label_4
label_4:  jra label_3 

Имена локальных символов являются только условным обозначением. Они немедленно преобразуются в более условные имена символов, прежде чем ассемблер использует их....

В вашем примере на этот ярлык ссылаются несколькими инструкциями ранее:

beqz t5, 1f;

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 \

Там мы видим ярлыки, на которые ссылаются как 2f, 1b, так далее.

Другие вопросы по тегам