Chapter 6

Conditional Processing

Modified
Overview
Programming is hard! The goal of much research in computer science is to develop methods that make programming easier and programs more reliable. One familiar method is structured programming which uses formal control structures (For, While, If, etc.) to control program execution. In Assembly language these control structures do not exist as part of the language but can be implemented using the techniques examined in these notes and the text.

6.2.1    CPU Flags

ZF Zero flag is set when the result of an operation equals zero.

CF Carry flag is set when an instruction generates a result that is too large (or too small) for the destination operand, an invalid unsigned number.

SF Sign flag is set if the destination operand is negative, and it is clear if the destination operand is positive.

OF Overflow flag is set when an instruction generates an invalid signed result (bit 7 carry is XORed with bit 6 Carry).

PF Parity flag is set when an instruction generates an even number of 1 bits in the low byte of the destination operand.

AF Auxiliary Carry flag is set when an operation produces a carry out from bit 3 to bit 4
 

6.2.2 Boolean and Comparison Instructions

Logical instructions are based upon the definition of And, OR, XOR, and Not logic operations.

The logical operations are often used when controlling hardware, such as a printer interface as given in the example below.
 

Definition of And, Xor, Or, Not
And Or Xor Not
A B|A AND B  A B|A AND B 
F F|   F     0 0| 0
F T|   F     0 1| 0
T F|   F     1 0| 0 
T T|   T     1 1| 1
A B| A OR B  A B|A OR B 
F F|   F     0 0| 0
F T|   T     0 1| 1
T F|   T     1 0| 1 
T T|   T     1 1| 1
A B A XOR B  A B|A XOR B 
F F|  F      0 0| 0
F T|  T      0 1| 1
T F|  T      1 0| 1 
T T|  F      1 1| 0
A | Not A  
0 | 1
1 | 0


Useful Results 
And Or Xor
Set bit to 0   A B|A AND B 
               0 0| 0
               0 1| 0
Copy bit B     A B|A AND B 
               1 0| 0
               1 1| 1
Set bit to 1   A B|A OR B 
               1 0| 1
               1 1| 1
Copy bit B     A B|A OR B 
               0 0| 0
               0 1| 1
Xor is its own inverse 

      10101
  XOR 11100
      01001
  XOR 11100
      10101
Bit-wise Instructions
The And, Or, Xor, Test, and Not instructions apply the corresponding logical definition to each bit of the operand.

Note that Test is identical to And except that it only sets the flags but does not produce a result.

Bit-wise And, Or, Xor, Not
And Test Or Xor Not
Mov Ah, 11110000B 
And Ah, 00110011B
Ah =    00110000
ZF = 0
SF = 0
Mov  Ah, 11110000B 
Test Ah, 00110011B
Ah =     11110000
ZF = 0
SF = 0
Mov Ah, 11110000B 
Or  Ah, 00110011B
Ah =    11110011
ZF = 0
SF = 1
Mov Ah, 11110000B 
Xor Ah, 00110011B
Ah =    11000011
ZF = 0
SF = 1
Mov Ah, 11110000B 
Not Ah
Ah =    00001111
ZF = 0
SF = 0

 
Examples of And, Test, and Or 
Upper to lowercase conversion
 Mov  Bh, 01000001B   ; = 'A' = 41h 
 Or   Bh, 00100000B   ; Upper to lowercase 
 Bh =     01100001  = 'a'
Lower to uppercase conversion
 Mov  Bh, 01100001B   ; = 'a' = 61h 
 And  Bh, 11011111B   ; Lower to uppercase
 Bh =     01000001  = 'A'
Check if printer has paper
 Mov Dx, 379h      ;Printer Status address
 In  Al, Dx        ;Input printer status
 And Al, 00100000B ;Bit 5 == 0 when paper

If bit 5 == 0 then AL = 00000000  
                   ZF = 1

See page 460 of text for printer status
Wait for printer to be ready
   Mov Dx, 379h      ;Printer Status 
repeat:              ;repeat
   In  Al, Dx        ;  until !Busy&&Paper&&Online  
   And Al, 10110000B ;Bits    7     5        4 
until:               ;   Busy=1 Paper=0 Online=1 
   Cmp Al, 10010000B 
   Jnz repeat
endrepeat:

 

Question 1

