How to add CH to EAX in x86 assembly?

I need to add the contents of CH to EAX in x86 assembly, but there is no address mode that seems to support this. Ideally, I need an addressing mode, for example:

 ADD EAX,r8 

or

 ADD r32,r8 

or

 ADD r/m32,r8 

But ADD does not have any of these modes. I cannot mask ECX because it has another junk file that I use elsewhere and I used all my other registers, so my only option is to use memory access. Any ideas how I can solve this problem?

Note. I can’t use a mode like r/m8,r8 , because there will be no transfer.

+4
source share
6 answers

x86 simply does not have such flexible addressing modes as you noticed. You cannot add an 8-bit register to a 32-bit register in one step. Your options: either free the case, or specify a zero / sign, then add r32, r32 or add r8, r8, and then expand the carry flag to adjust the result.

I would advise you to skip the register into memory, in a modern processor a couple of memory accesses are much cheaper than a branch (since it will be loaded from the storage buffer), and you can probably change your other code around the spill.

+3
source

Use a mode such as r / m8, r8, and if necessary transfer the transfer by adding the constant 0x100 to EAX.

+2
source

If you spill case, you can avoid branching. eg.

 subl $4, %esp 

use the sequence of commands:

 movl %eax, (%esp) ... movzbl %ch, %eax ... addl (%esp), %eax 

and restore the stack pointer at the end:

 addl $4, %esp 

This can lead to chaos with any attempts to debug the code inside this block if this is a problem.


Or, following Doug Curry's suggestion:

 addb %ch, %al jnc done addl 0x100, %eax done: 
+2
source

To paraphrase Doug's answer (in Intel syntax):

  add al, ch jnc no_carry add eax, 100h no_carry: 
+1
source

It is simple, for eax:

 add al,ch adc ah,0 rorx eax,16 adc ax,0 rorx eax,16 

In the first instruction, you add the lower part and save the carry flag; in the second command, you add the carry flag to the upper part of the register. It also saves the content of the source. Beware of registrars, and mix code with other instructions to avoid this.
Added:

 add al,ch adc ah,0 bswap eax xchg al,ah adc ax xchg al,ah bswap eax 
+1
source

You can also add 32-bit values ​​and undo the addition of 24 msb: s:

  add eax, ecx xor cl,cl // also `and ecx, 0xffffff00` is possible sub eax, ecx 

This naturally destroys the added value, but saves the garbage. (And re-reading the question, it is actually necessary to surround the code block xchg cl,ch , which makes the solution not optimal for the task.)

0
source

All Articles