如何在x86汇编中将CH添加到EAX?

时间:2013-04-03 18:21:23

标签: assembly x86 cpu-registers

我需要在x86程序集中将CH的内容添加到EAX,但是没有地址模式似乎支持这一点。理想情况下,我想要一个寻址模式,如:

ADD EAX,r8

ADD r32,r8

ADD r/m32,r8

ADD没有任何这些模式。我无法屏蔽ECX,因为它在我的其他地方使用了其他垃圾,并且我已经用完了所有其他寄存器,所以我唯一的选择似乎是使用内存访问。我有什么想法可以解决这个问题吗?

注意我不能使用像r/m8,r8这样的模式,因为那样就没有进位。

6 个答案:

答案 0 :(得分:3)

正如您所观察到的,x86只是没有这种灵活的寻址模式。您无法在一个步骤中将8位寄存器添加到32位寄存器。你的选择是释放一个寄存器和零/符号扩展然后添加r32,r32,或者添加r8,r8然后在进位标志上进行分支以调整结果。

我建议您将寄存器泄漏到内存中,在现代处理器上,一对内存访问比分支便宜得多(因为它将从存储缓冲区加载),您可以重新编写其他代码漏油事件。

答案 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包围代码块,这使得该解决方案不是最佳的。