What are Ah, ZF and SF?
Bit-wise And, Or, Xor, Not
And Test Or Xor Not
Mov Ah, 11110100B 
And Ah, 01110011B
Ah =    
ZF = 
SF = 
Mov  Ah, 11110100B 
Test Ah, 00110111B
Ah =     
ZF = 
SF = 
Mov Ah, 11011000B 
Or  Ah, 00010011B
Ah =    
ZF = 
SF = 
Mov Ah, 11110000B 
Xor Ah, 01111011B
Ah =    
ZF = 
SF = 
Mov Ah, 10000001B 
Not Ah
Ah =    
ZF = 
SF = 

 

6.2.7    CMP Instruction

CMP performs a SUB operation but only affecting the flags.

CMP    Destination, Source

CMP results ZF CF
Destination < Source 0 1
Destination > Source 0 0
Destination = Source 1 0

The add and subtract operation can operate on signed or unsigned numbers, either 8, 16 or 32-bit operands. The result is the same size as the operands so it is possible that incorrect results are produced when the result is too large or small. Remember that subtraction is performed by addition of a negative number.

 

Cmp

          Unsigned    11111111      Signed       Carry into and out of leftmost
 8 bits         110    000000012      110         bit equal, OF=0. 
-8 bits        -110 = +111111112     -110
 8 bits         010   1000000002      0          Valid unsigned, CF=0 since 
								  inverted on subtraction.
                     CF = 0    ZF = 1            
Mov Ah, 1            OF = 0    SF = 0            Valid signed, OF=0.
Cmp Ah, 1            Ah = 00000001
          Unsigned    11111110      Signed      Carry into and out of leftmost
 8 bits         210    000000102       210       bit equal, OF=0. 
-8 bits        -110 = +111111112      -110
 8 bits         110   1000000012 =     110       Valid unsigned 128, CF=0, inverted. 

                     CF = 0    ZF = 0            Invalid signed -128, OF=1.
Mov Ah, 2            OF = 0    SF = 0    
Cmp Ah, 1            Ah = 00000010
          Unsigned    00000000        Signed     Carry in 0, carry out of leftmost
 8 bits       110      000000012          110     bit 0, OF=0.
-8 bits      -210   = +111111102         -210
 8 bits     12710     0111111112 =       -110     Invalid unsigned CF=1, inverted. 

                      CF = 1    ZF = 0            Valid signed OF=1.
Mov Ah, 1             OF = 0    SF = 1  
Cmp Ah, 2             Ah = 00000001

Question 2

What are Ah, CF, OF, SF and ZF?
 
                     CF =     ZF =             
Mov Ah, 2            OF =     SF =             
Cmp Ah, 3            Ah =

                      CF =     ZF =  
Mov Ah, 3             OF =     SF =   
Cmp Ah, 2             Ah = 

 Execution Control Recall that the IP (Instruction Pointer) always points to the next instruction to execute, where the next fetch will occur. By changing the IP, different parts of the algorithm can be executed rather than the next sequential instruction. The following discusses the three forms of execution control available on the Intel processor.

Sequential, Unconditional, Conditional Execution

 
Corresponding Sequential, Unconditional, Conditional Code
   Mov  eAx, 0

   Call WriteDec

   Inc  eAx

   Mov  eDx, OFFSET Done
   Call WriteStrng




Output: 0 Done
   Mov  eAx, 0

A: Call WriteDec

   Inc  eAx

   Jmp  A

   Mov  eDx, OFFSET Done
   Call WriteStrng


Output: 0 1 2 ...   
   Mov  eAx, 0

A: Call WriteDec

   Inc  eAx

   Cmp  eAx, 10
   JL   A

   Mov  eDx, OFFSET Done
   Call WriteStrng

Output: 0 1 2 ... 8 9 Done
Labels

Labels define unique names for points in the algorithm. In the following unconditional branching code, A: defines the label, the Jmp A instruction branches to that point in the algorithm. The code produces an infinite execution with eAx= ...0, 1, 2, ..., FFFFFFFF, 0, 1, 2, ...
 

A: Call WriteDec
   Inc  eAx

   Jmp  A
Jmp - Unconditional Branch

An unconditional branch or jump is an execution branch always taken. In the program fragment above the Jmp A causes execution to branch unconditionally to the label A:.

