1

What is meant by writing the following lines?

OR AX,AX

JGE LABEL

To my knowledge, OR is not a comparison operator. And, Branching statements like, "JGE/JE/JL" can only be used only when I have used them after any Comparison process by CMP.

melpomene
  • 79,257
  • 6
  • 70
  • 127
  • You may need to read the description of `jge`. Conditional branches do not require the preceding instruction to be `cmp`. – melpomene May 06 '18 at 05:37
  • @peter-cordes I don't think this question is duplicated in that previous question (or in the other duplicate). The question here isn't about `test` vs `or` and it's not about a zero test. – D.Go May 07 '18 at 16:55
  • @D.Go I still think it *is* a duplicate. `or ax,ax` sets flags identically to `test ax,ax` or `cmp ax,0`, as explained in my answers on both questions. – Peter Cordes May 07 '18 at 23:59
  • @peter-cordes Agreed, the questions are closely related. Your description of the flags is great for an expert but it's in a different context that doesn't explain the interrelation between jumps and flags. That makes it very difficult for someone unfamiliar (as in this case) to derive an answer. The question here is "what do these two lines do?". So, I think it necessary to explain the code in its own context - namely, that it is checking positive/zero vs negative (_not_ zero vs non-zero). – D.Go May 08 '18 at 01:53
  • @D.Go: The OP already understands that cmp/jge works (IDK if they understand *why* it works, but it says right in the question that they were expecting cmp). This is a duplicate because `or ax,ax` works identically to `cmp ax,0`, and you can think of it that way whether you understand flags or not (for ALL flags, except maybe AF), not just ZF. That's exactly what my answer says (plus the details about flags), and with this comment that's plenty for a duplicate. I could probably dig up another duplicate about basics of why `cmp` works in the first place and how x86 flags work... – Peter Cordes May 08 '18 at 07:06
  • 1
    @PeterCordes I still think there is room for a question like this where the asker doesn't understand the foundation and needs help to connect the dots. But that's just my opinion and it's not important. Thanks for taking the time to respond (both to the question and my comments) and for explaining your viewpoint. It's appreciated! :) – D.Go May 08 '18 at 17:44

2 Answers2

4

It's an alternative to cmp ax, 0 to set FLAGS according to a value,
but the preferred way which also does the same thing is test ax,ax.


or instruction is bitwise operation, not comparison, so you are right in the first thing.

But about branching you are completely wrong, the conditional jump Jcc doesn't care what instruction was executed before it, it will only check the flag register EFLAG for certain conditions. (basically no instruction in CPU cares about previous instruction, it's state machine and each instruction is well defined how it will modify current state of CPU, and state of CPU is content of registers (but all of them, segment registers, also (E)FLAG is register and there are few control registers, and on modern x86 CPU also the FPU and MMX/SSE unit registers).

And the or will modify flag registers too, as many other instructions:

The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result. The state of the AF flag is undefined.

And the JGE is:

Jump short if greater or equal (SF=OF).

The OF will be zero after OR, and SF will be equal to the top bit of ax (for values 0x0000 .. 0x7FFF it will be 0, for values 0x8000 .. 0xFFFF it will be 1). So the branching jump will be executed when ax is value from range 0 .. 0x7FFF (32767).

It's the common, but unoptimal idiom for testing register against zero, the better way is test ax,ax, which is again bitwise operation (and), but the results is discarded, and only flags are modified, modern x86 CPUs understand this idiom and it has the same or better performance than cmp ax,0. The OR may internally store the result of operation back into ax, which may result in less optimal performance than test.

You can use the conditional jump any time, it will check the value in FLAGS register, so one old optimization from Pentium-like era was to do CMP few instructions ahead to give CPU time to write the change to FLAGS and execute between some instructions not affecting flags (like MOV and similar), but on modern x86 this is counter-performance measure, as modern unit will upon decoding pair of instructions cmp something jge label treat them in special way, sort of as single operation... but these are all performance related details, which require the knowledge of the underlying micro-architecture of particular target x86 CPU, if you are just learning basics of 8086, there's no need to worry about these yet, focus first to correctly understand what instructions do, so you can read any asm source, and together with the instruction guide you can deterministically predict what will be result of such code, understanding all the changes going on in the CPU on the high (registers/memory content) level. Whether some code takes one more clock to execute is less important in the beginning.

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
Ped7g
  • 15,245
  • 2
  • 24
  • 50
2

Many assembly instructions affect the CPU flags and those flags determine whether or not a branch will happen. OR affects the sign, overflow and zero flags (SF, OF, ZF).

JGE will jump if SF = OF or ZF = 1.

OR AX,AX has the following effects:

  1. OF = 0
  2. SF = 0 or 1 (if AX is positive or negative)
  3. ZF = 0 or 1 (if AX is non-zero or zero)

So, using OR AX,AX means that if AX is negative then JGE will not branch. If AX is zero or positive then it will branch.

D.Go
  • 171
  • 9