assembly: flags and jmps
jbwyatt.com

.. Conditional Jumps: JA, JG, JB, JL, JE, etc...

    Jumps Based on Specific flags

    Jumps Based on Equality

    Jumps Based on Unsigned comparisons

    Jumps Based on Signed Comparisons


      A,B unsigned    G,L signed
      Mnemonic              Meaning                    Jump Condition
           JA     Jump if Above                         CF=0 and ZF=0
           JAE    Jump if Above or Equal                CF=0
           JB     Jump if Below                         CF=1
           JBE    Jump if Below or Equal                CF=1 or ZF=1
           JC     Jump if Carry                         CF=1
           JCXZ   Jump if CX Zero                       CX=0
           JE     Jump if Equal                         ZF=1
           JG     Jump if Greater (signed)              ZF=0 and SF=OF
           JGE    Jump if Greater or Equal (signed)     SF=OF
           JL     Jump if Less (signed)                 SF != OF
           JLE    Jump if Less or Equal (signed)        ZF=1 or SF != OF
           JMP    Unconditional Jump                    unconditional
           JNA    Jump if Not Above                     CF=1 or ZF=1
           JNAE   Jump if Not Above or Equal            CF=1
           JNB    Jump if Not Below                     CF=0
           JNBE   Jump if Not Below or Equal            CF=0 and ZF=0
           JNC    Jump if Not Carry                     CF=0
           JNE    Jump if Not Equal                     ZF=0
           JNG    Jump if Not Greater (signed)          ZF=1 or SF != OF
           JNGE   Jump if Not Greater or Equal (signed) SF != OF
           JNL    Jump if Not Less (signed)             SF=OF
           JNLE   Jump if Not Less or Equal (signed)    ZF=0 and SF=OF
           JNO    Jump if Not Overflow (signed)         OF=0
           JNP    Jump if No Parity                     PF=0
           JNS    Jump if Not Signed (signed)           SF=0
           JNZ    Jump if Not Zero                      ZF=0
           JO     Jump if Overflow (signed)             OF=1
           JP     Jump if Parity                        PF=1
           JPE    Jump if Parity Even                   PF=1
           JPO    Jump if Parity Odd                    PF=0
           JS     Jump if Signed (signed)               SF=1
           JZ     Jump if Zero                          ZF=1

.. Status Flags

ALU has status flags that reflect the outcome of arithmetic
operations based on the contents of the destination operand
   Flags:
      Zero flag     – destination equals zero
      Sign flag     – destination is negative
      Carry flag    – unsigned value out of range (CU)
      Overflow flag – signed value out of range   (OS)

A flag is SET when it equals 1. A flag is CLEAR when it equals 0.

The 'mov' instruction NEVER affects ANY flag. The 'inc' & 'dec' instructions NEVER affect CF.
include emu8086.inc org 100h mov al, 0ffh add al, 2 jz YES jnz NO YES: PRINTN "zero" jmp Q NO: PRINTN "not zero" Q: ret
Zero Flag (values in hex) set when the result of operation is 0 ========= mov ax, 0FFFFh ; AX = FFFF inc ax ; AX = 0000, ZF = 1 ?? why ?? inc ax ; AX = 0001, ZF = 0
Sign Flag (values in hex) set when destination operand ========= CAN BE interpreted as negative (high bit set). mov al,0 ; AL = 00000000b, sub al,1 ; AL = 11111111b, SF = 1 add al,2 ; AL = 00000001b, SF = 0
Carry Flag (CU) set when result of operation generates an ========== UNSIGNED value too big or small for destination. mov al, 0FFh add al, 1 ; CF = 1, AL = 00 mov al, -1 ; -1 is FF hex IDENTICAL to above example add al, 1 ; CF = 1, AL = 00 mov bx, 65535 ; equals FFFF hex add bx, 1 ; CF = 1, BX = 0000
Overflow Flag (OS) set when SIGNED result of an operation ============= is invalid or out of range. ; Example 1 mov al, +127 add al, 1 ; OF = 1, AL = 80 ; Example 2 mov al, 7Fh ; OF = 1, AL = 80 add al, 1 Two examples are identical at the binary level because 7Fh equals +127. To determine the value of the destination operand, it is often easier to calculate in hex.
Both types (SIGNED UNSIGNED) of overflow occur independently and are signaled separately by CF (unsigned) and OF (signed) mov al, 01h ; (add 1 to 1) add al, 01h ; AL=02h, OF=0, CF=0 mov al, 0FFh ; (add 1 to 255? or to –1?) (ffh) add al, 1 ; AL=00h, OF=0, CF=1 mov al, 7Fh ; (add 1 to 127 = 128? or -128) (80h) add al, 1 ; AL=80h, OF=1, CF=0 mov al, 80h ; (add what to 128 or to –128?) add al, 80h ; AL=00h, OF=1, CF=1 When adding two integers, remember that the Overflow flag is only set when: Two positive operands are added and their sum is negative Two negative operands are added and their sum is positive
ADD and SUB affect the status flags according to result of the operation ZF (zero flag) = 1 iff the result is zero SF (sign flag) = 1 iff the msb of the result is one OF (overflow flag) = 1 iff there is a signed overflow CF (carry flag) = 1 iff there is an unsigned overflow

