Assembly Is Too High Level: SIB Doubles
xlogicx.net
xlogicx.net
It might if it lets the compiler eliminate temporaries and thereby avoid register spills. This is less important on x86-64, though.
For example, imagine you have code like this:
static int foo;
int *func(void) { return &foo; }
If you build it as position-independent code, on x86-64, you get: leaq foo(%rip), %rax
ret
Here, "foo" turns into the offset from the end of the LEA instruction to the variable foo. The x86 address calculation engine does the rest.On x86-32, there's no IP-relative addressing, so you can't use LEA like this, and you get a mess, which I've trimmed into readability:
; x86-32 has no instruction that reads EIP. Fake it.
__x86.get_pc_thunk.ax:
movl (%esp), %eax
ret
func:
call __x86.get_pc_thunk.ax ; <-- this sucks
addl $_GLOBAL_OFFSET_TABLE_, %eax
leal foo@GOTOFF(%eax), %eax <-- ???
ret
I don't know why this is as indirect as it is on x86-32, but this really is what gcc generates. The ??? is a GOT reference.Edit: fixed formatting
Possibly because the ELF relocs require that exact instruction sequence.
Since the result of the xor is never read and immediately overwritten by the following mov, I wonder if clever register renaming could actually detect that and discard the instruction.
Oh, and cool article btw. I think I have a hazy recollection from a long long time ago Microsoft assembler would do the same -- as in pick the smallest machine opcode in the case of multiple assembler possibilities.
Those were the days...