CONDITIONAL JUMPS

Posted by Atezaz | 6:44 PM | | 0 comments »

For every interesting or meaningful situation of flags, a conditional jump is there. For example JZ and JNZ check the zero flag. If in a comparison both operands are same, the result of subtraction will be zero and the zero flag will be set. Thus JZ and JNZ can be used to test equality. That is why there are renamed versions JE and JNE read as jump if equal or jump if not equal. They seem more logical in writing but mean exactly the same thing with the same opcode. Many jumps are renamed with two or three names for the same jump, so that the appropriate logi c can be conveyed in assembly language programs. This renaming is done by Intel and is a standard for iAPX88. JC and JNC test the carry flag. For example we may need to test whether there was an overflow in the last unsigned addition or subtraction. Carry flag will also be set if two unsigned numbers are subtracted and the first is smaller than the second. Therefore the renamed versions JB, JNAE, and JNB, JAE are there standing for jump if below, jump if not above or equal, jump if not below, and jump if above or equal respectively. The operation of all jumps can be seen from the following table.

JC Jump if carry CF = 1 This jump is taken if
JB Jump if below the last arithmetic
JNAE Jump if not above or equal operation generated a
carry or required a
borrow. After a CMP it
is taken if the
unsigned source is
smaller than the
unsigned destination.

JNC Jump if not carry CF = 0 This jump is taken if
JNB Jump if not below the last arithmetic
JAE Jump if above or equal operation did not


38


generated a carry or
required a borrow.
After a CMP it is taken
if the unsigned source
is larger or equal to
the unsigned
destination.

JE Jump if equal ZF = 1 This jump is taken if
JZ Jump if zero the last arithmetic
operation produced a
zero in its destination.
After a CMP it is taken
if both operands were
equal.

JNE Jump if not equal ZF = 0 This jump is taken if
JNZ Jump if not zero the last arithmetic
operation did not
produced a zero in its
destination. After a
CMP it is taken if both
operands were
different.

JA Jump if above ZF = 0 AND This jump is taken
JNBE Jump if not below or equal CF = 0 after a CMP if the
unsigned source is
larger than the
unsigned destination.

JNA Jump if not above ZF = 1 OR This jump is taken
JBE Jump if not below or equal CF = 1 after a CMP if the
unsigned source is
smaller than or equal
to the unsigned
destination.

JL Jump if less SF  OF This jump is taken
JNGE Jump if not greater or equal after a CMP if the
signed source is
smaller than the
signed destination.

JNL Jump if not less SF = OF This jump is taken
JGE Jump if greater or equal after a CMP if the
signed source is larger
than or equal to the
signed destination.

JG Jump if greater ZF = 0 AND This jump is taken
JNLE Jump if not less or equal SF = OF after a CMP if the
signed source is larger
than the signed
destination.

JNG Jump if not greater ZF = 1 OR This jump is taken
JLE Jump if less or equal SF  OF after a CMP if the
signed source is
smaller than or equal
to the signed
destination.


39


JO Jump if overflow. OF = 1 This jump is taken if
the last arithmetic
operation changed the
sign unexpectedly.

JNO Jump if not overflow OF = 0 This jump is taken if
the last arithmetic
operation did not
change the sign
unexpectedly.

JS Jump if sign SF = 1 This jump is taken if
the last arithmetic
operation produced a
negative number in its
destination.

JNS Jump if not sign SF = 0 This jump is taken if
the last arithmetic
operation produced a
positive number in its
destination.

JP Jump if parity PF = 1 This jump is taken if
JPE Jump if even parity the last arithmetic
operation produced a
number in its
destination that has
even parity.

JNP Jump if not parity PF = 0 This jump is taken if
JPO Jump if odd parity the last arithmetic
operation produced a
number in its
destination that has
odd parity.

JCXZ Jump if CX is zero CX = 0 This jump is taken if
the CX register is zero.


The CMP instruction sets the flags reflecting the relation of the destination to the source. This is important as when we say jump if above, then what is above what. The destination is above the source or the source is above the destination.

The JA and JB instructions are related to unsigned numbers. That is our interpretation for the destination and source operands is unsigned. The 16th bit holds data and not the sign. In the JL and JG instructions standing for jump if lower and jump if greater respectively, the interpretation is signed. The 16th bit holds the sign and not the data. The difference between them will be made clear as an elaborate example will be given to explain the difference.

One jump is special that it is not dependant on any flag. It is JCXZ, jump if the CS register is zero. This is because of the special treatment of the CX register as a counter. This jump is regardless of the zero flag. There is no counterpart or not form of this instruction.

The adding numbers example of the last chapter can be a little simplified using the compare instruction on the BX register and eliminating the need for a separate counter as below.

40


Example 3.1

001 ; a program to add ten numbers without a separate counter
002 [org 0x0100]
003 mov bx, 0 ; initialize array index to zero
004 mov ax, 0 ; initialize sum to zero
005
006 l1: add ax, [num1+bx] ; add number to ax
007 add bx, 2 ; advance bx to next index
008 cmp bx, 20 ; are we beyond the last index
009 jne l1 ; if not add next number
010
011 mov [total], ax ; write back sum in memory
012
013 mov ax, 0x4c00 ; terminate program
014 int 0x21
015
016 num1: dw 10, 20, 30, 40, 50, 10, 20, 30, 40, 50
017 total: dw 0

006 The format of memory access is still base + offset.

8 BX is used as the array index as well as the counter. The offset of 11th number will be 20, so as soon as BX becomes 20 just after the 10th number has been added, the addition is stopped.

9 The jump is displayed as JNZ in the debugger even though we have written JNE in our example. This is because it is a renamed jump with the same opcode as JNZ and the debugger has no way of knowing the mnemonic that we used after looking just at the opcode. Also every code and data reference that we used till now is seen in the opcode as well. However for the jump instruction we see an operand of F2 in the opcode and not 0116. This will be discussed in detail with unconditional jumps. It is actually a short relative jump and the operand is stored in the form of positive or negative offset from this instruction.

With conditional branching in hand, there are just a few small things left in assembly language that fills some gaps. Now there is just imagination and the skill to conceive programs that can make you write any program.

0 comments