Газовый макрос altmacro с знаком процента в параметре по умолчанию не выполняется: "% operator нуждается в абсолютном выражении"
Я хочу создать макрос следующим образом:
.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
: Результаты выражения как строки,
так как без .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 */
Чтобы предотвратить это расширение, мы должны сделать как упомянутый 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
, так как для каждого звонка требуется использовать дополнительный шум...