2

I have to prove that JL and JNGE are the same and specifically both mean

" if (left op < right op) then jump "

I can see some features from University lecture resources and stackoverflow giving thoughts about the question. (http://ee.usc.edu/~redekopp/cs356/slides/CS356Unit5_x86_Control.pdf and Why does x86 have the redundant JNGE instruction?)

But what I see on official document like oracle x86 assembly reference doc and so, just saying both JL and JNGE share the same operation, SF <> OF.

I rather want to provide some official doc that " < " is given.

What I'm doing now is to show SF <> OF means " < " though.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
sy choi
  • 43
  • 1
  • 6

1 Answers1

4

If two mnemonics assemble to the same opcode, by definition the machine will run them the same way. The CPU can only see the machine code, not the asm source. (You won't see < in the asm docs because that only applies if FLAGS were set by cmp or sub.)

And yes, https://www.felixcloutier.com/x86/jcc scraped from Intel's official PDFs (https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html) confirms that JL is "Jump short if less (SF≠ OF)."

Probably somewhere in Intel's Vol.1 they explain how cmp + JCC makes mnemonics match the "semantic meaning" they're named for. See also Assembly - JG/JNLE/JL/JNGE after CMP


As for the FLAGS setting, cmp x, y is like x - y just setting FLAGS. The result will be negative (SF set) if y is a larger number, unless you have signed overflow. See http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt for details on how OF is set by subtraction.

Note that subtraction of two equal-width numbers can only overflow once, not overflow and wrap all the way around back to negative (or the same sign as the correct result).

  • if SF=1 and there was no overflow, x-y < 0 so x < y .
  • if SF=0 and there was no overflow, x-y >= 0 so it's not true that x < y
  • If there was overflow, SF is opposite of the sign-bit of the correct result. (That's exactly what signed overflow is, see the linked guide). SF != OF is the XOR of those two bits: flip SF to find the sign of the correct result and consult the appropriate one of the no-overflow cases.

So we can prove that SF != OF is the right condition for cmp eax, edx / jl to be taken iff eax < edx (signed). Combined with the official documentation that describes their operation as jump if SF != OF, yes, we've proved that JL (and JNGE) match their mnemonics. If you want to flesh that out into a more rigorous proof with definitions of exactly what OF means, you can.


If you run jl after a different instruction, like add eax, edx, it will still check those flags, but the way they're set won't have anything to do with one being less than the other. That's why < isn't an inherent part of jl itself, just of what happens if you use it after cmp. (Or after test eax,eax, which sets FLAGS identically to cmp eax, 0, i.e. an implicit compare against zero, like for any operation that always clears OF, and sets SF and ZF according to the result.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • It was about my mid term exam. I gave JL and JNGE for the queation 'conditional jump that works when left op < right op', and they said it's wrong because JNGE includes "equal". I did other research too and provided some proofs. They finally took it as a correct answer.Thank you. – sy choi Apr 28 '21 at 13:52
  • 3
    @sychoi: lol, yeah, JNGE is jump if `NOT (G or E)`, not `(NG) or E`. Congrats on showing the markers the obvious, well-known, and well-documented fact that JNGE is a synonym of JL. (I mean, mistakes happen, that's fine, but I would have expected anyone to recognize it right away after it's pointed out in terms of sharing an opcode; hopefully they didn't resist for too long or it was about some other issue). Interestingly, it doesn't look at ZF at all, just like the simpler unsigned jb / jnae conditions, aka jc. But JG aka JNLE does to look at ZF while JGE / JNL doesn't. – Peter Cordes Apr 28 '21 at 14:05
  • 2
    @sychoi: Integer comparisons have 3 possible results: `<`, `==`, or `>`. (FP introduces unordered as a 4th possibility). `<` excludes `==` and `>`, so it's `!(x >= y)`. – Peter Cordes Apr 28 '21 at 14:10