Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For-loop macro/preprocessor for assembly files in GCC

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?

like image 676
sherrellbc Avatar asked Mar 08 '23 04:03

sherrellbc


1 Answers

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
like image 77
sherrellbc Avatar answered Mar 23 '23 11:03

sherrellbc