Table of Contents


Appendix D
JUMPING INSTRUCTIONS

Jumping instructions are a unique set. They are the ones that reset the IP register or the CS:IP register pair. By doing so, they cause an alteration of the standard next instruction program sequence. The CS:IP register pair is used by the CPU to keep track of where the next instruction to execute is located.

Standard Jumps

In the standard 80X86 instruction set, there are three different size offset values that can be used for jumping. They are the 8-bit short jumps, the 16-bit near jumps, and the 32-bit far jumps. The 32-bit far jumps use two 16-bit words combined to make up a 20-bit segment:offset address. The following are some common examples of jump instruction statements.

;goto near procedure next_task
     jmp  next_task
;goto far procedure next_task
     jmpf next_task
;the programmer does not need to use the jmpf mnemonic
   ; because the compiler will decide and use when needed
load BX with location of code routine
     mov  BX,offset next_task
     jmp  [BX]      ;goto where BX is pointing
;define data word with address of code routine
next dw   offset next_task
     jmp  [next]    ;goto next code routine

Conditional Jumps

A standard conditional jump instruction checks the contents of the Flag register bits relating to the jump condition. If the associated bits are set correctly for the jump condition, then the IP register is altered and program execution continues at the new address indicated by the instruction data. All conditional jump instructions use an eight-bit jump offset. To the programmer, this means that you can only jump over a few instructions. You can usually jump over 30 to 40 instructions; beyond that, you take a chance with compiling errors.

The following is a list of jump mnemonics with conditions and explanatory notes:

JB
jump below
This is normally used after a compare to see if the first variable was logically below the second value using unsigned numbers. Same as JC instruction.
JBE
jump below or equal
This is normally used after a compare to see if the first variable was logically below or equal to the second value using unsigned numbers.
JA
jump above
This is normally used after a compare to see if the first variable was logically above the second value using unsigned numbers.
JAE
jump above equal
This is normally used after a compare to see if the first variable was logically above or equal to the second value using unsigned numbers.
JC
jump carry
This is normally used to test for a set carry bit in the Flag register after an addition overflow or subtraction borrow. Same as JB instruction.
JNC
jump no carry
This is normally used to test for a no carry bit in the Flag register after an addition overflow or subtraction borrow.
JL
jump less
This is normally used after a compare to see if the first variable was less than the second value using signed numbers.
JLE
jump less or equal
This is normally used after a compare to see if the first variable was less than or equal to the second value using signed numbers.
JG
jump greater
This is normally used after a compare to see if the first variable was greater than the second value using signed numbers.
JGE
jump greater or equal
This is normally used after a compare to see if the first variable was greater than or equal to the second value using signed numbers.
JS
jump sign
This jump is used for testing for a set sign bit in the Flag register. The sign bit is set during some logical instructions to the same value as the most significant bit of the data.
JNS
jump no sign
This jump is used for testing for a no sign bit in the Flag register. The sign bit is set during some logical instructions to be a copy of the most significant bit of the data.
JO
jump overflow
Branch is taken if the overflow bit in the Flag register is set.
JNO
jump no overflow
Branch is taken if the overflow bit in the Flag register is not set.
JP
jump parity
Jump if the parity bit in the Flag register is set. Same as JPE instruction.
JNP
jump no parity
Jump if the parity bit in the Flag register is not set. Same as JPO instruction.
JCXZ
jump CX zero
This is a special condition jump for quick testing of the CX register and branching if zero. This does not test or change any bits in the Flag register.
LOOP
decrement CX and jump if CX not zero
This is a special condition jump normally used in repeat structures; it decrements the CX register and jumps if CX is not zero. Note that if you start with the CX register equal to zero, it loops 65536 times. To prevent this condition, the JCXZ instruction can be used before looping logic begins.

Real-time programmers note that the logical branch instructions execute several times faster if the jump is not taken. If possible, write your code such that the jumps are not taken under most conditions.

Subroutine Jumps

When you call a subroutine, the CPU saves the current contents of the CS:IP register pair or the IP register in the stack area so that when the subroutine is finished, it can load the return address from the stack area into the IP register or CS:IP register pair for continuation at the next instruction after the call statement.

  ;call procedure, compiler will decide if near or far
     call subroutine
  ;call using address in memory location
     call [indirect]
  ;call using address in register BX
     call [BX]

A subroutine call is terminated by a matching return instruction. The return instruction is a special case load instruction that loads the IP register or the CS:IP register pair with data indexed by the stack pointer.

RET
return
This is a standard near return that only pops the IP register from the stack. This is to be used by subroutines that are defined as near procedures.
RETF
return far
This is used when a subroutine is defined as a far procedure to return. This pops the CS:IP register pair off the stack. The reason that all calls are not far calls is to save memory and speed. Normally, the programmer will just use the RET mnemonic and let the compiler decide if the return is near or far.

Interrupt Jumps

These are normally used for calling system functions.

INT
interrupt
This is a software interrupt instruction that jumps to a location determined by the data and a vector table lookup. The interrupt vector table occupies the first 1,024 bytes of CPU addressing range. There are 256 different interrupt vectors. Each vector is made up of four bytes of memory locations for interrupt data to define CS:IP to the start of the interrupt routine.
IRET
interrupt return
This is like a normal RETF except the Flag register is popped as well as the CS:IP register pair. Note that you can make a far call look like an interrupt call by pushing the Flags before making the far call.

Because the conditional jumps are only eight bit offsets, problems will occur if you attempt to jump over more than a few instructions. One standard way to overcome this problem is to translate the jump as follows:

original

     jc   carry_overflow
     nop
carry_overflow:

translates to

     jnc  no_overflow
     jmp  carry_overflow
no_overflow:
carry_overflow:

Table Lookup Jumping

If you have a data variable and you want to execute one of several different functional routines depending on the data, then the table lookup jump is a good method for branching control. There are many ways that table lookup jumping can be performed, depending on the nature of the data that is used to select a particular subroutine from a set of possible subroutines.

The following is an example to select a jump given a positive binary integer between 0 and 32000:

function_table dw   function_0_routine
               dw   function_1_routine
               dw   function_2_routine
  ;load BX with number
     mov  bx,function_code
  ;point DI to index start of jump table
     lea  di,function_table
  ;adjust BX to word offset into jump table
     shl  bx,1
  ;perform call to routine indexed in table
     call [di+bx]

The following is an example of keyboard table lookup jumping.

keyboard_key        dw   0031
function_key_table  dw   0031
               dw   function_1_routine
table_end:
;
;load AX with function code
     mov  ax,keyboard_key
;ind
ex jump table with SI
     lea  si,function_key_table
function_loop:
     cmp  si,table_end        ;?? end of table ??
     jae  no_find_function    ;branch if end
     ;check for match of function codes
     cmp  ax,[si]
     je   function_find  ;branch if find code
     add  si,4      ;else point to next entry
     jmp  function_loop
function_find:
     jmp  [si+2]
no_find_function:


Table of Contents