Chapter 6 - Conditional Processing

In assembly, you often need to perform operations on certain bits. This chapter deals with ways to do this and reasons why you would do this.

Logical Operations

(i24) [<label>] AND <destination>,<source>

Each bit of the destination operand is anded with the corresponding bit of the source operand. The result is placed in the destination and the appropriate flags are set.

Two other instructions of importance are:

(i25) [<label>] OR <destination>,<source>

(i26) [<label>] XOR <destination>,<source>

The truth tables for each of these instructions is as follows:

AND		OR		XOR

b1 b2 result    b1 b2 result    b1 b2 result
0  0  0         0  0  0         0  0  0
0  1  0         0  1  1         0  1  1
1  0  0         1  0  1         1  0  1
1  1  1         1  1  1         1  1  0

The AND, OR, and XOR instructions clear the OF and CF flags and modify the SF, ZF, and PF flags based on the value of the destination operand.

P#1: The AX-register contains an arbitrary value. Write an assembly language program segment which will complement the last four bits.

(i27) [<label>] NOT <destination>

Not performs the 1's complement of the operand. No flags are affected in the flags register.

(i28) [<label>] TEST <destination>,<source>

TEST performs the AND operation without changing the destination value.

Control Structures

In this chapter, we are concerned about two types of control structures:
(1) the decision structure
(2) the loop structure

In order to implement either of these control structures, we need to have some kind of branching capability. The JUMP instructions provide the means of branching.

There are two kinds of jumps:
(1) conditional JUMP - this jump might cause the CS:IP register pair to be modified. The determination of the jump is dependent on the current state of the flags register.
(2) unconditional JUMP - always causes the CS:IP register pair to be modified.

Conditional JUMP

A conditional jump causes one of two things to happen depending on the outcome of some decision:
(1) Execution continues with the next instruction and no jump is taken.
(2) The CS:IP is modified causing the branch to effectively be taken.

Conditional jumps are divided into three categories:
(1) unsigned integer jumps
(2) signed integer jumps
(3) flag register jumps (i.e. jumps based on a specific flag in the flags register)

The general form of a conditional JUMP is:

(i29-46) [<label>] <op-code> <short-label>

where op-code is an op-code from one of the following tables:

Conditional JUMPs for unsigned integers:

Mnemonic       Interpretation                      JUMPs If
JA             Jump if above                       CF=0 and ZF=0
JNBE           Jump if not below nor equal
JAE            Jump if above or equal              CF=0
JNB            Jump if not below
JB             Jump if below                       CF=1
JNAE           Jump if not above nor equal
JBE            Jump if below or equal              CF=1 or ZF=1
JNA            Jump if not above
JE             Jump if equal to zero               ZF=1
JZ             (same as above)             
JNE            Jump of not equal to zero           ZF=0
JNZ            (same as above)

Conditional JUMPs for signed integers:

Mnemonic       Interpretation                      JUMPs If
JG             Jump if greater than                ZF=0 and SF=OF
JNLE           Jump if not less nor equal
JGE            Jump if greater than or equal       SF=OF
JNL            Jump if not less than
JL             Jump if less than                   SF<>OF 
JNGE           Jump if not greater nor equal
JLE            Jump if less than or equal          ZF=1 or SF<>OF
JNG            Jump if not greater than
JE             Jump if equal to zero               ZF=1
JZ             (same as above)             
JNE            Jump of not equal to zero           ZF=0
JNZ            (same as above)

Conditional JUMPs for flags register:

Mnemonic       Interpretation                      JUMPs If
JC             Jump if carry                       CF=1          
JNC            Jump if no carry                    CF=0
JO             Jump if overflow                    OF=1 
JNO            Jump if no overflow                 OF=0
JS             Jump if sign negative               SF=1       
JNS            Jump if sign nonnegative            SF=0
JZ             Jump if zero                        ZF=1              
JNZ            Jump if not zero                    ZF=0
JP/JPE         Jump if parity even                 PF=1
JNP/JPO        Jump if parity odd                  PF=0

Now we can do some serious damage!!!

I would like to proceed in the following manner:
(1) Let's look at some examples using the single-alternative IF
(2) Let's examine how the microprocessor actually transfers control if the branch is taken

Single Alternative IF

In general, the single alternative if has the following form:

if(condition) then
  true statement(s)
endif

The question that we need to answer is how do we test for the condition. A condition in general has the form: operand1 <relational-op> operand2 where the relational operator can be the standard six relational operators. As an example, we might have the condition: x < y.

What you want to do is start with the expression (e.g. x < y) and then subtract the second expression from the first. This is just algebraic manipulation. So now we have x - y < 0. The flags register will reflect this relationship and you can use the appropriate jump instructions to test and branch accordingly. That is, are you working with signed or unsigned numbers. What are you testing?

Q#1: Let's assume that x and y are unsigned values and we are testing whether x is less than y. We could write x-y < 0 as our condition. If x is 0 and y is 1, what is the value of the CF flag? What instruction would you use to branch to some label if x is less than y? Note: The following code would simulate the above action:

mov ax,x
sub ax,y
jb xlessy

We notice with the sub instruction that the destination operand is modified. It would be nice to have an instruction that performs the same operation as the subtract instruction without modifying the destination operand especially since compares happen so often. That is why there is the compare instruction with the following form:

(i47) [<label>] CMP <destination>,<source>

This instruction causes the source operand to be subtracted from the destination operand and the flags register reflects this relationship. Neither the source or destination operands are modified.

P#1: Given the following data segment, write an assembly language program segment that will print the smaller of the two numbers X and Y. Get the values from the keyboard.

.data
x WORD ?
y WORD ?


©Douglas J. Ryan/ryandj@pacificu.edu