.. ADD instruction and status flags

ADD Instruction
===============
   ADD destination, source
       adds source to destination, result in destination (source unchanged)

Both operands must be of the same size and they cannot BOTH be mem operands

ADD affects the status flags according to result of the operation ZF (zero flag) = 1 iff the result is zero SF (sign flag) = 1 iff the msb of the result is one OF (overflow flag) = 1 iff there is a signed overflow CF (carry flag) = 1 iff there is an unsigned overflow How ADD instruction modifies OF and CF: OF = (carry out of MSB) XOR (carry into MSB) CF = (carry out of the MSB) Instructions operate exactly the SAME on signed and unsigned integers CPU CANNOT distinguish between signed and unsigned integers. YOU, the programmer, are solely responsible for proper interpretation
What will be the values of the Overflow flag (OS) ? mov al, 80h (-128) add al, 92h (-110)) ; OF = 1, AL = (1)12h = 18d -238 What will be the values of the Carry flag (CU) ? mov al, 80h (128) add al, 92h (146) ; CF = 1, AL = (1)12h = 18d 274
What will be the values of the Carry and overflow Flags? myBytes DB 255, 1, 128 mov al, myBytes ; AL = FF (255, -1) add al, [myBytes+1] ; CF = 1 OF = 0 AL = (1)00 mov al, myBytes+2 ; AL = 80 (128, -128) add al, 7Fh ; CF = 0 OF = 0 AL = FF
MOV leaves flags as they were INC leaves CF flag as it was

.. CMP instruction

Compares the destination operand to the source operand
  Nondestructive subtraction of source FROM destination
  Destination operand NOT changed
   CMP destination, source
       -> dest - source
      

Example: destination == source mov al,5 cmp al,5 ; 5-5 - Zero flag set je l1
CMP compares first and second JA jumps if first is above second Example: destination > source mov al,6 cmp al,5 ; 6-5 -> CF = 0 ja l1 Example: destination < source mov al,4 cmp al,5 ; 4-5 -> CF =1
** more complex comparisons
Example: cmp ax, bx ; ax-bx and set flags jae AE ; if here, then ax is below bx ; code ..... jmp END ; MUST jump here or will "fall thru" and execute other code AE: je EQ ; above OR equal ; if here, ax is above bx ; code ..... jmp END EQ: ; if here, ax is equal to bx ; code ..... END: ; everybody rejoins HERE - It's a good programming practice to organize code so the expected case is executed without a jump since a jump takes longer to execute than falling through the test.

.. SUB instruction and flags

SUB Instruction
===============

SUB destination, source
   subtracts the source FROM destination, result in destination (source unchanged)

Both operands must be of the same size and they cannot BOTH be mem operands

SUB affects the status flags according to result of the operation ZF (zero flag) = 1 iff the result is zero SF (sign flag) = 1 iff the msb of the result is one OF (overflow flag) = 1 iff there is a signed overflow CF (carry flag) = 1 iff there is an unsigned overflow How SUB instruction modifies OF and CF: NEG the source and ADD it to the destination OF = (carry out of MSB) XOR (carry into MSB) CF = INVERT (carry out of the MSB) SUB ===== sub AL, BL ; => AL = AL - BL ; => AL = AL + (-BL) Remember: SUB just adds the negative

.. INC, DEC instructions and flags

INC and DEC instructions
========================
   Add 1 or Subtract 1 from a single operand (mem or reg operand)
   Affect all status flags, except CF (uns)
                            ^^^^^^^^^

   Say that initially we have, CF=OF=0

      mov bh, 0FFh   ; CF=0, OF=0
      inc bh         ; bh=00h, CF=0, OF=0

      mov bh, 7Fh    ; CF=0, OF=0
      inc bh         ; bh=80h, CF=0, OF=1
 

.. Example code: compare, jumps, loops

;
; Read a number and determine if it is between 1 and 99
;
INCLUDE emu8086.inc
org 100h

   call  SCAN_NUM        ; read number into CX 
   cmp   CX, 1           ; 
   jl BAD                ; jump if less than 1 (signed)
   cmp   CX, 99          ; 
   jg BAD                ; jump if greater than 99
   PRINTN "Good Input"   ;     
   MOV AX, CX
   call PRINT_NUM
   jmp   Quit
BAD:    
   PRINTN "Bad Input"  ; invalid input found
Quit:
ret
    
; PROCEDURES (call)
; ----------
DEFINE_SCAN_NUM		 ; reads signed number from keyboard into CX
DEFINE_PRINT_NUM     ; prints AX signed
DEFINE_PRINT_NUM_UNS ; prints AX unsigned

end

.. TEST instruction: AND and set flags

   TEST  REG, memory
         memory, REG
         REG, REG
         memory, immediate
         REG, immediate 	
 
 Logical AND between all bits of two operands for flags only.
 These flags are affected: ZF, SF, PF. Result is not stored anywhere.

 ** Usually looking for a ZERO **
 
These rules apply:
   1 AND 1 = 1
   1 AND 0 = 0
   0 AND 1 = 0
   0 AND 0 = 0

Example:
   MOV AL, 00000101b
   TEST AL, 1         ; ZF = 0.
   TEST AL, 10b       ; ZF = 1.