In this assembly file below, the macro jump_table
should automagically create ... a jump table to consecutively numbered labels like jump_0
, jump_1
, ... jump_<n>
.
It seems there is no loop feature in as
.macro
directive and the official documentation seems to suggest what appears to be a recursive macro.
Anyway, this is the file:
.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
The resulting binary, once disassembled with objdump
, yields this:
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
The jump table looks weird to me: offsets are decreasing while I would expect them to increase. Moreover, labelling also looks weird.
If I understood correctly, I should expect something like:
j 1c <jump_0>
j 20 <jump_1>
j 28 <jump_2>
j 34 <jump_3>
I bet I am missing something and some explanation would help me greatly.
I am using riscv64-elf-as
and riscv64-elf-objdump
v2.44 on MacOS M4.
\init+1
will not be evaluated before it gets passed recursively, therefore your macro creates something like this:
j jump_0
j jump_0+1
j jump_0+1+1
j jump_0+1+1+1
Which the assembler appears to round to the next valid address, i.e., in your case:
j 1c <jump_0>
j 1c <jump_0>
j 1e <jump_0+0x2>
j 1e <jump_0+0x2>
If you enable .altmacro
-mode, you can have expressions evaluated before they get passed as parameters, using %(expr)
:
.altmacro
.macro jump_table name init last
j \name\()_\init
.if \last > \init
jump_table \name, %(\init+1), \last
.endif
.endm
Godbolt-Demo: https://godbolt.org/z/hGjEG6TE1