2

I got 2 questions. The first one: what is the difference between 'or' and 'cmp'? I have seen both, and it seems like they do the same thing. My second question: what does

or al, al

mean? Should it not return true all the time (like x == x)?

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
Erik W
  • 2,470
  • 2
  • 17
  • 32
  • 3
    Related [Test whether a register is zero with CMP reg,0 vs OR reg,reg?](https://stackoverflow.com/a/33724806) - `test al,al` is architecturally equivalent but better on modern CPUs (can macro-fuse with JCC and doesn't write a partial register). – Peter Cordes Jul 19 '20 at 22:28

1 Answers1

9

Actually, assembly doesn't work as simply as return true. Generally speaking, conditional execution is usually based on a status register. I will use Intel x86 architecture in this explanation. Note that other architectures are different, but the basic principle stays as far as I know.

As mentioned before, the flow of the program is determined by status register, named FLAGS on x86 (http://en.wikipedia.org/wiki/FLAGS_register). As you can see there is for example ZF (zero flag) bit. In case when conditional instruction such as jz or jnz is executed, the ZF is checked and the jump is executed (or not) based on this state.

The FLAGS register is updated as the code is being executed, each instruction setting some (sometimes none) bits to appropriate values. This data can be read in appropriate manuals for the given architecture. On x86 for example, add instruction alters CF (carry flag).

If you look up or instruction, it updates FLAGS like this: "The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result." (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf#G5.251049).

Therefore, the

or al, al

code's functionality is based on whatever conditional instruction follows. It has no meaning standing alone as x |= x (in C-like languages) has basically no effect on the value but has a side-effect on the status register.

From what we could read, we could for example use

or al, al
jnz _someWhere

in order to decide whether the contents of al register are nonzero and in case it is, jump to _someWhere.

For an explanation of reasoning for using test al, al instead of cmp al, 0 or or al,al (all of which set FLAGS identically), I suggest reading Peter Cordes' excellent writeup at Test whether a register is zero with CMP reg,0 vs OR reg,reg?

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
Zdeněk Jelínek
  • 2,090
  • 15
  • 21
  • 1
    `and al, x` isn't as fast as `test al,x` in some cases, e.g. on AMD CPUs, or Intel Core2 / Nehalem, where `test` can macro-fuse with a JCC but `and` can't. See [Test whether a register is zero with CMP reg,0 vs OR reg,reg?](https://stackoverflow.com/a/33724806). – Peter Cordes Jul 19 '20 at 22:29
  • 1
    `or al,al` / `test al,al` are both architecturally equivalent to `cmp al, 0`. OR and AND both write all FLAGS; they set CF=OF=0, not leave it unmodified, just like `cmp`. There is no partial-flag problem, or any interaction with P4's false FLAGS dependency for `inc`/`dec`; P4's `inc` will have a false dep on `or al,al` just like `test al,al` or `cmp al,al`. Modern CPUs handle inc/dec and other instruction that only interact with CF by renaming CF separately from the SPAZO set of flags. See [INC instruction vs ADD 1: Does it matter?](https://stackoverflow.com/q/36510095) – Peter Cordes Jul 19 '20 at 22:35
  • 1
    @PeterCordes sorry for the late update, I have changed the answer to give just the basic explanation and link to your answer. – Zdeněk Jelínek Oct 11 '20 at 17:06