How to make a macro in C to parameterize register?

How to make a macro in C to parameterize register?

I want to define a assembly to read register from arm64. Code is like the following:

asm volatile(
        "str <reg> [%0]\n"
        :
        : "r"(value)
        : "memory"
    );

how to use a macro to define such code. <reg> is in a string literal and the behaviour of macros make me confused when I use # and ##

I tried to define even in the following way, it still causes an error.

#define STR_x0 "str x0 [%0]\n"
#define STR_x1 "str x1 [%0]\n"
...
#define STR_REG(reg) STR_##reg

#define ASM_READ_REG(reg) \
    asm volatile( \
        STR_REG(reg) \
        : \
        : "r"(value) \
        : "memory" \
    )

Answer

Try this corrected approach,

#define STR_x0 "str x0, [%0]\n"
#define STR_x1 "str x1, [%0]\n"
// your other registers

#define STR_REG(reg) STR_##reg

#define ASM_READ_REG(reg) \
    asm volatile( \
        STR_REG(reg) \
        : \
        : "r"(value) \
        : "memory" \
    )

Issues for you to fix:

  1. the arm64 assembly syntax requires a comma after the register name: str x0, [%0] not str x0 [%0]

  2. the way you're trying to use marcos is correct, but there is issues with how you're invoking them.

this is the another approarch

#define ASM_READ_REG(reg) \
    asm volatile( \
        "str " #reg ", [%0]\n" \
        : \
        : "r"(value) \
        : "memory" \
    )

with this kind of appraoch you can call it like

ASM_READ_REG(x0);
ASM_READ_REG(x1);

The # operator in the macro convers the parameter to a string literal, that is what you need for assembly a code, this avoids the need for the intermediate STR_REG and STR_x0 macros.

I HOPE IT WORKS FOR YOU! <3

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles