Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在x86程序集中向EAX添加CH?_Assembly_X86_Cpu Registers - Fatal编程技术网

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