如何用GNU汇编宏替换x86汇编符号值?实现xmm(i)寄存器名拼接
问题描述
我编写了一个GAS宏,用来把8个单精度浮点数加载到xmm寄存器中,构造函数参数:
.macro macro_name .set i, 0 .rept 8 movss (i * 4)(%rsi), %xmm(i) .set i , i + 1 .endr .endm
原本期望展开后得到这样的代码:
movss (%rsi), %xmm0 movss 0x4(%rsi), %xmm1 ... movss 0x1c(%rsi), %xmm7
但实际展开时,(i * 4)能正常替换成对应偏移量,可%xmm(i)却不会展开,直接保留成%xmm(i)的原样。
解决方法
GNU汇编器(GAS)不会自动解析寄存器名称里的括号表达式,要让寄存器编号正确展开,得用字符串插值的方式把变量值直接插入到寄存器名中。
方法一:修改.rept循环的寄存器引用
把原来的%xmm(i)改成%xmm\i,用\i直接引用计数器变量的值,修改后的宏如下:
.macro macro_name .set i, 0 .rept 8 movss (i * 4)(%rsi), %xmm\i .set i, i + 1 .endr .endm
这样循环时\i会被替换成当前的数字,生成%xmm0到%xmm7的正确寄存器名。
方法二:用.irp简化循环
如果不想手动维护计数器,可以用.irp指令直接遍历寄存器编号列表,代码更简洁:
.macro macro_name .irp num, 0,1,2,3,4,5,6,7 movss (\num * 4)(%rsi), %xmm\num .endr .endm
.irp会依次把列表里的每个值代入num变量,自动完成8次循环展开,完全符合预期效果。
内容的提问来源于stack exchange,提问作者arka
相关产品推荐
相关产品推荐

