Call-by-value/Call-by-reference/Dynamic Variables/Bit Operations/Multi-byte Arithmetic/Macros


1. (25) Euclid's algorithm for finding the greatest common divisor (GCD) of two positive integers, A and B, in C++ is:

    int GCD( int A, int B ) {
     int T;
     
          while (A != 0 && B != 0) {   
           A = A % B;
           T = A;
           A = B;
           B = T;
          };
          return A;
     }
Answer

A       Equ     word ptr[Bp+4]
B       Equ     word ptr[Bp+6]

GCD     proc    near
        Push    Bp
        Mov     Bp, Sp
 while: Cmp     A, 0            ; while( A!=0 && B!=0) {
        Jne     And
        Jmp     Endwhile
   And: Cmp     B, 0
        Jne     Do
        Jmp     Endwhile
    Do: Mov     Dx, 0
        Mov     Ax, A
        Div     B
        Mov     A, Dx            ;   A = A%B;
        Mov     Cx, A            ;   T = A;
        Mov     Bx, B
        Mov     A, Bx            ;   A = B;
        Mov     B, Cx            ;   B = T;
        Jmp     While            ; }
Endwhile:
        Mov     Ax, A            ; return A;
        Pop     Bp
        Ret
Write a COMPLETE assembly procedure to implement the above GCD. It is NOT necessary to give the complete program, only the FUNCTION. Parameters and results are passed using C++ conventions. Use stack or register for local variable T.


2. (30) The following is a brute force method for calculating prime numbers from 3 through 10,000 using the GCD function from Question 2. Implement the following C++ code FRAGMENT in Assembly language using the stack call-by-value or call- by-reference parameter passing conventions and procedures PutDec/PutStrng for input/output. Use data segment definitions of:
______________________________ 
Data Segment                  |         for (I = 3; I <= 10000; I++) 
     I     dw  ?              |         {
     P     dw  ?              |              Prime = 1;
     G     dw  ?              |              G = 2;
     Prime dw  ?              |              while (G <= I && Prime == 1) 
     PStr  db  'Prime'        |              {
     NPStr db  'not Prime'    |                   P = GCD( I, G);
Data Ends                     |                   if (P != 1 && P != I)
______________________________|                        Prime = 0;
                                                  G = G + 1;
                                             }; 
                                             if (Prime == 1)
                                                  cout << I << "Prime";
                                             else cout << I << "not Prime";
                                        };
Answer

        Mov    I, 3
for:    Cmp    I, 10000          
        Jbe    do
        Jmp    endfor
 do:    Mov    Prime, 1
        Mov    G, 2
 while: Mov    Ax, G
        Cmp    Ax, I
        Jbe    And1
        Jmp    endwhile
  And1: Cmp    Prime, 1
        Je     dowhile
        Jmp    endwhile
   dowhile:
        Push   G
        Push   I
        Call   GCD
        Add    Sp, 4   
        Mov    P, Ax
    if: Cmp    P, 1
        Jne    And2
        Jmp    endif
  And2: Mov    Ax, P
        Cmp    Ax, I
        Jne    then
        Jmp    endif
  then: Mov    Prime, 0
  endif:
        Inc    G
        Jmp    while
 endwhile:
   if2: Cmp    Prime, 1       
        Je     then2
        Jmp    else2
    then2:
        Lea    Di, PStr
        Mov    Cx, 5
        Call   PutStrng
        Jmp    endif2
    else2:
        Lea    Di, NPStr
        Mov    Cx, 9
        Call   PutStrng
        Jmp    endif2
    endif2:
        Inc    I
        Jmp    for
endfor:
       

3. (25) Trace the execution of the following to answer questions below:
Offset                             Offset 

       DSeg    Segment                  Subp   Proc  Near   
0000      Q    dw      5           000B        Push   Bp   
0002      R    dw      26          000C        Mov    Bp, Sp    
       DSeg    Ends                000D        Sub    Sp, 2     
                                   000E        Mov    Ax, [Bp+6]
                                   000F        Mov    [Bp-2], Ax
                                   0010        Mov    Bx, [Bp+4]
       Cseg     Segment            0011        Mov    [Bx], Ax
       Assume   Cs:Cseg, Ds:DSeg   0012        Mov    Ax, Bx
       Main  ProcFar               0013        Mov    [Bp+4], 789Ah
