32-bit x86 has 2 redundant ways to encode [disp32]
(with no registers): with and without a SIB byte. Assemblers will of course always use the shorter form, and that's what the link in your question is showing.
You're disassembling as 64-bit machine code.
x86-64 repurposed the without-SIB version to mean [RIP + rel32]
, leaving the longer with-SIB version to still mean [sign_extended_disp32]
like when you use a disp32 with GP registers. (RIP-relative is not available combined with any GP registers; only this one specific ModR/M encoding.)
In NASM syntax, [rel foo]
vs. [abs foo]
, or use default rel
.
AFAIK, lea r32, [disp32]
instead of mov r32, imm32
is never useful for performance on any CPU I'm aware of, except to make an instruction longer on purpose instead of padding with NOP.
The only use-case for lea
for static addresses is in 64-bit code with RIP-relative LEA.
See this canonical answer for more about LEA, but really this question has nothing to do with LEA specifically, and would have happened with any instruction that used a disp32
ModR/M addressing mode decoded in the wrong mode. You only ran into this because you found an example that compared using an inefficient lea
with an efficient mov
-immediate in 32-bit mode.