Gas altmacro macro with a percent sign in a default parameter fails with “% operator needs absolute expression”

不问归期 提交于 2019-11-28 10:43:33

问题


I want to create a macro like the following:

.altmacro

.macro assert_eq a, b=%eax
    LOCAL ok
    #...
.endm

To be used as:

assert_eq $1
assert_eq $1, %eax

I want .altmacro for LOCAL (I see the other possibility of using \@, but I want LOCAL).

But when I try to compile this I get:

Error: % operator needs absolute expression

I am guessing that this problem is created by the fact that b=%eax is attempting to use another feature enabled by .altmacro: Expression results as strings, since without .altmacro I could write this without problem.

If this is true, how do I escape that for my macro to work? If not, what is wrong with my code?

Bonus question: how to use %?

GAS version: 2.23.52


回答1:


I have run into a very similar problem where I wanted to pass registers as arguments to a macro that required the use .altmacro. The fix that worked was to enclose the registers in <> and place ! before %. So try changing your macro to be

.macro assert_eq a, b=<%eax>

and if you ever want to call your macro with a register as an argument do

assert_eq <%eax>, <%ecx>



回答2:


With .altmacro, any parameter passed or default with a percent % gets treated as an expression.

Sample usage:

.altmacro

.macro PERCENT x
    mov $\x, %eax
.endm
mov $0, %eax
PERCENT %1+1
/* eax == 2 */

.macro PERCENT_DEFAULT x=%1+1
    mov $\x, %eax
.endm
mov $0, %eax
PERCENT_DEFAULT 1
/* eax == 1 */
PERCENT_DEFAULT
/* eax == 2 */

To prevent that expansion from happening, we have to do as mentioned by mfbutner:

.altmacro

.macro PERCENT x
    mov \x, %eax
.endm
PERCENT <%ebx>

.macro PERCENT_DEFAULT x=<%ebx>
    mov \x, %eax
.endm
PERCENT_DEFAULT

Since this expansion happens only to arguments, not inside the macro itself, one alternative if we are sure that the argument is a register, is to put the percent inside the macro:

.macro PERCENT_ESCAPE_REG x
    mov %x, %eax
.endm
mov $0, %eax
mov $1, %ebx
PERCENT_ESCAPE_REG ebx
/* eax == 1 */

But this has the downside that we cannot pass immediates like $1 anymore:

PERCENT_ESCAPE_REG $1

This is to me a huge turnoff to using .altmacro, as it requires callers to use extra noise on every call...




回答3:


You can add

.att_syntax noprefix

and than call the macro as

assert_eq $1, eax


来源:https://stackoverflow.com/questions/19776992/gas-altmacro-macro-with-a-percent-sign-in-a-default-parameter-fails-with-oper

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!