0000     Mov    Ax, Seg DSeg       0014        Mov    Sp, Bp 
0001     Mov    Ds, Ax             0015        Pop    Bp       
0002     Push   Q                  0016        Ret              
0003     Push   offset R                Subp   Endp
0004     Call   Subp 
0005     Add    Sp, 4       
0006     Call   PutDec      
0007     Ret                                          
       Main     Endp        


A. Fill in values on STACK BEFORE       Assume initial values of:
execution of the instruction at                   IP = 0000      
offset 0014 hexadecimal.                          SP = 021E                  
                                                  AX = 6534
          _________________                       BX = 0054      
 021E    |                 |                      BP = 1234      
         |_________________|                      DS = AE1D      
 021C    |                 |                                     
         |___5_______Q_____| Bp+6       B. Fill in final REGISTER values and variables
 021A    |   0002  offset R|               immediately BEFORE the execution
         |___789A          | Bp+4          of instruction at offset 0007
 0218    |                 |                                    
         |___0005__ret addr| Bp+2                 IP = 0007
 0216    |                 |                      SP = _021E_____ 
         |___1234__________| Bp                   AX = _0002_____             
 0214    |                 |                      BX = _0002_____             
         |____5 ___________| Bp-2                 BP = __1234____       
 0212    |                 |                      Q  = __5      _
         |_________________|                      R  =   5       
 0210    |                 |
         |_________________|
 020A    |                 |            
         |_________________|

 Offset     Stack Segment
4. (15) Write a macro named Ones that will count the number of one bits in a word. It should return the count in Ax. In the following Ax = 2 is returned.
       Macro definition

      .Ones     Macro     A

        Example invocation

       .Ones     0000000000000101B 

C++ Algorithm

int Ones( int N) {
    int Ax = 0;
    while (N != 0) {
       if ( N & 1 == 1)
           Ax++;
       N = N >> 1;
    }
    return Ax;
}


Answer

 .Ones   Macro    A
        local    L
        ifB      <&A>
                 exitm
        endif

        Mov      Ax, 0
        Push     Cx
        Mov      Cx, &A
    while&L:
        Cmp      Cx, 0
        Jne      do&L
        Jmp      endwhile&L
     do&L:
      if&L:
        Shr      Cx
        Jc       then&L
        Jmp      endif&L
      then&L:
        Inc      Ax
      endif&L:
        Jmp      while&L
  endwhile&L:
        Pop      Cx
endM  
5. (18) Short Coding

a. Using either the AND or the OR operation, convert an 'A'-'Z' character (41h-5Ah) in the AL register to 'a'-'z' (61h-7Ah).

Or    Al, 00100000B
b. Rotate Si register 5 bits to the left through the carry flag.
Mov    Cl, 5
RCL    Si, Cl
c. Position the Carry Flag to bit 4 of BL.
Mov    Cl, 4
RCR    Bl, Cl
d. Branch to label ODD if the LEAST significant bit of AL is 1.
Test    Al, 00000001B
Jnz      ODD
e. Branch to label READY if bit 7 = 1 and bit 5 = 0 of Al, ignore the rest.
And    Al, 10100000B
Cmp   Al, 10000000B
Je       READY
f. Given 48-bit integers X=Ax:Bx:Cx and Y=Dx:Si:Di, compute X=X+Y.
Add    Cx, Di
Adc    Bx, Si
Adc    Ax, Dx
6. (15) In the following indicate the value in the AL register and the designated flag after execution of instructions.
        
     a.   MOV  AL,01001010B                   ZF = _0_
          AND  AL,0AH                         AL = _00001010_

     b.   MOV  AL,41H                         ZF = _1_
          AND  AL,20H                         AL = _00000000_

     c.   MOV  AL,00011100B                   ZF = _0_
          STC                                 CF = _0_
          RCR  AL,1                           AL = _10001110_

     d.   MOV  CL,5
          CLC                                 ZF = _0_
          MOV  AL,0EEH                        CF = _1
          SAL  AL,CL                          AL = __11000000_

     e.   MOV  CL, 4                          ZF = _          MOV  AL,10100000B                   CF = _0_
          SAR  AL, CL                         AL = __11111010_

     f.   MOV  AL, 10010001B                  ZF = _0_
          TEST AL, 10000001B                  AL = _10010001_