Search code examples
assemblyx86nasminstructionsopcode

Does [ebp*2] reference DS or SS segment?


IDM says the memory op uses SS segment if EBP is used as base register. As a result, [ebp + esi] and [esi + ebp] references SS and DS segments, respectively. See NASM's doc: 3.3 Effective Address.

In the above same section, NASM mentioned how to generate shorter machine code by replacing [eax*2] with [eax+eax].

However, NASM also generates [ebp + ebp] for [ebp*2] (i.e. no base register).

I suspect [ebp+ebp] references SS segment, and [ebp*2] references DS segment.

I asked NASM this question. They think [ebp*2] and [ebp+ebp] are the same, but it doesn't make sense to me. Obviously, [ebp+ebp] (ebp as base register) references SS segment. If they're the same, [ebp*2 must reference SS too. This means SS is referenced as long as ebp is the base or index register, which in turn means, both [ebp + esi] and [esi + ebp] reference SS segments, so they must be the same.

Does anyone know which segment [ebp*2] uses?


Solution

  • The Intel manual tells us below figure 3-11, which deals with Offset = Base + (Index * Scale) + Displacement:

    The uses of general-purpose registers as base or index components are restricted in the following manner:

    • The ESP register cannot be used as an index register.
    • When the ESP or EBP register is used as the base, the SS segment is the default segment. In all other cases, the DS segment is the default segment.

    This means that NASM is wrong when it changes [ebp*2] into [ebp+ebp] (in order to avoid the 32bit displacement).

    [ebp*2] uses DS because ebp is not used as base
    [ebp+ebp] uses SS because one of the ebp is used as base

    It would then be best to specify that you don't want this behaviour from NASM.
    Until the time NASM authors realize their mistake, you can disable this behaviour (where EBP is used as an index) by writing:

    [NoSplit ebp*2]