默认参数中带有百分号的 Gas altmacro 宏因“% 运算符需要绝对表达式”而失败
Posted
技术标签:
【中文标题】默认参数中带有百分号的 Gas altmacro 宏因“% 运算符需要绝对表达式”而失败【英文标题】:Gas altmacro macro with a percent sign in a default parameter fails with "% operator needs absolute expression" 【发布时间】:2013-11-15 14:51:07 【问题描述】:我想创建如下宏:
.altmacro
.macro assert_eq a, b=%eax
LOCAL ok
#...
.endm
用作:
assert_eq $1
assert_eq $1, %eax
我想要.altmacro
用于LOCAL
(我看到了使用\@
的另一种可能性,但我想要LOCAL
)。
但是当我尝试编译时,我得到:
Error: % operator needs absolute expression
我猜这个问题是由b=%eax
试图使用.altmacro
启用的另一个功能造成的:Expression results as strings,
因为没有.altmacro
,我可以毫无问题地写这个。
如果这是真的,我该如何转义以使我的宏工作?如果不是,我的代码有什么问题?
额外问题:如何使用%
?
GAS 版本:2.23.52
【问题讨论】:
【参考方案1】:我遇到了一个非常相似的问题,我想将寄存器作为参数传递给需要使用 .altmacro 的宏。有效的解决方法是将寄存器括在 中并放置 !前 %。所以试着把你的宏改成
.macro assert_eq a, b=<%eax>
如果你想用寄存器作为参数调用你的宏
assert_eq <%eax>, <%ecx>
【讨论】:
我用感叹号!
观察不到任何效果(除了不编译:-)),你能举个例子吗?【参考方案2】:
使用.altmacro
,任何传递的参数或带有百分比%
的默认参数都会被视为表达式。
示例用法:
.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 */
为了防止这种扩展发生,我们必须像mentioned by mfbutner那样做:
.altmacro
.macro PERCENT x
mov \x, %eax
.endm
PERCENT <%ebx>
.macro PERCENT_DEFAULT x=<%ebx>
mov \x, %eax
.endm
PERCENT_DEFAULT
由于这种扩展只发生在参数上,而不是宏本身,如果我们确定参数是一个寄存器,另一种选择是将百分比放在宏内:
.macro PERCENT_ESCAPE_REG x
mov %x, %eax
.endm
mov $0, %eax
mov $1, %ebx
PERCENT_ESCAPE_REG ebx
/* eax == 1 */
但这有一个缺点,我们不能再传递像 $1
这样的立即数:
PERCENT_ESCAPE_REG $1
这对我来说是使用.altmacro
的一大障碍,因为它要求呼叫者在每次呼叫时都使用额外的噪音...
【讨论】:
【参考方案3】:你可以添加
.att_syntax noprefix
然后将宏称为
assert_eq $1, eax
【讨论】:
以上是关于默认参数中带有百分号的 Gas altmacro 宏因“% 运算符需要绝对表达式”而失败的主要内容,如果未能解决你的问题,请参考以下文章