http://www.emu8086.com/assembler_tutorial/asm_tutorial_07.html
1. Unconditional Jumps
JMP label
It can jump anywhere in current cs (65,536bytes)
2. Short Conditional Jumps
(1) test single flag; (2) compare numbers as signed; (3) compares numbers as unsigned.
Jump instructions that test single flag
Instruction | Description | Condition | Opposite Instruction |
JZ , JE | Jump if Zero (Equal). | ZF = 1 | JNZ, JNE |
JC , JB, JNAE | Jump if Carry (Below, Not Above Equal). | CF = 1 | JNC, JNB, JAE |
JS | Jump if Sign. | SF = 1 | JNS |
JO | Jump if Overflow. | OF = 1 | JNO |
JPE, JP | Jump if Parity Even. | PF = 1 | JPO |
JNZ , JNE | Jump if Not Zero (Not Equal). | ZF = 0 | JZ, JE |
JNC , JNB, JAE | Jump if Not Carry (Not Below, Above Equal). | CF = 0 | JC, JB, JNAE |
JNS | Jump if Not Sign. | SF = 0 | JS |
JNO | Jump if Not Overflow. | OF = 0 | JO |
JPO, JNP | Jump if Parity Odd (No Parity). | PF = 0 | JPE, JP |
The instruction has only one byte to keep the offset, limited to pass control to -128bytes back or 127bytes forward-->short jump!
Jump instructions for signed numbers
Instruction | Description | Condition | Opposite Instruction |
JE , JZ | Jump if Equal (=). Jump if Zero. | ZF = 1 | JNE, JNZ |
JNE , JNZ | Jump if Not Equal (<>). Jump if Not Zero. | ZF = 0 | JE, JZ |
JG , JNLE | Jump if Greater (>). Jump if Not Less or Equal (not <=). | ZF = 0 and SF = OF | JNG, JLE |
JL , JNGE | Jump if Less (<). Jump if Not Greater or Equal (not >=). | SF <> OF | JNL, JGE |
JGE , JNL | Jump if Greater or Equal (>=). Jump if Not Less (not <). | SF = OF | JNGE, JL |
JLE , JNG | Jump if Less or Equal (<=). Jump if Not Greater (not >). | ZF = 1 or SF <> OF | JNLE, JG |
Jump instructions for unsigned numbers
Instruction | Description | Condition | Opposite Instruction |
JE , JZ | Jump if Equal (=). Jump if Zero. | ZF = 1 | JNE, JNZ |
JNE , JNZ | Jump if Not Equal (<>). Jump if Not Zero. | ZF = 0 | JE, JZ |
JA , JNBE | Jump if Above (>). Jump if Not Below or Equal (not <=). | CF = 0 and ZF = 0 | JNA, JBE |
JB , JNAE, JC | Jump if Below (<). Jump if Not Above or Equal (not >=). Jump if Carry. | CF = 1 | JNB, JAE, JNC |
JAE , JNB, JNC | Jump if Above or Equal (>=). Jump if Not Below (not <). Jump if Not Carry. | CF = 0 | JNAE, JB |
JBE , JNA | Jump if Below or Equal (<=). Jump if Not Above (not >). | CF = 1 or ZF = 1 | JNBE, JA |
CMP--compare numeric values, the same as SUB except that CMP does not keep the value
(CMP and SUB have the same affect on flags)
e.g.
A. compare 5 and 2:
CMP -->set ZF=0
SUB -->3 is stored in the first operand(REG or memory) and set ZF=0
B. compare 7 and 7:
CMP -->set ZF=1, then JZ or JE will do the jump
SUB -->0 is stored in the first operand and set ZF=1
3. Loops
instruction | operation and jump condition | opposite instruction |
LOOP | decrease cx, jump to label if cx not zero. | DEC CX and JCXZ |
LOOPE | decrease cx, jump to label if cx not zero and equal (zf = 1). | LOOPNE |
LOOPNE | decrease cx, jump to label if cx not zero and not equal (zf = 0). | LOOPE |
LOOPNZ | decrease cx, jump to label if cx not zero and zf = 0. | LOOPZ |
LOOPZ | decrease cx, jump to label if cx not zero and zf = 1. | LOOPNZ |
JCXZ | jump to label if cx is zero. | OR CX, CX and JNZ |
4.All conditional jumps have one big limitation, unlike JMP instruction they can only jump 127 bytes forward and 128 bytes backward.
(most instructions are assembled into 3 or more bytes)
AVOID using a cute trick:
(1) Get an opposite conditional jump instruction from the table above, make it jump to label_x.
(2) Use JMP to jump to desired location
(3) Define label_x: just after the JMP.
label_x: can be any valid name, but there must not be two or more labels with the same name.
example:
include "emu8086.inc"
org 100h
mov al, 5
mov bl, 5
cmp al, bl ; compare al - bl.
; je equal ; there is only 1 byte
jne not_equal ; jump if al <> bl (zf = 0).
jmp equal
not_equal:
add bl, al
sub al, 10
xor al, bl
jmp skip_data
db 256 dup(0) ; 256 bytes 00000...00
skip_data:
putc 'n' ; if it gets here, then al <> bl,
jmp stop ; so print 'n', and jump to stop.
equal: ; if gets here,
putc 'y' ; then al = bl, so print 'y'.
stop:
ret
-----------------------------------
(4) (rarely used) providing an immediate value instead of label.
When immediate value starts with $, relative jump is performed, otherwise compiler calculates instruction that jumps directly to given offset.
example:
org 100h
; unconditional jump forward:
; skip over next 3 bytes + itself
; the machine code of short jmp instruction takes 2 bytes.
jmp $3+2
a db 3 ; 1 byte.
b db 4 ; 1 byte.
c db 4 ; 1 byte.
; conditional jump back 5 bytes:
mov bl,9
dec bl ; 2 bytes.
cmp bl, 0 ; 3 bytes.
jne $-5 ; jump 5 bytes back
ret