IDA disassembled an x86-64 instruction as below:

0000000000000761                 lea     rdx, ds:0[rax*4]

What I know is, segment registers are only relevant in in segmented memory model, while in case of paging they hold an index in GDT/LDT. Why is the above instruction, out of nowhere, referring to the ds segment register?

  • Ubuntu 18.04, 64 bit – Holmes.Sherlock Dec 15 '18 at 15:25
  • The fact that you are not using a segmented memory model doesn’t mean the instruction encoding doesn’t allow you to specify the segment :) Basically on x86_64 the only relevant segment is gs, but a disassembler might still show other segment registers (implicitly) encoded in instructions... – mrexodia Dec 18 '18 at 20:34

Segments are still used on 64 bit long mode and are still set up, except the CPU treats their bases to be 0 (except for gs and fs), and does not perform a limit check. The default segment for rax is indeed ds, but this can be changed with a segment override. lea rdx, ds:0[rax*4] is lea rdx, ds:[rax*4 + 0], which is lea rdx, ds:[rax*4], which is the same as lea rdx, [rax*4] in that when that instruction is executed, the AGU uses the ds segment descriptor by default for rax to perform privilege checks, but not limit or base checks. This segment descriptor is either renamed and is placed in the reservation station (and hence it is the job of the decoder and allocator to use the correct segment descriptor based on the prefix override or lack thereof) or is internal to the AGU and the AGU uses the uop opcode which might encode the segment to use. I have also seen lea rdx, [ds:rax] notation, which is the same thing as lea rdx, ds:[rax], but the problem is lea rdx, [ds:rax*4] would be semantically misleading, as on x86 you can only do lea rdx, ds:[rax*4]. I believe that gs:[0x32], gs:0x32 and [gs:0x32] all represent the same thing in x86 assemblies / disassemblies, for instance gs:0x32 does not mean 'get the calculated linear address of gs:0x32', because we have lea for that, and gs:[0x32] does not mean 'get the address at value at ds:[0x32] and then use that as an offset into gs and get the calculated linear address', therefore the other 2 forms can safely represent [gs:0x32], and as mentioned gs:[...] is more clear as it acts as precedence demarcation when a scale or index is involved

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.