I have assembled the (somewhat weird) instruction ADD EAX, DWORD PTR [RBP + RAX]
with GCC, FASM and NASM. All of them produce the following output
0: 03 44 05 00 add eax,DWORD PTR [rbp+rax*1+0x0]
The 0x0
displacement is added since RBP may not be used as base register without it.
However, the same instruction could – as far as I can tell – be encoded as
0: 03 04 28 add eax,DWORD PTR [rax+rbp*1]
Base and Index registers are swapped here, which works as long as the scale is 1.
I would understand if this was an optimization these assemblers just don’t do, but that’s not the case either.
For example, NASM and FASM turn ADD EAX, DWORD [RBP + RSP*1]
into
0: 03 04 2c add eax,DWORD PTR [rsp+rbp*1]
Here, base and index registers were swapped, allowing for the SIB encoding without a displacement.
Is this just an optimization these assemblers don’t do, or is there a reason why they chose not to?