如何在不支持ADCX/ADOX的平台上将其转换为ADC等汇编指令?
ADCX/ADOX 转 ADC 指令的实现方案
核心原理说明
ADCX 和 ADOX 是 Intel 专为大整数运算设计的指令:
- ADCX:仅使用**进位标志(CF)**作为进位输入,运算后更新CF,不干扰溢出标志(OF)
- ADOX:仅使用**溢出标志(OF)**作为进位输入,运算后更新OF,不干扰CF
普通ADC指令会同时使用CF作为输入,且运算后同时更新CF和OF,因此单ADCX场景可直接替换,混合场景则需手动拆分两条进位链,通过标志位保存/恢复来模拟ADOX的行为。
场景1:仅ADCX指令的转换(FirstLoop)
原代码
; FirstLoop mov rdx,[rsi + 0] mulx rax,r11,[rcx] mulx r8,r12,[rcx +8] adcx r12,rax mulx rax,r13,[rcx +16] adcx r13,r8 mulx r8,r14,[rcx +24] adcx r14,rax mov r15,r10 adcx r15,r8
转换后代码
此场景仅依赖CF进位链,ADCX可直接替换为普通ADC指令,功能完全等价:
; FirstLoop (转换后,兼容无ADCX的平台) mov rdx,[rsi + 0] mulx rax,r11,[rcx] mulx r8,r12,[rcx +8] adc r12,rax mulx rax,r13,[rcx +16] adc r13,r8 mulx r8,r14,[rcx +24] adc r14,rax mov r15,r10 adc r15,r8
场景2:ADCX与ADOX混合使用的转换(SecondLoop)
原代码
; SecondLoop mov rdx,r9 mulx rax,rdx,r11 mulx r8,rax,[q] adcx rax,r11 mulx rax,r11,[q +8] adcx r11,r8 adox r11,r12 mulx r8,r12,[q +16] adcx r12,rax adox r12,r13 mulx rax,r13,[q +24] adcx r13,r8 adox r13,r14 mov r14,r10 adcx r14,rax adox r14,r15
转换思路
ADOX依赖OF作为进位链,需通过保存/恢复标志位、手动计算进位来模拟:
- 执行ADOX前,先保存当前OF标志到寄存器
- 用普通ADD完成加法,再结合原OF计算新的进位值
- 重新设置OF标志,确保ADCX对应的CF进位链不受干扰
转换后代码
; SecondLoop (转换后,兼容无ADCX/ADOX的平台) mov rdx,r9 mulx rax,rdx,r11 mulx r8,rax,[q] adc rax,r11 ; 替换ADCX为ADC,沿用CF进位链 mulx rax,r11,[q +8] adc r11,r8 ; 替换ADCX为ADC ; 模拟ADOX r11,r12 pushfq ; 保存当前标志寄存器 pop rbx and rbx, 0x0800 ; 提取OF标志位(第11位) shr rbx, 11 ; 将OF转为0/1的进位值 add r11, r12 ; 执行加法操作 adc rbx, 0 ; 计算新进位:原OF + 加法产生的CF shr rbx, 1 ; 得到更新后的OF值 pushfq pop rcx and rcx, ~0x0800 ; 清除原有OF位 or rcx, rbx << 11 ; 设置新的OF位 push rcx popfq ; 恢复标志寄存器 mulx r8,r12,[q +16] adc r12,rax ; 替换ADCX为ADC ; 模拟ADOX r12,r13 pushfq pop rbx and rbx, 0x0800 shr rbx, 11 add r12, r13 adc rbx, 0 shr rbx, 1 pushfq pop rcx and rcx, ~0x0800 or rcx, rbx << 11 push rcx popfq mulx rax,r13,[q +24] adc r13,r8 ; 替换ADCX为ADC ; 模拟ADOX r13,r14 pushfq pop rbx and rbx, 0x0800 shr rbx, 11 add r13, r14 adc rbx, 0 shr rbx, 1 pushfq pop rcx and rcx, ~0x0800 or rcx, rbx << 11 push rcx popfq mov r14,r10 adc r14,rax ; 替换ADCX为ADC ; 模拟ADOX r14,r15 pushfq pop rbx and rbx, 0x0800 shr rbx, 11 add r14, r15 adc rbx, 0 shr rbx, 1 pushfq pop rcx and rcx, ~0x0800 or rcx, rbx << 11 push rcx popfq
内容的提问来源于stack exchange,提问作者zkbitcoin.com
相关产品推荐
相关产品推荐