Recall that the IP always points to the next instruction to be fetched. The unconditional branch instruction is executed by changing the IP to the address of the label. Consider the following code which shows the effects on the IP of the unconditional Jmp A execution. The steps are:

  1. fetch instruction Jmp A at IP value, offset 0006,
  2. update IP to next instruction, offset 0009
  3. execute Jmp A by setting IP to 0002, the offset of the label A.
Before and After Execute of Jmp A
After Fetch/Before Execute

      0002    A: Call WriteDec      
      0005       Inc  eAx
      0006       Jmp  A
IP -> 0009       Call WriteDec
After Execute

IP -> 0002    A: Call WriteDec
      0005       Inc  eAx
      0006       Jmp  A
      0009       Call WriteDec
Cmp

Compare Before examining conditional branching it is useful to first consider how to compare two values.

It is common in programming to compare the relation of two values (>,<, !=, ==, etc.) which produces a true or false result.

The Cmp instruction is a simple way to make such a comparison. Consider the following identical C++ and Assembler code:
 

C++ and Assembler to print 0 1 ... 8 9 Done
    eAx = 0;
A:  cout << eAx;
 
    eAx++;  
      if (eAx < 10) goto A
    cout << "Done";  
   Mov  eAx, 0

A: Call WriteDec

   Inc  eAx
   Cmp  eAx, 10 
   JL   A
   Mov  eDx, OFFSET Done
   Call WriteString
Cmp versus Sub

Recall that the Sub subtracts producing a result but also setting  flags (CF, OF, SF, ZF).

The Cmp instruction is identical to the Sub but only sets flags.

To see the difference consider the following example noticing that the value of the Ah register changes with the Sub but not the Cmp.
 

Difference between Sub and Cmp
   Ah changes

   Mov  Ah, 00000101B = 5
   Sub  Ah, 00000010B = 2

   Ah = 00000011 = 3
   CF = 0 OF = 0
   ZF = 0 SF = 0
   Ah no change

   Mov  Ah, 00000101B = 5
   Cmp  Ah, 00000010B = 2

   Ah = 00000101 = 5
   CF = 0 OF = 0
   ZF = 0 SF = 0
Both set the flags which can now be examined to determine the relationship between two values, in this case 5 and 2.

As an example, consider some of the possible relations between 5 and 2. Examine the Flag values column and compare with the flag values above to determine if the Condition column of the relation is true or false.
 

Possible relationships between 5 and 2
Relation Condition Flag values for Condition to be True
5 == 2 False ZF = 1
5 != 2 True ZF = 0
5 < 2 False CF = 1
5 > 2 True ZF = 0 and CF = 0
5 <= 2 False ZF = 1 or CF = 1
5 >= 2 True CF = 0
Je, Jne, Jl, Jg, ... - Conditional Branch

Conditional branching tests whether a condition is true, if true the branch to a label is made, otherwise the next sequential instruction is executed. In the following code the JL A instruction branches to label A in the algorithm if the condition Less Than is true. Otherwise the next instruction Mov eCx, 4 is executed.

A: Call WriteDec
   Inc  eAx

   Cmp  eAx, 10
   JL   A
 
   Mov  eCx, 4
Conditional JMPs
Unsigned Numbers
 Mnemonic Description Flags values for
true condition
C++ condition
JA/JNBE 
Jump if above
Jump if not below nor equal
CF = 0 and ZF = 0
X > Y
JAE/JNB
Jump if above or equal
Jump if not below
CF=0
X >= Y
JB/JNAE
Jump if below
Jump if not above nor equal
CF = 1
X < Y
JBE/JNA
Jump if below or equal
Jump if not above
CF = 1 OR ZF = 1
X <= Y
JE/JZ
Jump if equal zero
ZF = 1
X == Y
JNE/JNZ
Jump if not equal zero
ZF = 0
X != Y
 
Signed Numbers
 Mnemonic Description Flags values for
true condition
C++ condition
JG/JNLE 
Jump if greater
Jump if not less nor equal
ZF = 0 and SF == OF
X > Y
JGE/JNL
Jump if above or equal
Jump if not below
SF == OF
X >= Y
JL/JNGE
Jump if less than
Jump if not greater nor equal
SF != OF
X < Y
JLE/JNG
Jump if less than or equal
Jump if not greater
ZF = 1 or SF != OF
X <= Y
JE/JZ
Jump if equal zero
ZF = 1
X == Y
JNE/JNZ
Jump if not equal zero
ZF = 0
X != Y

 

Unconditional/Conditional Differences

Beyond the obvious difference that the unconditional jumps ignore flags and conditional jumps examine flags, one other important difference is the distance the jump can make. We'll use the following program fragment listing to illustrate the differences. Some minor changes have been made to the listing to make the example more clear.
 

Conditional and Unconditional Jump Example
  10 00000003  8E D8                          Mov     Ds, Ax
 11
 12 00000005  74 09                          Je      A
 13
 14 00000007  EB 00000010                    Jmp     A
 15
 16 0000000A  C7 06 0000r 000A               Mov     X, 10
 17
 18 00000010  C7 06 0000r 000B         A:    Mov     X, 11
 19
 20 00000016  C7 06 0000r 000C               Mov     X, 12
 21
 22 0000001C  74 F2                          Je      A
 23
 24 0000001E  B4 4C                          Mov     Ah, 4ch
Problems

The problem that occasionally occurs is when a conditional jump is attempted that is too far from the destination label, beyond -128 to 127 bytes away. However, the unconditional jump can reach any number of bytes away. The solution to reach a label that is too far away for a conditional jump is to use a conditional jump to an unconditional jump to the label. Below is an example of the problem and a solution.

The solution is not completely satisfactory since it requires us to invert the logic.
 

Solving the Conditional Jump Limit
Problem Solution
 A:

  More than 127 bytes

  Je   A
  Mov  X, 12 
A:
    More than 127 bytes

     Jne   Aa
     Jmp   A
Aa:  Mov  X, 12

Structured Programming

Structured programming abstractions have long been widely utilized to improve programmer productivity and program reliability. One of the key concepts at the foundation of the success of structured programming methods is the restriction of sequence control structures to:

  1. Sequential - The next sequential instruction is executed
     
  2. Iteration - A sequence of instructions are repeatedly executed for a specified number of iterations. Example: FOR, WHILE
     
  3. Conditional - An instruction is conditionally executed based upon a conditional expression being true. Example: IF
The defining characteristic of structured programming constructs is that of ONE ENTRY/ONE EXIT. Entry is only at the beginning of the structure; exit is only at the end; its importance is to limit the number of possible entries and exits to a section of code to exactly one. Most modern, high-level languages support structured programming concepts, languages such as Pascal and C++ provide formal syntax to describe the three sequence control structures listed above. Notice that the GoTo instruction is not considered a part of structured programming since it allows arbitrary entries and exits. Unfortunately the Intel machine architecture and the corresponding assembly language does not formally support structured techniques, having only the branch, or JMP, instruction, but disciplined program implementation can easily abstract the necessary control structures.

The following gives the general form of assembly instructions necessary to abstract common structured constructs. As a general programming rule, one should solve the programming problem first in a pseudocode language using structured methods then translate the pseudocode to a target language. This holds doubly true for assembly language as the myriad of details involved in simultaneously designing and implementing an algorithm directly in assembly can be overwhelming.

The figure below illustrates the advantage of good structure and naming conventions for improved readability and programming correctness.
 

Structured versus Unstructured - Absolute Value of X
Structured C++

  int X = -5;   

  if (X < 0)
      X = -X;

  X++;
Structure not obvious  

   Mov  X, -5

   Cmp  X, 0
   JGE  Positive  
   Neg  X
Positive: 
   Inc  X  
Structured but logic 
inverted 

   Mov  X, -5

if: Cmp  X, 0
    JGE  endif  
    Neg  X
endif: 
   Inc  X  
Structure obvious

    Mov  X, -5   

if: Cmp  X, 0
    JL   then
    Jmp  endif
then:
    Neg  X
endif: 
    Inc  X  
 


If Then/If Then Else
Pseudocode                              Assembler

 IF Condition                            IF: cmp  opr1, opr2
  THEN statement1                            jCondition    THEN
  ELSE statement2                            jmp           ELSE
 ENDIF                                    THEN:
                                                statement1
                                                jmp        ENDIF
                                           ELSE:
                                                statement2
                                        ENDIF:  

Example:

 if (char == 'A' && bx != 10)                  IF:  cmp  char, 'A'
 {                                                  jE   AND
          al = char;                                jmp  ELSE
          bx = bx + 1;                         AND: cmp  bx, 10  
 }                                                  jNE  THEN
 else                                               jmp  ELSE
       bx = bx - 1;                             THEN:
                                                    mov     al, char
                                                    inc     bx
                                                    jmp     ENDIF
                                                ELSE:
                                                    dec     bx
                                               ENDIF:

Example:

 if (char == 'A')                              IF:  cmp  char, 'A'
 {                                                  jE   THEN
          al = char;                                jmp  ENDIF
          bx = bx + 1;                           THEN:
 }                                                  mov  al, char 
                                                    inc  bx
                                                 ENDIF:              

Question 3

Translate the following into structured assembly:

if( al == 5)
    bl = 'O'
else
    bl = 'X'

 

While
 Pseudocode                              Assembler

 WHILE Condition DO                      WHILE:    cmp  opr1, opr2
     statement;                                    jCondition DO
 ENDWHILE                                          jmp ENDWHILE      
                                             DO:
                                                       statement
                                                       jmp   WHILE
                                        ENDWHILE: 

Example:
 
 while (si > 5)                         WHILE:       cmp  si, 5
        si =  si - 1;                                jG   DO  
                                                     jmp  ENDWHILE
                                             DO:
                                                     dec   si
                                                     jmp   WHILE
                                        ENDWHILE: Example:

Example:

 while (si > 5  || AB != si)            WHILE:       cmp  si, 5
        si =  si - 1;                                jG   DO
                                                OR:  cmp  AB, si
                                                     jNE  DO
                                                     jmp  ENDWHILE
                                             DO:
                                                     dec   si
                                                     jmp   WHILE
                                        ENDWHILE:
 

Question 4

Translate the following into structured assembly:

eAx = 0
while ( eAx <= 5) {
    eAx = eAx + 1
    print( eAx )
}

 

For
Pseudocode                              Assembler

 FOR (Index = Start ;                        mov  Index, Start
      Index Condition Stop ; Index++)   FOR: cmp  Index, Stop
  DO statement;                              jCondition  DO
 ENDFOR                                      jmp  ENDFOR
                                          DO:
                                                  statement
                                                  inc  Index
                                                  jmp  FOR
                                        ENDFOR:

Example:

 for (bx = 10; bx <=15; bx++)  {             mov  bx, 10
     cin >> Ax ;                        FOR:
     if (Ax < 0)                             cmp  bx, 15
         Ax = -Ax;                           jLE  DO
     Dx = Dx + Ax;                           jmp  ENDFOR
 }                                        DO:
                                               call GetDec  
                                           IF: cmp  ax, 0       
                                               jL   THEN
                                               jmp  ENDIF
                                             THEN:  neg  ax          
                                           ENDIF:
                                             add  dx, ax
                                             inc  bx
                                             jmp  FOR
                                          ENDFOR:

Example:

 for (bx = 10; bx <=15; bx++)                mov  bx, 10
     cout << bx ;                        FOR:
                                             cmp  bx, 15
                                             jLE  DO
                                             jmp  ENDFOR
                                         DO:
                                             mov  ax, bx
                                             call PutDec  
                                             inc  bx
                                             jmp  FOR
                                          ENDFOR:

Question 5

Translate the following into structured assembly:

for ( eAx = 0; eAx < 5; eAx++) {
    print( eAx )
}

 

Repeat
Pseudocode                              Assembler

 REPEAT                             REPEAT:
   Statement                            Statement
 UNTIL Condition                    WHILE:
                                        cmp  opr1, opr2
                                        jCondition ENDREPEAT
                                        JMP  REPEAT
                                    ENDREPEAT:

Example:

 REPEAT                             REPEAT:
     si := si - 1                       dec  si
 UNTIL (si <= 5) AND                UNTIL:
      (AB = si );                       cmp  si, 5
                                        jle  AND
                                        jmp  REPEAT
                                    AND:
                                        cmp  AB, si
                                        je   ENDREPEAT
                                        jmp  REPEAT
                                   ENDREPEAT:

Question 6

Translate the following into structured assembly:

eAx = 0
repeat {
    eAx++
    print( eAx )
} until( eAx == 5 )

 

Do While
Pseudocode                              Assembly

 DO                                      DO:
     Statement                               Statement
 WHILE Condition                         WHILE: Cmp opr1, opr2
                                                jCondition DO
                                        ENDWHILE:                   

Example:

 do                                 DO:
     si = si - 1;                       dec  si
 while (si <= 5 );                  WHILE:
                                        cmp  si, 5
                                        jle  DO
                                    ENDWHILE:

Example:

 do                                 DO:
     si = si - 1;                       dec  si
 while (si <= 5 &&                  WHILE:
       AB == si );                      cmp  si, 5
                                        jle  AND
                                        jmp  ENDWHILE
                                     AND:
                                        cmp  AB, si
                                        je   DO
                                    ENDWHILE:

Question 7

Translate the following into structured assembly:

eAx = 0
do {
    eAx++
    print( eAx )
} while ( eAx < 5 )

 

Switch
Pseudocode                            Assembler

switch (selector) {              SWITCH:  cmp    selector, value1
    case value1: Statement1;              je     CASEvalue1
                 break;                   cmp    selector, value2
    case value2: Statement2;              je     CASEvalue2
                 break;                   jmp    DEFAULT
    default:     Default Statement;   CASEvalue1:
}                                         Instructions for Statement1
                                          jmp    ENDSWITCH
                                      CASEvalue2:
                                          Instructions for Statement2
                                          jmp    ENDSWITCH
                                      DEFAULT:
                                          Instructions for Default Statement
                                 ENDSWITCH:

Example:

switch (n) {                     SWITCH:  cmp         n, 1
  case 1: score = 95;                     je          CASE1
          break;                          cmp         n, 2
  case 2: score = 73;                     je          CASE2
          break;                          cmp         n, 5
  case 5: cout << Ax;                     je          CASE5
          break;                          jmp         DEFAULT
  default:score = 50;              CASE1: mov         score, 95
}                                         jmp         ENDSWITCH
                                   CASE2: mov         score, 73
                                          jmp         ENDSWITCH
                                   CASE2: call        PutDec
                                          jmp         ENDSWITCH     
                                 DEFAULT: mov       score, 50
                                 ENDSWITCH:

Question 8

Translate the following into structured assembly:

eAx = 0
switch( eAx)  {
    case 0 :  eAx++
                  break
    case 1 :  eAx--
                  break
    default : eAx = 0
}

 

Example - Linear Search of an array

Following searches an array for given value. Returns:

-1 if not found

array index if found.

 

 

int array[] = {1,-20,35,-12,66,4};

 

void main() {
  if( Search( -12 ) == -1)
    print("Not found")
  else
   print("Found")
}

 

 

 

 

 

int Search( int eAx ) {
  int eCx = 6;
  int eSi = 0;
  do {
    if( array[ eSi ] == eAx)
      return eSi;
    eSi++;
  } while (--eCx != 0);
  return -1;
}

INCLUDE Irvine32.inc

.data
Found		BYTE	"Found", 0
NotFound	BYTE	"Not Found", 0
array	      DWORD	1,-20,35,-12,66,4
.code
Main    Proc   
        	Mov		eAx, -12
        	Call		Search
  @@if:	Cmp		eAx, -1
		Je		@@then
		Jmp		@@else
  @@then:
		Mov		eDx, OFFSET NotFound
		Call		WriteString
		Jmp		@@endif
  @@else:
		Mov		eDx, OFFSET Found
		Call		WriteString
  @@endif:
        	Exit
Main   Endp
Search	Proc
		Mov		eCx, 6
		Mov		eSi, 0   
 @do:	
  @if:	Cmp		array[ eSi ], eAx
		Je		@then
		Jmp		@endif
  @then:
		Mov		eAx, eCx
		Ret
  @endif:
		Add		eSi, 4
@while:	Loop  	@do		
		Mov		eAx, -1
		Ret
Search	Endp

        End      Main

 

6.5.2    Compound Expressions

AND and OR logical operators create compound expressions.

Short-circuiting means that logical operands are evaluated left-to-right until the logical result can be determined. For example:

i = -1;

if( i >= 0 && x[ i ] < 5)
     print( x[ i ] );

            mov    eSi, -1
@if:      cmp    eSi, 0
            jge      @and
            jmp     @endif
@and:  cmp     x[ eSi ], 5
            jl         @then
            jmp     @endif
@then: mov    eAx, x[ eSi ]
            call      WriteDec
@endif:

because i >= 0 is false, i >= 0 && x[ i ] < 5 can not be true, x[ i ] < 5 is not evaluated.

i >= 0 serves as a guard to prevent indexing the array x with a negative index.

Question 9

Translate the following into structured assembly:

if( eAx >= 0 && eAx < 10)

      print(eAx);

Below, because i >= 0 is true, i >= 0 || x[ i ] < 5 will be true, x[ i ] < 5 is not evaluated.

i = 1;

if( i >= 0 || x[i] < 5)
     print( i );

            mov    eSi, -1
@if:      cmp    eSi, 0
            jge      @then
@or:    cmp     x[ eSi ], 5
            jl         @then
            jmp     @endif
@then: mov    eAx, x[ eSi ]
            call      WriteDec
@endif:

 

 

And
 Pseudocode                              Assembler

 Condition1 AND Condition2                  cmp          opr1, opr2
                                            jCondition1  AND
                                            jmp          AND_FALSE
                                        AND:cmp          opr3, opr4
                                            jCondition2  AND_TRUE
                                            jmp          AND_FALSE
                                        AND_TRUE:
                                            Instructions when TRUE
                                        AND_FALSE:

Example:
 
 (si > 5 && AB != si)                           cmp    si, 5         
                                                jG     AND
                                                jmp    AND_FALSE
                                        AND:    cmp    AB, si
                                                jne    AND_TRUE
                                                jmp    AND_FALSE
                                        AND_TRUE:
                                               Instructions when TRUE
                                        AND_FALSE:
 

 

Or
Pseudocode                              Assembler

 Condition1 OR Condition2                  cmp             opr1, opr2
                                           jCondition1     OR_TRUE
                                   OR:     cmp             opr3, opr4

                                           jConditional2   OR_TRUE
                                           jmp             OR_FALSE
                                   OR_TRUE:
                                           Instructions when TRUE
                                   OR_FALSE:

Example:
 (si > 5 || AB != si)                           cmp    si, 5       
                                                jG     OR_TRUE
                                        OR:     cmp    AB, si
                                                jne    OR_TRUE
                                                jmp    OR_FALSE
                                        OR_TRUE:
                                              Instructions when TRUE
                                        OR_FALSE:

Question 10

Translate the following into structured assembly:

if( eAx >= 0 || eAx < -10)

      print(eAx);

 

Example - Four function calculator

User enters: 5
                   + 4

Output:    9

C++ Program Example 
// Simple 4 function calculator 
//
#include "iostream.h"

void main(void)
{
   int  opr1, opr2;
   char op;

   do {
       cin >> opr1;
       cin >> op;
       cin >> opr2;

       switch (op) {
          case '+' :  cout << opr1 + opr2;
                      break;
          case '-' :  cout << opr1 - opr2;
                      break;
          case '*' :  cout << opr1 * opr2;
                      break;
          case '/' :  cout << opr1 / opr2;
                      break;
       }
   } while (op != 'Q' && op != 'q'); 
}
Assembler Program Example 
; Simple 4 function calculator -  
;  Enter 12/3 as: 12
;                 /3  due to text Input/Output

Include	Irvine32.inc     		     ; #include "iostream.h"

.data   
        opr1    dword      ?            ; int  opr1, opr2;
        opr2    dword      ?            ; char op;
        op      byte       ?

.code
 main   Proc                            ; void main(void)
  do1:                                  ;   do {
        Call    ReadInt                 ;       cin >> opr1;
        Mov     opr1, eAx
        Call    ReadChar                ;       cin >> op;
        Mov     op, Al                  ;       
        Call    ReadInt                 ;       cin >> opr2;
        Mov     opr2, eAx 

     switch:                            ;       switch (op) {
        Cmp     op, '+'                 ;          case '+' :  cout << opr1 + opr2;
        Je      case1                   ;                      break;
        Cmp     op, '-'                 ;          case '-' :  cout << opr1 - opr2;
        Je      case2                   ;                      break;
        Cmp     op, '*'                 ;          case '*' :  cout << opr1 * opr2;
        Je      case3                   ;                      break;
        Cmp     op, '/'                 ;          case '/' :  cout << opr1 / opr2;
        Je      case4                   ;                      break;
        Jmp     endswitch
     case1:
        Mov     eAx, opr1
        Add     eAx, opr2
        Call    WriteInt
        Jmp     EndSwitch
     case2:
        Mov     eAx, opr1
        Sub     eAx, opr2
        Call    WriteInt
        Jmp     EndSwitch
     case3:
        Mov     eAx, opr1
        Imul    opr2
        Call    WriteInt
        Jmp     EndSwitch
     case4:
        Mov     eAx, opr1
        Cdq
        Idiv    opr2
        Call    WriteInt
     EndSwitch:                         ;         }
  while1:
        Cmp     op, 'Q'                 ;       } while (op != 'Q' && op != 'q');
        Jne     and1
        Jmp     endwhile1
     and1:
        Cmp     op, 'q'
        Jne     do1                   
  endwhile1:
        exit
 main   Endp                            ; }

        End     main

 

6.7    Decision Directives

We have constructed structured programs by creating if, while, and repeat statements.

The assembler has directives that automatically generate the code necessary to implement those statements.

Using directives can make your program more readable and source code that you write, smaller.

Because directives generate additional code that becomes part of your program, debugging traces are more difficult to follow.

.IF

Example - column 2 is generated by the assembler from the .IF directive in column 1.

.IF eax > ebx
   mov edx,1
.ELSE
   mov edx,2
.ENDIF
.IF eax > ebx
                   cmp eax,ebx
                   jbe @C0001
                   mov edx,1
.ELSE
                   jmp @C0003
@C0001      mov edx,2
@C0003
.ENDIF
if( eax > ebx)
   edx = 1;
else
   edx = 2;

Example

.IF eax > ebx && ebx < 10
   mov edx,1
.ELSE
   mov edx,2
.ENDIF
if( eax > ebx && ebx < 10)
   edx = 1;
else
   edx = 2;

Question 11

Translate the following into structured assembly using .IF:

if( eAx >= 0 )

      print(eAx);

else

      eAx--;

 

.WHILE

Example

     mov   eAx, 10
.WHILE eax > 0
     Call   WriteInt
     Call   CrLf
     dec    eAx
.ENDW
eAx = 10;
while( eax > 0) {
   print( eAx );
   eAx--;
}

Example

     mov   eAx, 10
.WHILE eax > 0 && eax <=10
     Call   WriteInt
     Call   CrLf
     dec    eAx
.ENDW
eAx = 10;
while( eax > 0 && eax <= 10) {
   print( eAx );
   eAx--;
}

Question 12

Translate the following into structured assembly using .WHILE:

while( eAx >= 0 && eAx < 10) {

      eAx--;

      print( eAx );

}

 

.REPEAT

Example

     mov   eAx, 10
.REPEAT
     Call   WriteInt
     Call   CrLf
     dec    eAx
.UNTIL eAx == 0
eAx = 10;
do {
   print( eAx );
   eAx--;
} while( eax != 0)

Question 13

Translate the following into structured assembly using .REPEAT:

do {

      eAx--;

      print( eAx );

} while( eAx >= 0 && eAx < 10)

 

 

Example - Linear Search of an array

Search function searches an array for given value. Returns:

-1 if not found

array index if found.

 

 

int array[] = {1,-20,35,-12,66,4};

 

void main() {
  if( Search( -12 ) == -1)
    print("Not found")
  else
   print("Found")
}

 

 

 

 

 

int Search( int eAx ) {
  int eCx = 6;
  int eSi = 0;
  do {
    if( array[ eSi ] == eAx)
      return eSi;
    eSi++;
  } while (--eCx != 0);
  return -1;
}

INCLUDE Irvine32.inc

.data
Found		BYTE	"Found", 0
NotFound	BYTE	"Not Found", 0
array	    	DWORD	1,-20,35,-12,66,4

.code
Main    	Proc   
        	Mov		eAx, -12
        	Call		Search
  .IF	eAx == -1
		Mov		eDx, OFFSET NotFound
		Call		WriteString
  .ELSE
		Mov		eDx, OFFSET Found
		Call		WriteString
  .ENDIF
        	Exit
Main   Endp

Search	Proc
		Mov		eCx, 6
		Mov		eSi, 0   
 .REPEAT	
  .IF	array[ eSi ] == eAx
		Mov		eAx, eCx
		Ret
  .ENDIF
		Add		eSi, 4
		Dec		eCx
 .UNTIL	eCx == 0	
		Mov		eAx, -1
		Ret
Search	Endp

End      Main