Strangely enough, the position 096B3D47 is just a few lines above the above excerpt...
... and the instruction before that address is a
call instruction. Right?
This kind of instructions is used for position-independend code: The code can be loaded into another address and it will work the same way without modifications. Typically it works like this:
call some_address ; 1
pop ebx ; 2
lea eax, (some_text - some_address)[ebx] ; 3
- After the
call instruction the address of the instruction after the
call instruction will have been pushed to the stack. This means that the address
some_address is now on the stack.
pop we read the address of
some_address from the stack (and remove it from there).
- This instruction will calculate
some_text - some_address + someaddress so the instruction has the same effect as
lea eax, [some_text].
some_text - some_address is always the same when the executable file is loaded into different memory addresses. Therefore the
lea instruction will work independently on the location (address) where the program is executed.
The same is true for the
call instruction because the argument of the
call instruction is stored PC-relative.
The argument of the instruction
lea eax, [some_text] however would be an absolute (not a PC-relative) address so you would have to exchange it when executing the program at another address.
For me it reads like "the symbol at 0x96B3D47 bytes prior to the symbol table index".
If there is a relocation table entry for the
lea instruction the disassembler could take the information from the relocation table.
In your case this seems to be different:
Your disassembler seems also to be intelligent enough to see that
ebx contains the address 096B3D47 at this point. Therefore it will know that the instruction
lea eax, XYZ[ebx] will result in a value of
096B3D47+XYZ in the
Therefore it will disassemble the instruction as
lea eax, ((XYZ+096B3D47)-096B3D47)[ebx] and tries to find out what symbol the address
Many disassemblers I know however only guess here; they assume that the address belongs to the last symbol before that address. And in your case the symbol
stru_8199A2C.st_shndx seems to be that symbol.
Obviously your disassembler does not only evaluate symbols but also debugging information such as "Dwarf" debugging data (which contains information used by debuggers).