I am fairly certain I have seen this in code before, but I am unable to find any references on how to do it. I do expect this to be compiler or assembler specific.
I want to define an function pointer array of (compile-time) fixed length for use as an interrupt vector table on an embedded device. Each handler will push its interrupt number before jumping to a common handler. Creating a macro for these simpler functions is straight forward:
.macro irq number
.global irq\number
irq\number:
pushd $\number
jmp irq_handler_common
.endm
These can then be defined manually like this:
irq 0
irq 1
irq 2
...
However, I would rather not clutter my ASM file by manually defining 256 of these. Thus, what I would like to do is use an for-loop like preprocessor/macro that would allow me to do something like this:
for i in 0 ... 255
irq i
Can this be done in using macros?
Using suggestions by @MichaelPetch and @Jester I've compiled the following working solution (requires use of the GNU Assembler for altmacro
, or other supporting assembler). Unfortunately I had to create two macros, one to instantiate the interrupt entry point stubs and the other to help create the vector of these entry addresses. I was observing Error: invalid operands (*UND* and *ABS* sections) for %
if I tried to use .long irq %i
from within the .rept
that creates default_handlers
. If anyone has a smaller/simpler solution please post!
Define the entry point specific to each handler entry
.macro irq_stubX number
irq\number:
pushd $\number
jmp irq_handler_common
.endm
Using this macro (and altmacro
), create 256 instances
.altmacro
.section .text
.set i,0
.rept 256
irq_stubX %i
.set i,i+1
.endr
Finally, using another macro, create a vector of the labels we just created above.
.section .data
.macro irq_labelX number
.long irq\number
.endm
default_handlers:
.set i,0
.rept 256
irq_labelX %i
.set i, i+1
.endr
For reference, this does not work and reports the error mentioned above:
default_handlers:
.set i,0
.rept 256
.long irq %i
.set i, i+1
.endr
EDIT. The solution can be made smaller and more clear per @RossRidge's suggestion below.
.altmacro
.macro irq_insertX number
.section .text
irq_stubX \number
.section .data
.long irq\number
.endm
.section .data
default_handlers:
.set i,0
.rept 256
irq_insertX %i
.set i, i+1
.endr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With