Assembly 如何在x86程序集中向EAX添加CH?
我需要将Assembly 如何在x86程序集中向EAX添加CH?,assembly,x86,cpu-registers,Assembly,X86,Cpu Registers,我需要将CH的内容添加到x86汇编中的EAX,但没有显示支持此操作的地址模式。理想情况下,我希望采用如下寻址模式: ADD EAX,r8 或 或 但是ADD没有任何这些模式。我不能屏蔽ECX,因为它有我在别处使用的其他垃圾,并且我已经用完了所有其他寄存器,所以我唯一的选择似乎是使用内存访问。有没有办法解决这个问题 注意:我不能使用像r/m8、r8这样的模式,因为这样就没有进位。使用像r/m8、r8这样的模式,并在必要时通过向EAX添加一个常量0x100来传播进位。x86只是没有像您所观察到的那
CH
的内容添加到x86汇编中的EAX
,但没有显示支持此操作的地址模式。理想情况下,我希望采用如下寻址模式:
ADD EAX,r8
或
或
但是ADD
没有任何这些模式。我不能屏蔽ECX,因为它有我在别处使用的其他垃圾,并且我已经用完了所有其他寄存器,所以我唯一的选择似乎是使用内存访问。有没有办法解决这个问题
注意:我不能使用像r/m8、r8这样的模式,因为这样就没有进位。使用像r/m8、r8这样的模式,并在必要时通过向EAX添加一个常量0x100来传播进位。x86只是没有像您所观察到的那样灵活的寻址模式。不能在一个步骤中将8位寄存器添加到32位寄存器。您可以选择释放寄存器和零/符号扩展,然后添加r32、r32,或者添加r8、r8,然后在进位标志上分支以调整结果
我建议您应该将寄存器溢出到内存中,在现代处理器上,一对内存访问比一个分支便宜得多(因为它将从存储缓冲区加载),并且您可能可以重写溢出周围的其他代码。如果溢出寄存器,您可以避免分支。e、 g
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:
还可以添加32位值并撤消添加24个msb:s:
add eax, ecx
xor cl,cl // also `and ecx, 0xffffff00` is possible
sub eax, ecx
这自然破坏了要增加的价值,但保留了垃圾。
(重读这个问题,实际上需要在代码块周围加上xchg cl,ch
,这使得解决方案不适合任务。)重新表述Doug的答案(英特尔语法):
对于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
是时候使用x64并获得这些额外的寄存器了。:)帮助您释放更多寄存器,使函数调用更快,并生成更小的代码,以换取更困难的调试。但是无论如何,使用64位是更好的。上面的代码不是和“push eax”(后面是“pop eax”)一样吗?是的-但是我不知道循环中是否需要这个,所以我想我应该明确它。但是只适用于haspwell(宏用于短循环而不带进位版本,需要1个循环)。。。其他选项是bswap,XCHG间接跳转的惩罚可能比指令量更大,因此使用更多指令是有意义的
add al, ch
jnc no_carry
add eax, 100h
no_carry:
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