5 ms·
The cool thing about the address calculation is that there is a LEA instruction (load effective address), which gives you the resulting address. I.e. instead of
by __michaelg 11y ago
The cool thing about the address calculation is that there is a LEA instruction (load effective address), which gives you the resulting address. I.e. instead of actually loading the value from the calculated address in memory, it gives you the address itself without accessing memory. This allows you to do "complex" calculations in just one instruction. This doesn't really help performance-wise in modern CPUs, but it used to in the old 386 days.
- igravious 11y agoYes, a lot of these let's call them `assembler hacks' were true at one time in the x86 32 bit era but are probably not true now. Also, the x86 processor market is quite big now from Pentiums and Core Ms and Core Is and AMD and god knows who else. There used to be assembler books that could teach you all this in the 32 bit era, do these exist for the 64 bit era. It's been a while since I did any low-level bit twiddling.
- _wmd 11y agoAgner Fog's PDFs are the closest thing I know of
- colejohnson66 11y agogcc generates lea instructions still because `lea eax [eax*5]' is a lot shorter than whatever the machine code for multiplying by 5 is.
- pcwalton 11y ago> This doesn't really help performance-wise in modern CPUs, but it used to in the old 386 days. It might if it lets the compiler eliminate temporaries and thereby avoid register spills. This is less important on x86-64, though.
- emily-c 11y agolea also doesn't set any flags which can be pretty useful when interleaving arithmetic operations with other things.
- amluto 11y agoLEA is extremely useful on x86-64 for a different reason: it lets you determine your program counter. 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
- pcwalton 11y ago> I don't know why this is as indirect as it is on x86-32, but this really is what gcc generates. Possibly because the ELF relocs require that exact instruction sequence.