How can I move like: MOV EAX, EBX without using the MOV operator?
CodePudding user response:
You can use lea with a simple register addressing mode as a slower mov (no mov-elimination and runs on fewer ports on Intel before Ice Lake), although it's still one instruction.
# nasm -f elf64 foo.asm && objdump -drwC -Mintel foo.o
0000000000000000 <.text>:
0: 89 c8 mov eax,ecx
2: 8d 01 lea eax,[rcx] # in 64-bit code,
4: 67 8d 01 lea eax,[ecx] # don't use 32-bit address size
As well as being slower, it takes extra code size for some registers (RSP/R12, and RBP/R13). (I used 64-bit operand-size so they'd all need REX prefixes, so for example RSP and R12 machine code lines up because they both need to use a SIB byte.
10: 48 89 fe mov rsi,rdi
13: 48 8d 37 lea rsi,[rdi]
16: 48 8d 34 24 lea rsi,[rsp]
1a: 49 8d 34 24 lea rsi,[r12]
1e: 48 8d 75 00 lea rsi,[rbp 0x0] # source had just [rbp]
22: 49 8d 75 00 lea rsi,[r13 0x0]
The same thing is of course possible in other modes, using lea eax, [ecx] as a 2-byte instruction. (Or 4 bytes in 16-bit mode for 32-bit registers. Even if you only want 16-bit registers, 16-bit mode needs 32-bit address size for source registers other than [bx|bp] [si|di] because of 16-bit addressing mode encoding limitations.)
push/pop is also an option, making it possible to copy a 64-bit register in only 2 bytes of machine code, instead of the usual 3:
30: 52 push rdx
31: 58 pop rax
32: 48 89 d0 mov rax,rdx
35: 48 8d 02 lea rax,[rdx]
This is useful for code-golf.
Other silly computer tricks include immediate imul by 1.
40: 6b f1 01 imul esi,ecx,0x1
Or if you want to consider multiple instructions, you could xor-zero the destination and add, or, or xor into it like Yuri suggests. Zero is the identity element for , | and ^.
Even less efficient would be to AND into all-ones, the identity element for &. (False dependency on the old value of EAX, and it's not xor-zeroing so it can't be eliminated (no execution unit) the way Sandybridge-family CPU do. Also larger code-size)
or eax, -1
and eax, ecx
CodePudding user response:
First, clean the data on one register XOR EAX, EAX, then perform OR EAX, EBX
