x86_64汇编中如何给寄存器设置SIB不支持的偏移值
x86-64环境下24倍偏移数组寻址实现方案
x86-64的SIB寻址仅支持1、2、4、8四种缩放系数,且单条寻址语句仅允许一个带缩放的索引寄存器,因此不能直接通过[a + rbx*24]或[a + rbx*8 + rbx*16]的方式实现24倍偏移,可通过以下两种常用方案实现需求:
方案1:LEA系数拆分(优先推荐)
利用24 = 3 * 8的拆分逻辑,通过两次LEA指令计算偏移,全程无乘法指令、不修改FLAGS寄存器,性能最优:
; 输入:rbx = 数组下标,a为数组基地址(全局符号或存在基址寄存器中) lea rcx, [rbx + rbx*2] ; 利用2倍缩放系数计算 rcx = rbx * 3 lea rdi, [a + rcx*8] ; 利用8倍缩放系数计算 rdi = a + rbx * 3 * 8 = a + rbx*24 lea rsi, [rdi + 8] ; 直接基于rdi偏移得到rsi,无需重复计算
如果数组基地址存储在其他寄存器(例如rax),只需将代码中的a替换为对应基址寄存器即可。
方案2:IMUL直接乘法(寄存器紧张时使用)
如果没有多余的临时寄存器可用,可以使用立即数乘法指令直接计算24倍偏移,现代x86-64 CPU上该乘法为单周期指令,性能差距极小:
imul rcx, rbx, 24 ; 直接计算 rcx = rbx * 24 lea rdi, [a + rcx] lea rsi, [rdi + 8]
两种方案均符合x86-64指令集规范,可直接嵌入汇编代码使用。
内容的提问来源于stack exchange,提问作者SRobertJames
相关产品推荐
相关产品推荐

