#131 Less efficient code generation than MASM


.model flat

; Exchange of the base and index registers using 'ebp' leads to more
; efficient code. In fact, MASM generates the effective address
; '[esi + ebp]'. See 'modrm' and 'sib' bytes:

; ml v.7.10.3077 | JWasm v2.05
; ----------------+-------------------
mov eax, [ebp + edi] ; 8B042F | 8B443D 00
mov eax, [ebp + esi] ; 8B042E | 8B4435 00
mov dword ptr [ebp + esi], 1234h ; C7042E 00001234 | C74435 00 00001234
mov dword ptr [ebp + edi], 1234h ; C7042F 00001234 | C7443D 00 00001234



  • japheth

    japheth - 2011-03-27

    I see, but I'm unsure whether this optimization is to be regarded as something "good".

    The optimization is ok if SS and DS are "equally assumed" , but AFAICS Masm doesn't care at all about segment register assumes in those cases.

  • Nobody/Anonymous

    He is talking about the generated instruction length. When ebp is used as a base register a displacement byte is also generated. This basically is a result of JWasm generating the sib byte reversed from what MASM does which is [index+base] unless an explicit scale is specified. This is a long standing difference between JWasm and MASM. While the code is semantically the same, using ebp is the one case where generated code is different.

    mov eax,[ebp+edi] ; ebp=index, edi=base

    mov eax,[ebp+edi] ; ebp=base, edi=index

    If you specify a scale then MASM and JWasm generate the same code:
    mov eax,[ebp*1+edi] ;ebp=index, edi=base
    mov eax,[ebp+edi*1] ;ebp=base, edi=index

  • japheth

    japheth - 2011-03-27

    > He is talking about the generated instruction length....

    Thanks, I had understood this aspect. My problem is that I doubt whether this behavior of Masm is worth to be copied.

    IMO an assembler should optimize only if there's no risk of any harm. This is probably not true in this case. Currently I tend to implement this "feature", but optionally ( option -Zg ) only.

  • Nobody/Anonymous

    Option /Zg has no effect on the sib byte generation. Granted it's not clear which should be first when using [reg32+reg32] without an explicit scale specifier but MASM takes the first register as the index while JWasm takes the first register as the base.

    I guess since it's SIB (scale index base) and not SBI, MASM assumes index is first.

  • Terry Philips

    Terry Philips - 2011-03-28

    Just a note: Sounds to me like this could be related to bug# 3074643 (Jwasm prioritizes assumes differently from MASM)

  • japheth

    japheth - 2011-03-28

    > specifier but MASM takes the first register as the index while JWasm takes
    > the first register as the base.

    That's exactly the problem, because the Masm docs tell something differently:

    "if two registers are used, only one can have a scaling factor. The register with the scaling factor is defined as the index register. The other register is defined as the base. If scaling is not used, the first register is the base. If only one register is used, it is considered the base for deciding the default segment unless it is scaled. "

    That's why I tend to assume that there is a small Masm-bug.

    > Just a note: Sounds to me like this could be related to bug# 3074643 (Jwasm
    > prioritizes assumes differently from MASM)

    Nom this issue is already fixed in v2.06.

  • Nobody/Anonymous

    MASM has taken the first register as the index by default since at least MASM 6. I'm pretty sure MASM 5 did this as well so consider it a doc error. Since JWasm is a MASM-compatible assembler it should mimic this behavior. Note this is one of the few cases I've seen where JWasm doesn't generate exactly the same code as MASM does.

  • Peter Kuznetsov

    Peter Kuznetsov - 2011-03-28

    To complement the discussion, give an example in which JWasm unlike MASM generates no displacement:

    mov eax, [esi + ebp]
    mov eax, [esi + ebp] ; 8B042E
    MASM :
    mov eax, [ebp + esi] ; 8B4435 00 - a strange exchange of base and index registers (error?)

    To eliminate the generation of zero displacement, in all cases, except for scaling, EBP should be considered as the index register, and not base. Why bring compatibility to the absolute, repeating all the MASM errors?


  • Nobody/Anonymous

    It's not an error, it a matter of interpretation:

    mov eax, [esi + ebp]
    mov eax, [ebp + esi]

    are logically the same, the difference is the SIB byte generated. This is only an issue when ebp is involved since ebp as a base register will generate a displacement.

  • japheth

    japheth - 2011-03-29

    > I'm pretty sure MASM 5 did this as well so consider it a doc error.

    No, Masm 5x does what the docs are telling.
    In the Masm docs there's even an example, chapter "Indirect Memory Operands":

    mov eax, [edx][ebp] ; EDX base (first - seg DS)
    mov eax, [ebp][edx] ; EBP base (first - seg SS)

    So I regard this issue a bug in Masm v6+, which JWasm shouldn't copy - perhaps unless option -Zg is set.

  • Nobody/Anonymous

    Why would you want to copy the behavior of MASM 5.x ?

    Anyway if you look in volume 2A of the Intel manuals, there's a table at the very end of chapter 2 listing the SIB bytes. Under the table you'll find a note with the following:

    [scaled index] + disp32
    [scaled index] + disp8 + [EBP]
    [scaled index] + disp32 + [EBP]

    So Intel is suggesting the index is first. Since it's Intel's architecture I'd say they're right.

  • japheth

    japheth - 2011-03-30
    • priority: 5 --> 1
  • japheth

    japheth - 2011-03-30

    > So Intel is suggesting the index is first.

    I prefer the Masm documentation - because that's what I intuitively feel is correct :)).

    Priority changed to 1.

  • japheth

    japheth - 2012-09-01

    in v2.08, the -Zg cmdline option will now copy Masm v6 behavior, that is, the second register becomes the base. See jwasm's manual.html, -Zg option.

    the standard jwasm code generation is unchanged.

    status changed to pending.

  • japheth

    japheth - 2012-09-01
    • status: open --> pending
  • dosfan01

    dosfan01 - 2013-04-21

    Since JWasm v2.10 now copies MASM 6.0+ SIB byte generation behavior this is no longer an issue and can likely be closed.

    • Peter Kuznetsov

      Peter Kuznetsov - 2013-04-21

      Please, close it yourself. I can't find the button for it. Thank you.

  • japheth

    japheth - 2013-04-21
    • Description has changed:


    --- old
    +++ new
    @@ -1,4 +1,3 @@
     .model flat                  
    • status: pending --> closed
    • Group: --> v210
  • japheth

    japheth - 2013-04-21

    Issue is fixed with v2.10 - JWasm copies Masm 6 behavior.


Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks