Author Topic: CMP defeats intuition  (Read 3987 times)

jj2007

  • Member
  • *****
  • Posts: 11135
  • Assembler is fun ;-)
    • MasmBasic
CMP defeats intuition
« on: August 14, 2013, 10:46:11 PM »
A spin-off from the Comparing 128-bit numbers aka OWORDs thread.

Uppercase in flags means "set":

cmp eax, edx
eax             -1
edx             1
flags:          czSo
ecx             -2


So far, so clear: Sign? is set, because eax=-1 is obviously below edx=+1

cmp eax, edx
eax             -2013265784
edx             1996488823
flags:          czsO
ecx             285212689


Oops :redface:
eax=-2013265784, edx=+1996488823, and Sign? is clear??

cmp eax, edx
jl IsLower


"If eax is below edx, then jump to the IsLower branch"

Nope... the documentation says "cmp sets flags like sub but it doesn't subtract". And eax minus edx is ecx=285212689 in this case, so the cmp says "positive".

I'll add it to Tips, Tricks & Traps...


include \masm32\MasmBasic\MasmBasic.inc        ; download
  Init
  mov eax, -1        ; clearly below zero
  mov edx, 1        ; clearly above zero
  mov ecx, eax        ; create a copy
  sub ecx, edx        ; "cmp with action"
  cmp eax, edx
  deb 4, "cmp eax, edx, result in ecx", ecx, eax, edx, x:eax, x:edx, flags

  mov eax, 88000088h        ; clearly below zero
  mov edx, 77000077h        ; clearly above zero
  mov ecx, eax
  sub ecx, edx
  cmp eax, edx
  deb 4, "cmp eax, edx, result in ecx", ecx, eax, edx, x:eax, x:edx, flags
  Inkey CrLf$, 'uppercase in flags means "set"'
  Exit
end start

qWord

  • Member
  • *****
  • Posts: 1476
  • The base type of a type is the type itself
    • SmplMath macros
Re: CMP defeats intuition
« Reply #1 on: August 14, 2013, 11:18:08 PM »
What exactly is the problem? The sign flag comes from the result of an operation and not from it's source operands.
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

  • Member
  • *****
  • Posts: 11135
  • Assembler is fun ;-)
    • MasmBasic
Re: CMP defeats intuition
« Reply #2 on: August 14, 2013, 11:24:50 PM »
Yes, I have understood that. But using "normal" language, it would appear that "less" as in jl means "less" and not "the sign of the result of a subtraction". That is what I call counterintuitive.

eax=-..., edx=+...

cmp eax, edx
jl IsLower

"If eax is lower than edx, then jump to the IsLower branch" - wrong :(

dedndave

  • Member
  • *****
  • Posts: 8829
  • Still using Abacus 2.0
    • DednDave
Re: CMP defeats intuition
« Reply #3 on: August 14, 2013, 11:27:40 PM »
for signed branches, it looks for SF=OF
Code: [Select]
****************************************************************
Equality Branches (Used for Signed or Unsigned Comparisons)
----------------------------------------------------------------
Instruction  Description               Condition       Aliases
----------------------------------------------------------------
JZ           Jump if equal             ZF=1            JE
JNZ          Jump if not equal         ZF=0            JNE
****************************************************************

****************************************************************
Unsigned Branches
----------------------------------------------------------------
Instruction  Description               Condition       Aliases
----------------------------------------------------------------
JA           Jump if above             CF=0 and ZF=0   JNBE
JAE          Jump if above or equal    CF=0            JNC JNB
JB           Jump if below             CF=1            JC JNAE
JBE          Jump if below or equal    CF=1 or ZF=1    JNA
****************************************************************

****************************************************************
Signed Branches
----------------------------------------------------------------
Instruction  Description               Condition       Aliases
----------------------------------------------------------------
JG           Jump if greater           SF=OF or ZF=0   JNLE
JGE          Jump if greater or equal  SF=OF           JNL
JL           Jump if less              SF<>OF          JNGE
JLE          Jump if less or equal     SF<>OF or ZF=1  JNG
JO           Jump if overflow          OF=1
JNO          Jump if no overflow       OF=0
JS           Jump if sign              SF=1
JNS          Jump if no sign           SF=1
****************************************************************

jj2007

  • Member
  • *****
  • Posts: 11135
  • Assembler is fun ;-)
    • MasmBasic
Re: CMP defeats intuition
« Reply #4 on: August 15, 2013, 11:23:06 AM »
for signed branches, it looks for SF=OF
JL           Jump if less              SF<>OF

Interesting, Dave. Unfortunately, there is no
   .if Sign? != OverFlow?
   .endif

I know you prefer the plain mnemonics, but jl @F is a no-no in macros 8)
It can be done, though, using a label counter; check for oqCt in MasmBasic.inc (as of today 15 August, the Qcmp and Ocmp macros are included in MasmBasic, see here).
« Last Edit: August 15, 2013, 12:30:36 PM by jj2007 »

dedndave

  • Member
  • *****
  • Posts: 8829
  • Still using Abacus 2.0
    • DednDave
Re: CMP defeats intuition
« Reply #5 on: August 15, 2013, 12:29:52 PM »
the JL JG works great in .IF syntax
you just have to use SDWORD PTR
Code: [Select]
    .if sdword ptr eax<0
        ;do whatever
    .endif

the one i am trying to figure out is JBE   :biggrin:

well - i can do JBE (.if eax<=something)
but......
i often like to perform a SUB, then .if FLAGS?
.if CARRY? gets you JB
.if ZERO? gets you JZ
but, there is no single flag test for JBE

for the moment, i DEC then check for sign

jj2007

  • Member
  • *****
  • Posts: 11135
  • Assembler is fun ;-)
    • MasmBasic
Re: CMP defeats intuition
« Reply #6 on: August 15, 2013, 12:33:54 PM »
the JL JG works great in .IF syntax
you just have to use SDWORD PTR
Code: [Select]
    .if sdword ptr eax<0
        ;do whatever
    .endif

OK if you do the comparison, but not helpful if you got the flag only, e.g. after a pop eax.
For a workaround in macros, see my edit in the post before regarding labels.