GNU as递归宏生成跳转表异常:跳转偏移递减问题咨询
RISC-V汇编递归宏生成跳转表异常原因解析
问题现象
使用GNU as递归宏jump_table生成指向jump_0、jump_1、jump_2、jump_3的跳转表,反汇编后发现跳转偏移不符合预期,呈现递减且重复的错误指向,环境为MacOS M4平台的riscv64-elf-as/objdump v2.44。
汇编代码
.section .text .align 4 .macro jump_table name init last j \name\()_\init .if \last > \init jump_table \name \init+1 \last .endif .endm jump_table jump 0 3 jump_0: nop jump_1: nop nop jump_2: nop nop nop jump_3: nop nop nop nop
反汇编结果
0000000000000000 <jump_0-0x1c>: 0: 00000013 nop 4: 00000013 nop 8: 00000013 nop c: 0100006f j 1c <jump_0> 10: 00c0006f j 1c <jump_0> 14: 00a0006f j 1e <jump_0+0x2> 18: 0060006f j 1e <jump_0+0x2> 000000000000001c <jump_0>: 1c: 00000013 nop 0000000000000020 <jump_1>: 20: 00000013 nop 24: 00000013 nop 0000000000000028 <jump_2>: 28: 00000013 nop 2c: 00000013 nop 30: 00000013 nop 0000000000000034 <jump_3>: 34: 00000013 nop 38: 00000013 nop 3c: 00000013 nop 40: 00000013 nop 44: 00000013 nop 48: 00000013 nop 4c: 00000013 nop
预期结果
j 1c <jump_0> j 20 <jump_1> j 28 <jump_2> j 34 <jump_3>
异常原因
- 宏参数算术运算未被正确解析:GNU as中直接传递
init+1作为宏参数时,.if指令无法正确将其解析为数值表达式,而是当作字符串处理,导致递归条件判断逻辑出错,生成重复的跳转指令。 - 递归执行顺序问题:即使参数解析正常,原宏的递归逻辑是先生成当前
j指令再触发递归,但如果参数表达式未被正确计算,会导致init值无法递增,最终生成多个指向同一标签的跳转指令。
修复方案
使用.eval指令显式计算下一个init的数值,确保递归参数正确传递:
.section .text .align 4 .macro jump_table name init last j \name_\init .if \last > \init .eval \init + 1, next_init # 显式计算下一个init值 jump_table \name \next_init \last .endif .endm jump_table jump 0 3 jump_0: nop jump_1: nop nop jump_2: nop nop nop jump_3: nop nop nop nop
修改后,宏会正确生成顺序为j jump_0→j jump_1→j jump_2→j jump_3的跳转表,反汇编结果将符合预期。
内容的提问来源于stack exchange,提问作者EnzoR
相关产品推荐
相关产品推荐

