我需要在x86程序集中将CH
的内容添加到EAX
,但是没有地址模式似乎支持这一点。理想情况下,我想要一个寻址模式,如:
ADD EAX,r8
或
ADD r32,r8
或
ADD r/m32,r8
但ADD
没有任何这些模式。我无法屏蔽ECX
,因为它在我的其他地方使用了其他垃圾,并且我已经用完了所有其他寄存器,所以我唯一的选择似乎是使用内存访问。我有什么想法可以解决这个问题吗?
注意我不能使用像r/m8,r8
这样的模式,因为那样就没有进位。
答案 0 :(得分:3)
我建议您将寄存器泄漏到内存中,在现代处理器上,一对内存访问比分支便宜得多(因为它将从存储缓冲区加载),您可以重新编写其他代码漏油事件。
答案 1 :(得分:2)
使用像r / m8,r8这样的模式,并在必要时通过向EAX添加常量0x100来传播进位。
答案 2 :(得分:2)
如果您泄漏了寄存器,则可以避免分支。如,
subl $4, %esp
使用指令序列:
movl %eax, (%esp)
...
movzbl %ch, %eax
...
addl (%esp), %eax
并在最后恢复堆栈指针:
addl $4, %esp
如果这是一个问题,它可能会对调试此块中的代码的任何尝试造成严重破坏。
或者,按照Doug Currie的建议:
addb %ch, %al
jnc done
addl 0x100, %eax
done:
答案 3 :(得分:1)
重新描述道格的答案(采用英特尔语法):
add al, ch
jnc no_carry
add eax, 100h
no_carry:
答案 4 :(得分:1)
对于eax来说很简单:
add al,ch
adc ah,0
rorx eax,16
adc ax,0
rorx eax,16
在第一条指令中添加下部并保留进位标志,在第二条指令中,将进位标志添加到寄存器的上部。它还保留了源的内容。请注意寄存器停顿,并将代码与其他指令混合以避免它。
加了:
add al,ch
adc ah,0
bswap eax
xchg al,ah
adc ax
xchg al,ah
bswap eax
答案 5 :(得分:0)
您还可以添加32位值并撤消添加24 msb:s:
add eax, ecx
xor cl,cl // also `and ecx, 0xffffff00` is possible
sub eax, ecx
这自然会破坏要添加的值,但会保留垃圾。
(并重新阅读问题,实际上需要用xchg cl,ch
包围代码块,这使得该解决方案不是最佳的。