Appendix B

Answers to Select Problems

Chapter 1 Number Systems and Number Representations

  1. 1.5 Convert the octal number 173.258 to decimal.

    473.268=(4×82)+(7×81)+(3×80)+(2×81)+(6×82)=(256+56+3+0.25+0.09375)10=315.3437510

  2. 1.9 Add the following binary numbers to yield a 12-bit sum:

    1111   1111   11111111   1111   11111111   1111   11111111   1111   1111_1111   1111   1100

  3. 1.16 Multiply the unsigned binary numbers 11112 and 00112.

    image

  4. 1.19 The numbers shown below are in sign-magnitude representation. Convert the numbers to 2s complement representation for radix 2 with the same numerical value using eight bits.

    Sign magnitude

    2s complement

    1001 1001

    – 25

    1110 0111

    0001 0000

    + 16

    0001 0000

    1011 1111

    – 63

    1100 0001

  5. 1.21 Add the following BCD numbers:

    10011000+)10010111_        1_1111100110110_0110_01011001000110010101

Chapter 2 X86 Processor Architecture

  1. 2.3 The 7-bit code words shown below are received using Hamming code with odd parity. Determine the syndrome word for each received code word.

    1. (a) Bit Position=1234567Received Code Word=1111111Syndrome Word=111

    2. (b) Bit Position=1234567Received Code Word=0000000Syndrome Word=111

  2. 2.7 Obtain the code word using the Hamming code with odd parity for the following message word: 1 1 0 1 0 1 0 1 1 1 1.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    0

    0

    1

    1

    1

    0

    1

    0

    0

    1

    0

    1

    1

    1

    1

    2.13 A fraction and the bits to be deleted (low-order three bits) are shown below. Determine the rounded results using truncation (round toward zero), adder-based rounding (round to nearest), and von Neumann rounding.

    Fraction

    .

    0

    0

    1

    0

    1

    0

    0

    1

    1

    0

    1

    Truncation:.0010  1001Adder-based:.0010  1010von Neumann:.0010  1001

Chapter 3 Addressing Modes

  1. 3.3 Let DS = 1100H, DISPL = –126, and SI = 0500H. Using the real addressing mode with a 20-bit address, determine the physical memory address for the instruction shown below.

    MOV DISPL[SI], DX

    image

  2. 3.6 Differentiate between the operation of the following two move instructions:

    (a) MOV EBX, 1234ABCDH
    (b) MOV [EBX], 1234H
    1. (a) Moves the immediate value of 1234ABCDH to register EBX.

    2. (b) Moves the immediate value of 1234H to the address pointed to by register EBX.

Chapter 4 C Programming Fundamentals

  1. 4.3 Write a program to change the following Fahrenheit temperatures to centigrade temperatures: 32.0, 100.0, and 85.0. Then print the results.

    //fahr_to_cent.cpp
    //change Fahrenheit to centigrade

    #include "stdafx.h"

    int main (void)
    {
      float fahr1 = 32.0;
      float fahr2 = 100.0;
      float fahr3 = 85.0;

      float cent1, cent2, cent3;

      cent1 = (fahr1 - 32) * (5.0/9.0);
      cent2 = (fahr2 - 32) * (5.0/9.0);
      cent3 = (fahr3 - 32) * (5.0/9.0);

      printf ("fahrenheit 32.0 = centigrade %f\n",
       cent1);
      printf ("fahrenheit 100.0 = centigrade %f\n",
       cent2);
      printf ("fahrenheit 85.0 = centigrade %f\n\n",
       cent3);

      return 0;
    }
    Fahrenheit 32.0 = centigrade 0.000000
    Fahrenheit 100.0 = centigrade 37.777779
    Fahrenheit 85.0 = centigrade 29.444445

    Press any key to continue . . . _
  2. 4.7 Write a program to illustrate the difference between integer division and floating-point division regarding the remainder, using the following dividends and divisors: 742 ÷ 16 and 1756 ÷ 24. For the floating-point result, let the integer be two digits and the fraction be four digits.

    //div_int_flp.cpp
    //show difference between integer division and
    //floating-point division regarding the remainder
    #include "stdafx.h"

    int main (void)
    {
      printf ("Integer division: %d\n", 742/16);
      printf ("Floating-point division:
         %2.4f\n\n", 742.0/16.0);

      printf ("Integer division: %d\n", 1756/24);
      printf ("Floating-point division:
         %2.4f\n\n", 1756.0/24.0);
      return 0;
    }
    Integer division: 46
    Floating-point division: 46.3750
    Integer division: 73 
    Floating-point division: 73.1667

    Press any key to continue . . . _
  3. 4.10 Indicate the value to which each of the following expressions evaluate.

    (a) (1 + * 3)

    Evaluates to 7.

    (b) 10 % 3 * 3 – (1 + 2)

    Evaluates to 0 (* and % same precedence).

    (c) ((1 + 2) * 3)

    Evaluates to 9 (1 + 2) first.

    (d) (5 = = 5)

    Evaluates to true (1)

    (e) (5 = 5)

    Evaluates to 5.

  4. 4.18 To what does the expression 5+3*8/2+2 evaluate?

    Rewrite the expression, adding parentheses, so that it evaluates to 16.

    //evaluate_expr.cpp
    //evaluate expression without parentheses,
    //then with parentheses
    #include "stdafx.h"
    int main (void)
    {
      int result1, result2;
      result1 = 5 + 3 * 8 / 2 + 2;
      result2 = (5 + 3) * 8 / (2 + 2);

      printf ("Result1 = %d \nResult2 = %d\n\n",
         result1, result2);
      return 0;
    }
    Result1 = 19
    Result2 = 16

    Press any key to continue . . . _
  5. 4.22 Given the program shown below, obtain the outputs for variables a and b after the program has executed.

    //pre_post_incr4.cpp
    //example to illustrate pre- and post-increment
    #include "stdafx.h"
    int main (void)
    {
      int a, b;
      int c = 0;
      a = ++c;
      b = c++;

      printf ("%d %d %d\n\n", a, b, ++c);
      return 0;
    }
    1 1 3

    Press any key to continue . . . _
  6. 4.30 Use a for () loop to count from 10 to 100 in increments of 10. Display the numbers on a single line.

    //for_loop4.cpp
    //use a for loop to count from 10 to 100
    //in increments of 10
    #include "stdafx.h"
    int main (void)
    {
      int int1;

      for (int1 = 10; int1 < 110; int1 = int1 + 10)
      printf ("%d ", int1);

      printf ("\n\n");
      return 0;
    }
    10 20 30 40 50 60 70 80 90 100

    Press any key to continue . . . _
  7. 4.33 Determine the number of As that are printed by the program shown below.

    //for_loop_nested.cpp
    //nested for loop to yield multiple outputs
    #include "stdafx.h"
    int main (void)
    {
      int x, y;

      for (x = 0; x < 5; x++)
      for (y = 5; y > 0; y--)
       printf ("A");

      printf ("\n\n");

      return 0;
    }
    AAAAAAAAAAAAAAAAAAAAAAAAA

    Press any key to continue . . . _
  8. 4.36 Write a program that defines a string, then prints the string. Then reverse the order of the original string and print the new string.

    //string_cpy_len.cpp
    //print a string in reverse order

    #include "stdafx.h"

    #include "string.h"

    int main (void)

    {
      char string[15];
      int i;

      strcpy (string, "54321 edcba");

      for (i=0; string[i]; i++)
      printf ("%c", string[i]);

      printf ("\n\n");

      for (i=strlen(string)-1; i>=0; i--)
      printf ("%c", string[i]);

      printf ("\n\n");

      return 0;
    }
    54321 edcba

    abcde 12345

    Press any key to continue . . . _
  9. 4.38 Write a program to illustrate pointer postincrement. Assign an integer int1 a value of 50 and assign a pointer variable the address of int1.

    //ptr_incr.cpp
    //program to illustrate pointer postincrement

    #include "stdafx.h"

    int main (void)
    {
      int int1 = 50;
      int *pointer = &int1;

      int1++;
      (*pointer)++;

      printf ("int1 = %d\n\n", *pointer);

      return 0;
    }
    int1 = 52

    Press any key to continue . . . _

Chapter 5 Data Transfer Instructions

  1. 5.3 The sign-magnitude notation for a positive number is represented by the equation shown below, where the sign bit of 0 indicates a positive number.

    A=(0 an2an3 ...  a1a0)r

    The sign-magnitude notation for a negative number is represented by the equation shown below, where the sign bit is the radix minus 1. In sign-magnitude notation, the positive version differs from the negative version only in the sign digit position. The magnitude portion an–2 an–3 ... a1a0 is identical for both positive and negative numbers of the same absolute value.

    A=[(r1) an2an3 ...  a1a0]r

    The numbers shown below are in sign-magnitude representation for radix 2. Convert the numbers to 2s complement representation with the same numerical value using eight bits.

    Sign-magnitude

    2s Complement

    (a)

    0111 1111

    0111 1111

    (b)

    1111 1111

    1000 0001

    (c)

    0000 1111

    0000 1111

    (d)

    1000 1111

    1111 0001

    (e)

    1001 0000

    1111 0000

  2. 5.4 Convert the positive 2s complement numbers shown below to negative numbers in 2s complement representation.

    0000  1100  00112(+19510)=1111  0011  11012(19510)0101  0101  01012(+136510)=1010  1010  10112(1365)

  3. 5.7 Write a program using C and assembly language that shows the application of the conditional move greater than or equal (CMOVGE) instruction for signed operands.

    //mov_cond3.cpp
    //uses cmovge (greater than or equal); sf xor of = 0.
    //if signed user-entered x is greater than or equal to
    //user-entered y, then print x; otherwise, print y.
    //if integers are equal, then print x

    #include "stdafx.h"

    int main (void)
    {
    //define variables
      int  x, y, rslt;

      printf ("Enter two signed integers: \n");
      scanf ("%d %d", &x, &y);

    //switch to assembly
     _asm
     {
       MOV  EAX, x
       MOV  EBX, y

       // move ebx to rslt if conditional move fails
       MOV  EDX, EBX
       CMP  EAX, EBX  //set flags

       //if eax >= ebx, move eax to rslt;
       //otherwise, move ebx to result
       CMOVGE  EDX, EAX
       MOV  rslt, EDX
    }

      printf ("Result = %d\n\n", rslt);

      return 0;
    }
    Enter two signed integers:
    –256 –128
    Result = –128

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two signed integers:
    555 444
    Result = 555

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two signed integers:
    –400 400
    Result = 400

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two signed integers:
    750 750
    Result = 750

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two signed integers:
    –800 –800
    Result = –800

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two signed integers:
    –100 –101
    Result = –100

    Press any key to continue . . . _
  4. 5.10 Write a program using C and assembly language that shows the application of the conditional move sign (CMOVS) instruction for signed operands. The compare instruction subtracts the second source operand from the first source operand and the state of the sign flag is set to either 0 or 1, depending on the sign of the result. If the sign of the difference is negative (SF = 1), then the move operation is executed.

    //mov_cond7.cpp
    //uses cmovs (sign is neg); sf = 1.
    //signed user-entered x is compared to user-entered y.
    //If sign flag is set, print x; otherwise, print y.

    #include "stdafx.h"

    int main (void)
    {
    //define variables
      int x, y, rslt;
      printf ("Enter two signed integers: \n");
      scanf ("%d %d", &x, &y);

    //switch to assembly
     _asm
     {
       MOV  EAX, x
       MOV  EBX, y
    //move ebx to rslt if conditional move fails

       MOV  EDX, EBX
       CMP  EAX, EBX //set flags
    //if sf = 1 (sign is neg), move eax to rslt;
    //otherwise, move ebx to result

       CMOVS EDX, EAX
       MOV  rslt, EDX
    }
      printf ("Result = %d\n\n", rslt);

      return 0;
    }
    Enter two signed integers:
    20000 2000  //4E20H 07D0H
    Result = 2000 //Difference = 4650H
        //Sign is positive

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter two signed integers:
    28000 30000  //6D60H 7530H
    Result = 2800 //Difference = F830H
        //Sign is negative

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter two signed integers:
    -4500 -6000  //EE6CH E890H
    Result = -6000  //Difference = 05DCH
        //Sign is positive

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter two signed integers:
    -6000 -4500  //E890H EE6CH
    Result = -6000  //Difference = FA24H
        //Sign is negative

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter two signed integers:
    750 -600   //02EEH FDA8H
    Result = -600  //Difference = 0546H
        //Sign is positive

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter two signed integers:
    -600 750   //FDA8H 02EEH
    Result = -600  //Difference = FABAH
        //Sign is negative

    Press any key to continue . . .

Chapter 6 Branching and Looping Instructions

  1. 6.3 Determine if an overflow occurs for the operation shown below. The operands are signed numbers in 2s complement representation.

    image

    No overflow, because (an1bn1sn1)=111

  2. 6.7 Determine whether the conditional jump instructions shown below will cause a jump to DEST.

    1. (a) 004FH + 200D JS DEST

      004FH + 00C8H = 0117H

      Sign is positive; therefore no jump.

    2. (b) FF38H + 200D JZ DEST

      FF38H + 00C8H = 1 ← 0000H

      Result is zero; therefore, a jump will occur.

  3. 6.11 Let AX = –405D. Determine whether the conditional jump instruction shown below will cause a jump to BRANCH_ADDR.

    CMP AX, FE6CH
    JGE BRANCH_ADDR

    For signed operands, a jump will not occur, because FE6CH (–404D)

    is greater than –405D (FE6BH).

  4. 6.13 Determine the number of times the following program segment executes the body of the loop:

      MOV  CX, –1
    LP1:  .
        .
        .
      LOOP  LP1   65,535 times.

Chapter 7 Stack Operations

  1. 7.3 Determine the result of each instruction for the following program segment:

    image

  2. 7.5 The partial contents of a stack are shown below before execution of the program segment listed below. Determine the contents of the stack after the program has been executed and indicate the new top of stack.

    image

    POP BX  ;BX = 11 E4 H
    MOV AH, BH  ;AX = 11 _ H
    ADD AH, BL  ;AX = F5 _ (E4 + 11 = F5)
    MOV BH, AH  ;BX = F5 E4 H   BL = E4
    PUSH BX  ;Stack = E4 F5 H   Low addr = E4
  3. 7.8 Write an assembly language program — using the PUSH and POP instructions — that adds four decimal integers, then displays their sum. Embed the assembly module in a C program. The decimal integers are entered from the keyboard.

    //push_pop_add_int.cpp
    //add four decimal integers using push and pop

    #include "stdafx.h"
    int main (void)
    {
    //define variables
      int dec1, dec2, dec3, dec4, sum_1234;

      printf ("Enter four decimal integers: \n");
      scanf ("%d %d %d %d", &dec1, &dec2, &dec3, &dec4);

    //switch to assembly
     _asm
     {
       MOV  EAX, dec1
       MOV  EBX, dec2
       ADD  EAX, EBX  ;dec1 + dec2 -> EAX
       PUSH  EAX   ;push dec1 + dec2

       MOV  EAX, dec3
       MOV  EBX, dec4
       ADD  EAX, EBX  ;dec3 + dec4 -> EAX

       POP  EBX   ;pop dec1 + dec2
       ADD  EAX, EBX  ;total sum -> EAX

       MOV  sum_1234, EAX ;move sum to result area
    }

      printf ("\nsum of four integers = %d\n\n",
       sum_1234);

    return 0;
    }
    Enter four decimal integers:
    1 2 3 4

    sum of four integers = 10

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter four decimal integers:
    25 50 75 100

    sum of four integers = 250

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter four decimal integers:
    1000 2000 3000 4000

    sum of four integers = 10000

    Press any key to continue . . . _
    -----------------------------------------------------
    Enter four decimal integers:
    37 1200 750 875

    sum of four integers = 2862

    Press any key to continue . . . _

Chapter 8 Logical, Bit, Shift, and Rotate Instructions

  1. 8.3 Using only logic instructions, write one instruction for each of the following parts that will perform the indicated operations.

    1. (a) Set the low-order four bits of register AX.

      OR AX, 000FH
    2. (b) Reset the high-order three bits of register AX.

      AND AX, 1FFFH
    3. (c) Invert bits 7, 8, and 9 of register AX.

      XOR AX, 0380H
  2. 8.8 Write an assembly language module embedded in a C program that uses the bit scan forward (BSF) instruction to detect whether the first bit detected is in the low-order half or the high-order half of a 32-bit operand. Do not determine the bit position.

    //bsf_if_struc.cpp
    //determine if first bit is in position <= 15 or > 15
    //using an if structure

    #include "stdafx.h"
    int main (void)
    {
    //define variables
      int bsf_src_opnd;

      printf ("Enter an 8-digit hexadecimal number: \n");
      scanf ("%X", &bsf_src_opnd);
    //switch to assembly
     _asm
     {
       MOV  EBX, bsf_src_opnd
       CMP  EBX, 0
       JZ   NO_ONES
       BSF  EAX, EBX
       CMP  EAX, 15
       JBE  LESS_THAN_16
       JMP  GREATER_THAN_15
    }

    NO_ONES:
      printf ("\nBSF opnd has no 1s\n\n");
      goto end;

    LESS_THAN_16:
      printf ("\nBit is in position 15 -- 0\n\n");
      goto end;

    GREATER_THAN_15:
      printf ("\nBit is in position 31 -- 16\n\n");

    end:
      return 0;
    }
    Enter an 8-digit hexadecimal number:
    00A07000

    Bit is in position 15 -- 0

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter an 8-digit hexadecimal number:
    7BC68000

    Bit is in position 15 -- 0

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter an 8-digit hexadecimal number:
    FFFF0001

    Bit is in position 15 -- 0

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter an 8-digit hexadecimal number:
    80D10000

    Bit is in position 31 -- 16

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter an 8-digit hexadecimal number:
    0DC00000

    Bit is in position 31 -- 16

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter an 8-digit hexadecimal number:
    80000000

    Bit is in position 31 -- 16

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter an 8-digit hexadecimal number:
    00000000

    BSF opnd has no 1s

    Press any key to continue . . . _
  3. 8.12 Determine the contents of register EBX and the flags register after execution of the program segment shown below. Then write an assembly language module embedded in a C program to verify the results.

    MOV EBX, 0FFFFA85BH
    SAL EBX, 20
    MOV EBX, 0FFFFA85BH
    SAR EBX, 20

    SAL result = 85B00000

    SAR result = FFFFFFFF

    SAL flags = 86

    SAR flags = 87

    //sal_sar.cpp
    //program to illustrate shift arithmetic left
    //and shift arithmetic right instructions
    //for the same operand

    #include "stdafx.h"
    int main (void)
    {
    //define variables
      int dst_opnd, sal_rslt, sar_rslt;
      unsigned char sal_flags, sar_flags;

      printf ("Enter an 8-digit hexadecimal number: \n");
      scanf ("%X", &dst_opnd);

    //switch to assembly
      _asm
      {
    //SAL instruction
      MOV EBX, dst_opnd
      SAL EBX, 20
      MOV sal_rslt, EBX
      LAHF
      MOV sal_flags, AH

    //SAR instruction
      MOV EBX, dst_opnd
      SAR EBX, 20
      MOV sar_rslt, EBX
      LAHF
      MOV sar_flags, AH
     }

      printf ("\nSAL result = %X\nSAL flags = %X\n\n",
       sal_rslt, sal_flags);

      printf ("\nSAR result = %X\nSAR flags = %X\n\n",
       sar_rslt, sar_flags);

      return 0;
    }
    Enter an 8-digit hexadecimal number:
    FFFFA85B

    SAL result = 85B00000
    SAL flags = 86

    SAR result = FFFFFFFF
    SAR flags = 87

    Press any key to continue . . . _
  4. 8.14 Write an assembly language module embedded in a C program that will multiply and divide a decimal number by eight using arithmetic shift instructions. When dividing, some numbers will have the fraction truncated.

    //sal_sar_2.cpp
    //shifting positive and negative numbers
    //using SAL and SAR instructions

    #include "stdafx.h"

    int main (void)
    {
    //define variables
      int dst_opnd, sal_rslt, sar_rslt;

      printf ("Enter a decimal number: \n");
      scanf ("%d", &dst_opnd);

    //switch to assembly
     _asm
     {
    //SAL instruction
      MOV  EAX, dst_opnd
      SAL  EAX, 3
      MOV  sal_rslt, EAX
    //SAR instruction
      MOV  EAX, dst_opnd
      SAR  EAX, 3
      MOV  sar_rslt, EAX
    }

      printf ("\nSAL result = %d\n", sal_rslt);

      printf ("SAR result = %d\n\n", sar_rslt);

      return 0;
    }
    Enter a decimal number:
    8

    SAL result = 64
    SAR result = 1

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal number:
    –8

    SAL result = –64
    SAR result = –1

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal number:
    –10

    SAL result = –80
    SAR result = –2   //1.25; 1111 ... 1111 0110
          //1111 ... 1111 1110
    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal number:
    25

    SAL result = 200
    SAR result = 3  //3.125; 0000 ... 0001 1001
          //0000 ... 0000 0011
    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal number:
    –25

    SAL result = –200
    SAR result = –4   //–3.125; 1111 ... 1110 0111
          //1111 ... 1111 1100
    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal number:
    500

    SAL result = 4000
    SAR result = 62   //62.5; 0000 ... 0001 1111 0100
          //0000 ... 0000 0011 1110
    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal number:
    1000

    SAL result = 8000
    SAR result = 125

    Press any key to continue . . . _
  5. 8.16 Let register EAX contain AD3E14B5H and the carry flag be set. Determine the contents of register EAX after the following instruction is executed:

    CF

    RCL EAX, 6

    1

    1010

    1101

    0011

    1110

    0001

    0100

    1011

    0101

    1

    0101

    1010

    0111

    1100

    0010

    1001

    0110

    1011

    After 1 shift

    0

    1011

    0100

    1111

    1000

    0101

    0010

    1101

    0111

    After 2 shifts

    1

    0110

    1001

    1111

    0000

    1010

    0101

    1010

    1110

    After 3 shifts

    0

    1101

    0011

    1110

    0001

    0100

    1011

    0101

    1101

    After 4 shifts

    1

    1010

    0111

    1100

    0010

    1001

    0110

    1011

    1010

    After 5 shifts

    1

    0100

    1111

    1000

    0101

    0010

    1101

    0111

    0101

    After 6 shifts

Chapter 9 Fixed-Point Arithmetic Instructions

  1. 9.3 Indicate whether an overflow occurs for the operation shown below. The numbers are in radix complementation for radix 3.

    image

    No overflow, because a positive and negative number are being added.

    The sign for a positive number is 0.

    The sign for a negative number is r1=31=2.

  2. 9.6 Determine the contents of registers AL and BL after the program segment shown below has executed. Then write an assembly language module embedded in a C program to verify the results.

    AL BL

    AL BL

    AL BL

    AL BL

    AL BL

    MOV

    AL, 00H

    0

    MOV

    BL, -5

    0

    L00P1:

    ADD

    BL, 2

    0 -3

    1 -2

    2 -1

    3 0

    4 1

    INC

    AL

    1 -3

    2 -2

    3 -1

    4 0

    5 1

    ADD

    BL, -1

    1 -4

    2 -3

    3 -2

    4 -1

    5 0

    JNZ

    LOOP1

    //inc_al_dec_bl.cpp
    //program to determine the contents of registers
    //AL and BL after a program has executed
    #include "stdafx.h"
    int main (void)
    {
    //define variables
      char al_sum, bl_sum;
    //switch to assembly
     _asm
     {
       MOV  AL, 00H
       MOV  BL, -5
    LOOP1: ADD  BL, 2
       INC  AL
       ADD  BL, -1
       JNZ  LOOP1
       MOV  al_sum, AL
       MOV  bl_sum, BL
    }
      printf ("\nAL = %d\nBL = %d\n\n", al_sum, bl_sum);
      return 0;
    }
    AL = 5
    BL = 0

    Press any key to continue . . . _
  3. 9.9 Write an assembly language program — not embedded in a C program — that removes all nonletters from a string of characters that are entered from the keyboard.

    PAGE 66, 80
    ;non letters.asm
    ;----------------------------------------------------
    .STACK

    ;----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 40
    ACTLEN DB ?
    OPFLD  DB 40 DUP(?)
    PRMPT  DB 0DH, 0AH, 'Enter text $'
    RSLT DB 0DH, 0AH, 'Result =   $'

    ;----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV  AX, @DATA
      MOV  DS, AX

    ;read prompt
      MOV  AH, 9
      LEA  DX, PRMPT
      INT  21H

    ;kybd rtn to enter characters
      MOV  AH, 0AH
      LEA  DX, PARLST
      INT  21H

      MOV  CL, ACTLEN ;get # of chars entered
      MOV  CH, 0

      LEA  SI, OPFLD ;source addr to si
      LEA  DI, RSLT + 11 ;destination addr to di

    LP1: MOV  AL, [SI]  ;get char in opfld
      CMP  AL, 41H  ;compare to uppercase A
      JL   LP2   ;if < A, jump
      CMP  AL, 5AH  ;compare to uppercase Z
      JLE  LP4   ;if between A and Z, jump

      CMP  AL, 7AH  ;compare to lowercase z
      JG   LP2   ;if > z, jump
      CMP  AL, 61H  ;compare to lowercase a
      JL   LP2   ;if < a, jump

    LP4: MOV  [DI], AL  ;move valid char to dst
      INC  DI   ;inc di to next dst

    LP2: INC  SI   ;addr of next character
      LOOP  LP1   ;jump, get char in opfld

    ;display result
      MOV  AH, 09H
      LEA  DX, RSLT
      INT  21H

    BEGIN ENDP
      END  BEGIN
    Enter text: the6h7h
    Result = the
    ------------------------------------------------------
    Enter text: 7HD3e23kl
    Result = HDekl
    ------------------------------------------------------
    Enter text: 1234567879A
    Result = A
    ------------------------------------------------------
    Enter text: ABcdEF7
    Result = ABcdEF
    ------------------------------------------------------
    Enter text: abcdefghij
    Result = abcdefghij
    ------------------------------------------------------
    Enter text: 123456789
    Result =
  4. 9.17 Let register AL = 61H (9710). Then execute the instruction shown below to obtain the difference and the state of the following flags: OF, SF, ZF, AF, PF, and CF.

    SUB AL, 65H ;65H = 10110

    image

  5. 9.21 Write an assembly language program — not embedded in a C program — to reverse the order and change to uppercase all letters that are entered from the keyboard. The letters that are entered may be lowercase or uppercase.

    ;reverse uppercase
    PAGE 66, 80
    ;-----------------------------------------------------
    .STACK
    ;-----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 40
    ACTLEN DB ?
    OPFLD  DB 40  DUP(?)
    PRMPT  DB 0DH, 0AH, 'Enter characters: $'
    RSLT DB 0DH, 0AH, 'Result =    $'

    .CODE
    BEGIN PROC FAR

    ;setup pgm ds
      MOV  AX, @DATA  ;get addr of data seg
      MOV  DS, AX   ;move addr to ds

    ;read prompt
      MOV  AH, 09H   ;display string
      LEA  DX, PRMPT  ;put addr of prompt in dx
      INT  21H   ;dos interrupt

    ;keyboard request rtn to enter characters
      MOV  AH, 0AH   ;buffered keyboard input
      LEA  DX, PARLST   ;put addr of parlst in dx
      INT  21H   ;dos interrupt

    ;setup count and addresses
      MOV  CL, ACTLEN   ;number of characters
      MOV  CH, 0    ;... entered
      MOV  BX, CX   ;bx is displacement
      DEC  BX
      LEA  SI, OPFLD[BX] ;addr of last character
      LEA  DI, RSLT + 11 ;setup destination addr

    ;change to uppercase and reverse order
    SWAP: MOV  AL, [SI]  ;move character to al
      CMP  AL, 61H   ;compare to lowercase
      JL UPPER    ;jump if uppercase
      SUB  AL, 20H   ;if lowercase, change to
            ;uppercase
    UPPER:  MOV  [DI], AL  ;move char to result area
      DEC  SI
      INC  DI
      LOOP SWAP   ;loop if cx !=0

    ;display result
      MOV  AH, 09H   ;display string
      LEA  DX, RSLT  ;put addr of rslt in dx
      INT  21H   ;dos interrupt

    BEGIN ENDP
      END  BEGIN
    Enter characters: aBCdeFGh
    Result = HGFEDCBA
    ------------------------------------------------------
    Enter characters: ihgfedcba
    Result = ABCDEFGHI
    ------------------------------------------------------
    Enter characters: ABCDEFGHIJ
    Result = JIHGFEDCBA
  6. 9.23 Write an assembly language program — not embedded in a C program — to sort n single-digit numbers in ascending numerical order that are entered from the keyboard. A simple exchange sort is sufficient for this program. The technique is slow, but appropriate for sorting small lists. The method is as follows:

    1. Search the list to find the smallest number.

    2. After finding the smallest number, exchange this number with the first number.

    3. Search the list again to find the next smallest number, starting with the second number.

    4. Then exchange this (second smallest) number with the second number.

    5. Repeat this process, starting with the third number, then the fourth number, etc.

    ;sort n numbers2.asm

    ;-----------------------------------------------------
    .STACK
    ;-----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 15
    ACTLEN DB ?
    OPFLD DB 15 DUP(?)
    PRMPT DB 0DH, 0AH, ‘Enter numbers: $’
    RSLT  DB 0DH, 0AH, ‘Sorted numbers =   $’

    ;-----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV AX, @DATA   ;get addr of data seg
      MOV DS, AX   ;move addr to ds

    ;read prompt
      MOV AH, 09H    ;display string
      LEA DX, PRMPT   ;put addr of prompt in dx
      INT 21H    ;dos interrupt

    ;keyboard request rtn to enter characters
      MOV AH, 0AH    ;buffered keyboard input
      LEA DX, PARLST  ;put addr of parlst in dx
      INT 21H    ;dos interrupt

    ;sort numbers
      LEA SI, OPFLD   ;addr of first byte to si
      MOV DL, ACTLEN  ;# of bytes to dx
      MOV DH, 00H    ;... as loop ctr
      DEC DX     ;loop ctr - 1

    LP1:  MOV CX, DX   ;cx is loop2 ctr

    LP2:  MOV AL, [SI]   ;number to al
      MOV BX, CX   ;bx is base addr
      CMP AL, [BX+SI]  ;is number <= to al?
      JBE NEXT    ;number is <=; get next #
      XCHG AL, [BX+SI]  ;number is !<=; put in al
      MOV [SI], AL   ;put # in input buffer

    NEXT: LOOP LP2    ;loop until #s compared
      INC SI     ;point to next number
      DEC DX     ;dec internal loop ctr
      JNZ LP1    ;compare remaining #s

    ;set up src (opfld) and dst (rslt)
      LEA SI, OPFLD
      LEA DI, RSLT+20
      MOV CL, ACTLEN
      MOV CH, 00H    ;cx is counter

    ;move sorted numbers to input buffer
    INP_BUFF:
      MOV BL, [SI]   ;opfld to bl
      MOV [DI], BL   ;byte to result area
      INC SI
      INC DI
      LOOP INP_BUFF

    ;display sorted numbers
      MOV AH, 09H    ;display string
      LEA DX, RSLT   ;put addr of rslt in dx
      INT 21H    ;dos interrupt

    BEGIN ENDP
      END BEGIN
    Enter numbers: 7658943034
    Sorted numbers = 0334456789
    ------------------------------------------------------
    Enter numbers: 7548391235
    Sorted numbers = 1233455789
    ------------------------------------------------------
    Enter numbers: 9876543210
    Sorted numbers = 0123456789
  7. 9.27 Determine the hexadecimal contents of register AX after the following program segment has been executed:

      MOV  CX, 3
      MOV  AX, 2  ;AX = 2
    LP1: MUL  AX  ;AX = 4 16  256
      LOOP LP1   ;CX = 3 2 1

    AX = 0000 0001 0000 0000
  8. 9.30 Write an assembly language module embedded in a C program that uses the three-operand form for signed multiplication. Enter a signed decimal multiplicand from the keyboard and assign an immediate multiplier for the IMUL operation. Display the multiplicand, the multiplier, and the product.

    //imul_3_opnds.cpp
    //signed decimal multiplication using 3 operands

    #include "stdafx.h"
    int main (void)
    {
    //define variables
      long mpcnd, product;

      printf ("Enter a signed decimal multiplicand: \n");
      scanf ("%d", &mpcnd);

    //switch to assembly
     _asm
     {
       MOV  EBX, mpcnd
       IMUL EAX, EBX, 10 ;EAX = EBX x 10
       MOV  product, EAX
    }

     printf ("\nMultiplicand = %d", mpcnd);
     printf ("\nMultiplier = 10");
     printf ("\nProduct = %d\n\n", product);

     return 0;
    }
    Enter a signed decimal multiplicand:
    450

    Multiplicand = 450
    Multiplier = 10
    Product = 4500

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a signed decimal multiplicand:
    –5

    Multiplicand = –5
    Multiplier = 10
    Product = –50

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a signed decimal multiplicand:
    6000

    Multiplicand = 6000
    Multiplier = 10
    Product = 60000

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a signed decimal multiplicand:
    –6000

    Multiplicand = –6000
    Multiplier = 10
    Product = –60000

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a signed decimal multiplicand:
    65535

    Multiplicand = 65535
    Multiplier = 10
    Product = 655350

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a signed decimal multiplicand:
    –65535

    Multiplicand = –65535
    Multiplier = 10
    Product = –655350

    Press any key to continue . . . _
  9. 9.34 Write an assembly language module embedded in a C program to perform unsigned division (DIV) on two decimal integers that are entered from the keyboard. Print the dividend, divisor, quotient, and remainder.

    //div.cpp
    //unsigned division of two integers
    #include "stdafx.h"
    int main (void)
    {
    //define variables
      unsigned short dvdnd, dvsr, quot, rem;

      printf ("Enter a decimal dividend and divisor: \n");
      scanf ("%d %d", &dvdnd, &dvsr);

    //switch to assembly
     _asm
     {
       MOV  AX, dvdnd
       CWD
       DIV  dvsr
       MOV  quot, AX
       MOV  rem, DX
    }
      printf ("\nDividend = %d\nDivisor = %d\n",
       dvdnd, dvsr);
      printf ("\nQuotient = %d\nRemainder = %d\n\n",
       quot, rem); 
      return 0;
    }
    Enter a decimal dividend and divisor:
    450 20

    Dividend = 450
    Divisor = 20

    Quotient = 22
    Remainder = 10

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal dividend and divisor:
    25000 250

    Dividend = 25000
    Divisor = 250

    Quotient = 100
    Remainder = 0

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal dividend and divisor:
    25000 30

    Dividend = 25000
    Divisor = 30

    Quotient = 833
    Remainder = 10

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter a decimal dividend and divisor:
    4660 86

    Dividend = 4660
    Divisor = 86

    Quotient = 54
    Remainder = 16

    Press any key to continue . . . _
  10. 9.38 Write an assembly language module embedded in a C program that evaluates the expression shown below, where x=40010(019016), y=510(000516), z=100010(03E816), and v=400010(0FA016).

    [v(x×y+z500)]/x

    [v(x×y+z500)]/x=[4000(400×5+1000500)]/400=[40002500]/400=1500/400=3.75=Quotient=310(316),Remainder=30010(12C16)

    //solve_eqn.cpp
    //use imul, add, sub, and idiv to solve the equation:
    //[V - (X x Y + Z - 500)]/X

    #include "stdafx.h"

    int main (void)
    {
    //define variables
      short x, y, z, v, quot, rem;

      x = 0x0190;
      y = 0x0005;
      z = 0x03E8;
      v = 0x0FA0;

    //switch to assembly
     _asm
     {
    //X x Y
       MOV  AX, x
       IMUL y
       MOV  CX, AX
       MOV  BX, DX

    //+Z
       MOV  AX, z
       CWD
       ADD  CX, AX
       ADC  BX, DX

    //-500
       SUB  CX, 01F4H  //500
       SBB  BX, 0

    //V-()
       MOV  AX, v
       CWD
       SUB  AX, CX
       SBB  DX, BX

    ///400
       IDIV x

    //move ax to quotient and dx to remainder
       MOV  quot, AX
       MOV  rem, DX
    }

      printf ("\nQuotient = %X, Remainder = %X\n\n",
       quot, rem);
      return 0;
    }
    Quotient = 3, Remainder = 12C

    Press any key to continue . . . _

Chapter 10 Binary-Coded Decimal Arithmetic Instructions

  1. 10.5 In each part below, assume that the following instructions are executed:

    ADD AL, BL
    DAA
    1. (a) Give the values of AL after the ADD instruction has been executed, but before the DAA instruction has been executed for the indicated register values shown below.

    2. (b) Give the values of AL, the carry flag (CF), and the auxiliary carry flag (AF) after the DAA instruction has been executed for the indicated register values shown below.

    After ADD

    After DAA

    CF

    AF

    (1) AL = 35H, BL = 48H

    Sum = 7DH

    Sum = 83

    0

    1

    (2) AL = 47H, BL = 61H

    Sum = A8H

    Sum = 08

    1

    0

    (3) AL = 75H, BL = 46H

    Sum = BBH

    Sum = 21

    1

    1

    Then write an assembly language module embedded in a C program to verify the results.

    //daa3.cpp
    //illustrates the use of the daa instruction
    #include "stdafx.h"

    int main (void)
    {
    //define variables
      unsigned char augend, addend, add_sum, daa_sum,
         flags;

      printf ("Enter two 2-digit hexadecimal numbers:
      \n");
      scanf ("%X %X", &augend, &addend);
    //switch to assembly
      _asm
      {
    //obtain sum
      MOV AL, augend
      ADD AL, addend
      MOV add_sum, AL
      DAA
      MOV daa_sum, AL
    //save flags
      PUSHF
      POP AX
      MOV flags, AL
     }
      printf ("\nAugend = %X, Addend = %X\n",
       augend, addend);
      printf ("\nADD sum = %X, DAA sum = %X\n",
       add_sum, daa_sum);
      printf ("Flags = %X\n\n", flags);
      return 0;
    }
    Enter two 2-digit hexadecimal numbers:
    35 48

    Augend = 35, Addend = 48

    ADD sum = 7D, DAA sum = 83  //DAA sum = 083
    Flags = 92    //SF, AF

    Press any key to continue . . . _
    ------------------------------------------------------
    ------------------------------------------------------
    Enter two 2-digit hexadecimal numbers:
    47 61

    Augend = 47, Addend = 61

    ADD sum = A8, DAA sum = 8  //DAA sum = 108
    Flags = 3    //CF

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two 2-digit hexadecimal numbers:
    75 46

    Augend = 75, Addend = 46

    ADD sum = BB, DAA sum = 21  //DAA sum = 121
    Flags = 17    //AF, PF, CF

    Press any key to continue . . . _
  2. 10.8 Perform a subtraction and adjustment of the following two operands: 07 – 09. Show the details of the subtraction and adjustment.

    image

  3. 10.17 Write an assembly language program — not embedded in a C program — that multiplies a five-digit multiplicand by a one-digit multiplier using the MUL instruction in combination with the AAM instruction. The ADD instruction and the AAA instruction will also be used in implementing the program.

    The five-digit multiplicand and the one-digit multiplier are entered from the keyboard and stored in the OPFLD, as shown below using a multiplicand of 12345 and a multiplier of 6. Enter several different multiplicands and multipliers, then display the operands and the resulting product.

    image

    The paper-and-pencil example shown below may help to illustrate the algorithm used in the program.

    image

    ;aam4.asm
    ;obtain the product of a 5-digit multiplicand
    ;and a 1-digit multiplier
    ; -----------------------------------------------------
    .STACK

    ; -----------------------------------------------------
    .DATA
    PARLST  LABEL BYTE
    MAXLEN  DB 10
    ACTLEN  DB ?
    OPFLD DB 10 DUP(?)
    PRMPT DB 0DH, 0AH, 'Enter 5-digit mpcnd and
          1-digit mplyr: $'
    RSLT DB 0DH, 0AH, 'Product =  $'
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV AX, @DATA ;get addr of data seg
      MOV DS, AX   ;move addr to ds

    ;read prompt
      MOV AH, 09H  ;display string
      LEA DX, PRMPT ;put addr of prompt in dx
      INT 21H   ;dos interrupt

    ;keyboard request rtn to enter characters
      MOV AH, 0AH  ;buffered keyboard input
      LEA DX, PARLST ;put addr of parlst in dx
      INT 21H   ;dos interrupt

    ; -----------------------------------------------------
    ;perform the multiplication
      MOV CX, 05   ;five loops

      LEA SI, OPFLD+4  ;si = addr of low-order
           ;mpcnd digit
      LEA DI, RSLT+17  ;di = addr of low-order
           ;product digit
      AND OPFLD+5, 0FH ;unpack multiplier

    LP1: MOV AL, [SI]  ;get next low-order
           ;mpcnd digit
      AND AL, 0FH  ;unpack it
      MUL OPFLD+5  ;multiply by the mplyr
      AAM    ;adjust the product
      ADD AL, [DI]  ;add low-order product
           ;digit to al
      AAA    ;adjust the sum
      OR  AL, 30H  ;add ascii bias
      MOV [DI], AL  ;move to low-order
           ;result area
      DEC DI   ;get addr of next
           ;low-order result area
      OR  AH, 30H  ;add ascii bias
      MOV [DI], AH  ;move to next low-order
           ;result area

      DEC SI   ;address next high-order
           ;mpcnd digit
      LOOP LP1   ;loop if cx != 0
    ;display product
      MOV AH, 09H  ;display string
      LEA DX, RSLT  ;addr of product in dx
      INT 21H   ;dos interrupt
    BEGIN ENDP
      END BEGIN
    Enter 5-digit mpcnd and 1-digit mplyr: 123456
    Product = 074070
    ------------------------------------------------------
    Enter 5-digit mpcnd and 1-digit mplyr: 007899
    Product = 007101
    ------------------------------------------------------
    Enter 5-digit mpcnd and 1-digit mplyr: 999999
    Product = 899991
    ------------------------------------------------------
    Enter 5-digit mpcnd and 1-digit mplyr: 556667
    Product = 389662
    ------------------------------------------------------
    Enter 5-digit mpcnd and 1-digit mplyr: 111118
    Product = 088888
    ------------------------------------------------------
    Enter 5-digit mpcnd and 1-digit mplyr: 765432
    Product = 153086
  4. 10.19 Repeat Problem 10.18, this time using an assembly language module embedded in a C program. Note the simplicity of this program. There is no requirement to remove the ASCII bias for the numbers that are entered from the keyboard, or to restore the ASCII bias before displaying the hours, minutes, and seconds. It is also not necessary to establish stack or data segments. The range is the same: 10,000 to 60,000 seconds.

    //hrs_min_sec.cpp
    //given a 5-digit number of seconds, calculate the
    //equivalent number of hours, minutes, and seconds
    #include "stdafx.h"
    int main (void)
    {
     unsigned short seconds, hrs, min, sec;

     printf ("Enter 5-digit #: range 10000 -- 60000:
       \n");
     scanf ("%d", &seconds);
    //switch to assembly
      _asm
      {
       MOV DX, 0
       MOV AX, seconds
       MOV BX, 3600
       DIV BX
       MOV hrs, AX
       MOV AX, DX
       MOV DX, 0
       MOV BX, 60
       DIV BX
       MOV min, AX
       MOV sec, DX}

     printf ("\nHours = %d", hrs);
     printf ("\nMinutes = %d", min);
     printf ("\nSeconds = %d\n\n", sec);

     return 0;
    }
    Enter 5-digit #: range 10000 -- 60000:
    43210

    Hours = 12
    Minutes = 0
    Seconds = 10

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000:
    10000

    Hours = 2
    Minutes = 46
    Seconds = 40

    Press any key to continue . . . _
    ------------------------------------------------------

    Enter 5-digit #: range 10000 -- 60000:
    00060

    Hours = 0
    Minutes = 1
    Seconds = 0

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 5-digit #:range 10000 -- 60000:
    00059

    Hours = 0
    Minutes = 0
    Seconds = 59

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 5-digit #:range 10000 -- 60000:
    20000

    Hours = 5
    Minutes = 33
    Seconds = 20

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000:
    39760

    Hours = 11
    Minutes = 2
    Seconds = 40

    Press any key to continue . . . _
  5. 10.20 Write an assembly language program to repeat Problem 10.18 — not embedded in a C program — that calculates the number of hours, minutes, and seconds from a number of seconds that are entered from the keyboard. This time use a loop to calculate the sum that is represented by the digits that are entered from the keyboard. The number of seconds entered ranges from 10,000 to 60,000. Enter several different 5-digit numbers of seconds. This program will use the MUL, DIV, and AAM instructions.

    ;hrs_min_sec2.asm
    ;given a 5-digit number of seconds,
    ;calculate the equivalent number of
    ;hours, minutes, and seconds

    ; ----------------------------------------------------
    .STACK

    ; ----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 10
    ACTLEN DB ?
    OPFLD  DB 10 DUP(?)
    PRMPT  DB 0DH, 0AH, 'Enter 5-digit #:
         range 10000 -- 60000: $'
    SUM DW 8 DUP(0)
    HOURS  DB 0DH, 0AH, ‘Hours =  $’
    MINUTES DB 0DH, 0AH, ‘Minutes =  $’
    SECONDS DB 0DH, 0AH, ‘Seconds =  $’

    ; ----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ; ----------------------------------------------------
    ;set up pgm ds
       MOV AX, @DATA  ;get addr of data seg
       MOV DS, AX  ;move addr to ds

    ;read prompt
       MOV AH, 09H  ;display string
       LEA DX, PRMPT  ;put addr of prompt in dx
       INT 21H    ;dos interrupt

    ;keyboard request rtn to enter characters
       MOV AH, 0AH  ;buffered keyboard input
       LEA DX, PARLST  ;put addr of parlst in dx
       INT 21H    ;dos interrupt

    ; ----------------------------------------------------
    ;obtain the 5-digit number as a sum
       LEA SI, OPFLD  ;addr of first digit
       MOV BX, 10000  ;bx = 2710h
       MOV CX, 5   ;five loops
    LP1: MOV AL, [SI]   ;get next digit
       AND AL, 0FH  ;unpack it
       MOV AH, 00H  ;ax = 00 al
       MUL BX   ;dx ax = product
       ADD SUM, AX  ;accumulate sum

       MOV AX, BX  ;move multiply amount
          ;to ax for divide
       MOV DX, 00H  ;dx ax = 00 ax
       MOV DI, 10  ;10 is the divisor
       DIV DI   ;divide bx (ax) by 10
       MOV BX, AX  ;move quot in ax to bx
       INC SI   ;si points to next digit
       LOOP LP1    ;loop if cx != 0
    ; ----------------------------------------------------

    ;calculate the hours
       MOV DX, 0   ;clear dx
       MOV AX, SUM  ;move sum to ax
       MOV BX, 3600   ;to divide ax for hours
       DIV BX   ;quot (hrs) in ax;
          ;rem (min) in dx
       AAM     ;2 unpacked bcd #s in ax
       OR  AX, 3030H  ;add ascii bias
       MOV HOURS+10, AH ;move units hours
       MOV HOURS+11, AL ;move tens hours

    ;calculate the minutes
       MOV AX, DX  ;move rem (min) to ax
       MOV DX, 0   ;clear dx
       MOV BX, 60  ;to divide ax for min
       DIV BX   ;quot (min) in ax;
          ;rem (sec) in dx
       AAM     ;2 unpacked bcd #s in ax
       OR  AX, 3030H  ;add ascii bias
       MOV MINUTES+12, AH ;move units minutes
       MOV MINUTES+13, AL ;move tens minutes

    ;calculate the seconds
       MOV AX, DX  ;move rem (sec) to ax
       MOV DX, 0   ;clear dx
       AAM     ;2 unpacked bcd #s in ax
       OR  AX, 3030H  ;add ascii bias
       MOV SECONDS+12, AH ;move units seconds
       MOV SECONDS+13, AL ;move tens seconds
    ; ----------------------------------------------------
    ;display hours
       MOV AH, 09H   ;display string
       LEA DX, HOURS  ;put addr of hours in dx
       INT 21H    ;dos interrupt

    ;display minutes
       MOV AH, 09H   ;display string
       LEA DX, MINUTES ;put addr of min in dx
       INT 21H    ;dos interrupt

    ;display seconds
       MOV AH, 09H   ;display string
       LEA DX, SECONDS ;put addr of sec in dx
       INT 21H    ;dos interrupt

    ; ----------------------------------------------------
    BEGIN  ENDP
       END BEGIN
    Enter 5-digit #: range 10000 -- 60000: 43210
    Hours = 12
    Minutes = 00
    Seconds = 10
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 10000 
    Hours = 02
    Minutes = 46
    Seconds = 40
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 12345 
    Hours = 03
    Minutes = 25
    Seconds = 45
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 00060 
    Hours = 00
    Minutes = 01
    Seconds = 00
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 00059
    Hours = 00
    Minutes = 00
    Seconds = 59
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 20000 
    Hours = 05
    Minutes = 33
    Seconds = 20
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 39760 
    Hours = 11
    Minutes = 02
    Seconds = 40
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 60000 
    Hours = 16
    Minutes = 40
    Seconds = 00
    ------------------------------------------------------
    Enter 5-digit #: range 10000 -- 60000: 50000 
    Hours = 13
    Minutes = 53
    Seconds = 20

Chapter 11 Floating-Point Arithmetic Instructions

  1. 11.4 The floating-point number shown below has an unbiased exponent and an unnormalized fraction. Show the same floating-point number with a biased exponent and a normalized fraction in the single-precision floating-point format.

    image

    Add bias: 1011  0011+0111  1111=0011  0010 (for unnormalized fraction) Normalize: shift fraction left 4 to yield an implied 1

    image

  2. 11.10 Write an assembly language module embedded in a C program that uses the add (FADDP) instruction and the add (FIADD) instruction. For the FADDP instruction, use the FADDP ST(i), ST(0) version. Enter three floating-point numbers and one integer number from the keyboard. Display the results of the program and show the register stack for each sequence of the program.

    //fadd_versions2.cpp
    //show the use of the FADDP and FIADD instructions

    #include "stdafx.h"

    int main (void)
    {
    //define variables
      float flp1_num, flp2_num, flp3_num, int1_num,
      flp_rslt1, flp_rslt2, flp_rslt3;

      int int1_num;

      printf ("Enter 3 floating-point numbers
       and 1 integer: \n");

      scanf ("%f %f %f %d", &flp1_num, &flp2_num,
       &flp3_num, &int1_num);

    //switch to assembly
     _asm
    {
       FLD flp1_num //flp1_num -> ST(0)
       FLD flp2_num //flp2_num -> ST(0)
          //flp1_num -> ST(1)
       FLD flp3_num //flp3_num -> ST(0)
          //fld2_num -> ST(1)
          //fld1_num -> ST(2)

       FADDP ST(2), ST(0)//ST(0) + ST(2) -> ST(2),
          //pop
       FST flp_rslt1  //ST(0) -> flp_rslt1

       FADDP ST(1), ST(0)//ST(0) + ST(1) -> ST(1),
          //pop

       FST flp_rslt2  //ST(0) -> flp_rslt2
       FIADD int1_num //ST(0) + int1_num -> ST(0)
       FST flp_rslt3 //ST(0) -> flp_rslt3
    }

    //print result
      printf ("\nflp_rslt1 = %f\n", flp_rslt1);

      printf ("flp_rslt2 = %f\n", flp_rslt2);

      printf ("flp_rslt3 = %f\n\n", flp_rslt3);

      return 0;
    }
    Enter 3 floating-point numbers and 1 integer:
    1.2 2.3 3.4 5

    flp_rslt1 = 2.300000
    flp_rslt2 = 6.900000
    flp_rslt3 = 11.900000

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 3 floating-point numbers and 1 integer:
    32.456 45.789 16.123 10

    flp_rslt1 = 45.789001
    flp_rslt2 = 94.368004
    flp_rslt3 = 104.368004

    Press any key to continue . . . _

    image

    image

  3. 11.20 Perform the following operation on the two operands: (–47.25) – (–18.75).

    image

  4. 11.22 Write an assembly language module embedded in a C program that uses the mul (FMULP) and the mul (FIMUL) instructions. For the FMULP instruction, use the FMULP ST(i), ST(0) version. Use the three sequences shown below to execute the FMULP, FMULP, and FIMUL instructions in that order and display the results of the program. Show the register stack for the third sequence of the program.

    +1.200  +2.300  +3.400  +5
    +32.400 +45.700 +16.100 +10
    –23.600 +28.500 –27.400 –12
    //fmul_versions2.cpp
    //show the use of the FMULP and FIMUL instructions
    #include "stdafx.h"
    int main (void)
    {
    //define variables
      float flp1_num, flp2_num, flp3_num,
      flp_rslt1, flp_rslt2, flp_rslt3;
      int int1_num;

      printf ("Enter 3 floating-point numbers and
       1 integer: \n");
      scanf ("%f %f %f %d", &flp1_num, &flp2_num,
          &flp3_num, &int1_num);

    //switch to assembly
     _asm
    {
       FLD  flp1_num //flp1_num -> ST(0)
       FLD  flp2_num //flp2_num -> ST(0)
          //flp1_num -> ST(1)
       FLD  flp3_num //flp3_num -> ST(0)
          //fld2_num -> ST(1)
          //fld1_num -> ST(2)
    //----------------------------------------------------
       FMULP ST(2), ST(0)//ST(2) × ST(0)->ST(2), pop
       FST  flp_rslt1  //ST(0) -> flp_rslt1
    //----------------------------------------------------
       FMULP ST(1), ST(0)//ST(1) × ST(0)->ST(1), pop
       FST  flp_rslt2  //ST(0) -> flp_rslt2
    //----------------------------------------------------
    //----------------------------------------------------
       FIMUL int1_num //ST(0) × int1_num->ST(0)
       FST  flp_rslt3  //ST(0) -> flp_rslt3
    //----------------------------------------------------
    }

    //print result
      printf ("\nflp_rslt1 = %f\n", flp_rslt1);
      printf ("flp_rslt2 = %f\n", flp_rslt2);
      printf ("flp_rslt3 = %f\n\n", flp_rslt3);

    return 0;
    }
    Enter 3 floating-point numbers and 1 integer:
    1.2 2.3 3.4 5

    flp_rslt1 = 2.300000
    flp_rslt2 = 9.384001
    flp_rslt3 = 46.920002

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 3 floating-point numbers and 1 integer:
    32.4 45.7 16.1 10

    flp_rslt1 = 45.700001
    flp_rslt2 = 23838.949219
    flp_rslt3 = 238389.500000

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter 3 floating-point numbers and 1 integer:
    –23.6 +28.5 –27.4 –12

    flp_rslt1 = 28.500000
    flp_rslt2 = 18429.240234
    flp_rslt3 = –221150.875000

    Press any key to continue . . . _

    image

  5. 11.28 A resistor is one of four passive circuit elements: resistor, capacitor, inductor, and the recently discovered memristor. The equivalent resistance Req — specified in ohms — of resistors connected in series is the sum of the resistor values. However, the equivalent resistance of resistors connected in parallel is shown in the equation below.

    1Req=1R1+1R2+1R3++1Rn

    The value of Req is smaller than the resistance of the smallest resistor in the parallel circuit. The circuit shown below contains three parallel resistors.

    image

    Write an assembly language module embedded in a C program that calculates the equivalent resistance of a three-resistor parallel network. Enter four sets of values for the resistors and display the equivalent resistance.

    //parallel_resistors.cpp
    //find the equivalent resistance of a
    //three-resistor parallel network

    #include "stdafx.h"

    int main (void)
    {
     float res1, res2, res3,
       res1_inv, res2_inv, res3_inv,
       resn_sum, res_equiv;

     printf ("Enter three resistor values: \n");

     scanf ("%f %f %f", &res1, &res2, &res3);
    //switch to assembly
     _asm
     {
    //----------------------------------------------------
    //calculations for resistor 1
       FLD1   //+1.0 -> ST(0)
       FLD  res1   //res1 -> ST(0)
          //+1.0 -> ST(1)
       FDIVP ST(1), ST(0)//+1.0 / res1 -> ST(1), pop
       FST res1_inv //ST(0) (+1.0 / res1) ->
          //res1_inv
    //----------------------------------------------------
    //calculations for resistor 2
       FLD1   //+1.0 -> ST(0)
          //+1.0 / res1 -> ST(1)
       FLD  res2   //res2 -> ST(0)
          //+1.0 -> ST(1)
          //+1.0 / res1 -> ST(2)
       FDIVP ST(1), ST(0)//+1.0 / res2 -> ST(1), pop
       FST  res2_inv //ST(0) (+1.0 / res2) ->
          //res2_inv
    //----------------------------------------------------
    //calculations for resistor 3
       FLD1   //+1.0 -> ST(0)
          //+1.0 / res2 -> ST(1)
          //+1.0 / res1 -> ST(2)
       FLD  res3   //res3 -> ST(0)
          //+1.0 -> ST(1)
          //+1.0 / res2 -> ST(2)
          //+1.0 / res1 -> ST(3)
       FDIVP ST(1), ST(0)//+1.0 /res3 -> ST(1), pop
       FST  res3_inv //ST(0) (+1.0 / res3) ->
          //res3_inv
    //----------------------------------------------------
    //calculate the sum of the inverted resistors
       FADD ST(0), ST(1)//(+1.0 / res3) +
          //(+1.0 / res2) -> ST(0)
       FADD ST(0), ST(2)//ST(0) + (+1.0 / res1) ->
          //ST(0). Sum of inverted
          //resistors -> ST(0)
       FST  resn_sum //sum of inverted resistors
          //-> resn_sum
    //----------------------------------------------------
    //----------------------------------------------------
    //calculate the equivalent resistance
       FLD1   //+1.0 -> ST(0)
       FDIV resn_sum //+1.0 / resn_sum -> ST(0)
       FST  res_equiv  //ST(0) -> equivalent
          //resistance
    //----------------------------------------------------
    }

    //print result
      printf ("\nEquivalent resistance = %f ohms\n\n",
       res_equiv);
      return 0;
    }
    Enter three resistor values:
    1000.0 1000.0 1000.0

    Equivalent resistance = 333.333344 ohms

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter three resistor values:
    72.25 1000 64.38

    Equivalent resistance = 32.923325 ohms

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter three resistor values:
    750.0 75000.0 3600.0

    Equivalent resistance = 615.595032 ohms

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter three resistor values:
    1.0 2.0 3.0

    Equivalent resistance = 0.545455 ohms

    Press any key to continue . . . _
  6. 11.33 Write an assembly language module embedded in a C program that calculates the result of the expression shown below for different values of the floating-point variables flp1 and flp2.

    12πflp1×flp2

    //square_root.cpp
    //uses FMUL, FSQRT, FLDPI, FLD1, FDIV instructions
    #include "stdafx.h"
    int main (void)
    {
      float flp1, flp2, denom_rslt, flp_rslt;
      float two;
      two = 2.0;

      printf ("Enter two floating-point numbers: \n");
      scanf ("%f %f", &flp1, &flp2);

    //switch to assembly
     _asm
     {
       FLD  flp1   //flp1 -> ST(0)
       FMUL flp2   //flp1 x flp2 -> ST(0)
       FSQRT    //sq root of ST(0) -> ST(0)
       FMUL two  //sq root of ST(0) x 2.0 ->
          //ST(0)
       FLDPI    //pi -> ST(0)
          //sq root of ST(0) x 2.0 ->
          //ST(1)
       FMUL ST(0), ST(1)//2.0 x sq root x pi ->
          //ST(0)
       FSTP denom_rslt //denominator ->
          //denom_rslt, pop stack
       FLD1   //1.0 -> ST(0)
       FDIV denom_rslt //1.0 / denom_rslt -> ST(0)
       FST  flp_rslt //result -> flp_rslt area
    }
    //print result
      printf ("\nResult = %f\n\n", flp_rslt);

      return 0;
    }
    Enter two floating-point numbers:
    10.0 10.0

    Result = 0.015915

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two floating-point numbers:
    20.0 30.0

    Result = 0.006497

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two floating-point numbers:
    0.5 0.5

    Result = 0.318310

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two floating-point numbers:
    0.05 0.08

    Result = 2.516461

    Press any key to continue . . . _
    ------------------------------------------------------
    Enter two floating-point numbers:
    0.05 0.05

    Result = 3.183099

    Press any key to continue . . . _

Chapter 12 Procedures

  1. 12.1 Write an assembly language program — not embedded in a C program — that uses a procedure to multiply two single-digit operands. Enter several operands for the multiplicand and multiplier and display the products.

    ;mul_proc.asm
    ; -----------------------------------------------------
    .STACK
    ; -----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 5
    ACTLEN DB ?
    OPFLD DB 5 DUP(?)
    PRMPT DB 0DH, 0AH, 'Enter two single-digit integers: $'
    RSLT  DB 0DH, 0AH, 'Product =  $'
    ; -----------------------------------------------------
    .CODE
    BEGIN  PROC FAR

    ;set up pgm ds
      MOV  AX, @DATA ;get addr of data seg
      MOV  DS, AX
    ;read prompt
      MOV AH, 09H ;display string
      LEA DX, PRMPT
      INT 21H  ;dos interrupt
    ;kybd rtn to enter chars
      MOV AH, 0AH ;buffered kybd input
      LEA DX, PARLST
      INT 21H
    ;get the two integers
      MOV  AL, OPFLD ;get 1st digit (mpcnd) fm opfld
      AND AL, 0FH ;remove ascii bias
      MOV AH, 00H ;clear ah
      PUSH AX
      MOV BL, OPFLD+1 ;get 2nd digit (mplyr) fm opfld
      AND BL, 0FH ;remove ascii bias
      MOV BH, 00H ;clear bh
      PUSH BX

      CALLCALC  ;push ip. call calc rtn
    ;return to here after calc procedure
    ;move the sum to result
      MOV RSLT+12, AH
      MOV RSLT+13, AL
    ;display the resulting sum
      MOV AH, 09H ;display string
      LEA DX, RSLT
      INT 21H
    BEGIN ENDP
    ; -----------------------------------------------------
    CALC PROC NEAR
      PUSH BP  ;bp will be used
      MOV BP, SP  ;bp points to tos
      MOV AX, [BP+4] ;get opnd a (mpcnd)
      MUL [BP+6]  ;mul opnd b (mplyr). prod to ax
      AAM   ;ascii adjust for mul
      OR AX, 3030H ;convert to ascii
      POP BP  ;restore bp
      RET 4   ;pop ip. add 4 to sp so that
         ;sp points to initial location
    CALC ENDP
    END BEGIN
    Enter two single-digit integers: 23
    Product = 6
    ------------------------------------------------------
    Enter two single-digit integers: 91
    Product = 09
    ------------------------------------------------------
    Enter two single-digit integers: 54
    Product = 20
    ------------------------------------------------------
    Enter two single-digit integers: 78
    Product = 56
    ------------------------------------------------------
    Enter two single-digit integers: 98
    Product = 72
    ------------------------------------------------------
    Enter two single-digit integers: 99
    Product = 81
    ------------------------------------------------------
    Enter two single-digit integers: 90
    Product = 00
  2. 12.4 Write an assembly language program — not embedded in a C program — that uses a procedure to exclusive-OR six hexadecimal characters that are entered from the keyboard. The following characters are exclusive-ORed: the first and third; the second and fourth; the third and fifth; and the fourth and sixth. The keyboard data can be any hexadecimal characters; for example, 2T/}b*.

    ;xor_proc.asm
    ;exclusive-OR characters
    ;opfld xor opfld2
    ;opfld2 xor opfld4
    ;opfld3 xor opfld5
    ;opfld4 xor opfld6
    ; -----------------------------------------------------
    .STACK
    ; -----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 10
    ACTLEN DB ?
    OPFLD  DB 10 DUP(?)
    PRMPT  DB 0DH, 0AH, 'Enter six hexadecimal
          characters: $'
    RSLT DB 0DH, 0AH, 'Result =  $'
    ; -----------------------------------------------------
    .CODE
    BEGIN  PROC  FAR

    ;set up pgm ds
      MOV  AX, @DATA
      MOV  DS, AX
    ;read prompt
      MOV  AH, 09H
      LEA  DX, PRMPT
      INT  21H
    ;keyboard request rtn to enter characters
      MOV  AH, 0AH
      LEA  DX, PARLST
      INT  21H
    ;set up addresses
      LEA  SI, OPFLD ;1st number
      LEA  DI, OPFLD+2  ;3rd number
      LEA  BX, RSLT+12  ;result area
      CALL EXOR   ;push ip. call exor rtn
    ; ----------------------------------------------------
    ;return to here after exor procedure
    ;display result
      MOV  AH, 09H   ;display string
      LEA  DX, RSLT
      INT  21H

    BEGIN ENDP

    ; ----------------------------------------------------
    EXOR PROC NEAR
     MOV  CX, 4  ;loop control
    LP1: MOV  AL, [SI]
     MOV  AH, [DI]
     XOR  AL, AH
     OR AL, 30H
     MOV  [BX], AL
     INC  SI
     INC  DI
     INC  BX
     LOOP LP1
     RET
    EXOR ENDP

    ; ----------------------------------------------------
    END BEGIN
    Enter six hexadecimal characters: 123456
    Result = 2662
    ------------------------------------------------------
    Enter six hexadecimal characters: F0E2CF
    Result = 326t
    ------------------------------------------------------
    Enter six hexadecimal characters: B67dMt
    Result = urz0
    ------------------------------------------------------
    Enter six hexadecimal characters: F05urM
    Result = suw8
    ------------------------------------------------------
    Enter six hexadecimal characters: :/<?]+
    Result = 60q4

Chapter 13 String Instructions

  1. 13.2 Determine the contents of RSLT after execution of the following program:

    ;movs_byte5.asm
    ; -----------------------------------------------------
    .STACK

    ; -----------------------------------------------------
    .DATA
    RSLT  DB 0DH, 0AH, '123456789  $'

    ; -----------------------------------------------------
    .CODE
    BEGIN  PROC FAR

    ;set up pgm ds
      MOV AX, @DATA  ;get addr of data seg
      MOV DS, AX    ;move addr to ds
      MOV ES, AX    ;move addr to es

    ; -----------------------------------------------------
    ;move string elements
      CLD
      MOV CX, 4   ;count in cx
      LEA SI, RSLT+2  ;addr of rslt+2 -> si as src
      LEA DI, RSLT+4  ;addr of rslt+4 -> di as dst

    REP  MOVSB    ;move bytes to dst

    ; -----------------------------------------------------
    ;display result
      MOV AH, 09H   ;display string
      LEA DX, RSLT   ;put addr of rslt in dx
      INT 21H    ;dos interrupt

    BEGIN ENDP
      END BEGIN
    ; -----------------------------------------------------
    //121212789
  2. 13.8 Given the program segment shown below, determine the contents of the count in register CL and the ZF flag after the program has been executed. Then write an assembly language program — not embedded in a C program — to verify the results.

           . . .
    .DATA
    STR1 DB 'ABCDEF $'
    STR2 DB 'AB1234 $'
    CL_RSLT DB 0DH, 0AH, 'CL = $'
    FLAGS  DB 0DH, 0AH, 'ZF flag =  $'

    ; -----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds and es
     MOV AX, @DATA   ;get addr of data seg
     MOV DS, AX   ;move addr to ds
     MOV ES, AX   ;move addr to es

    ; -----------------------------------------------------
     LEA SI, STR1   ;addr of str1 -> si
     LEA DI, STR2   ;addr of str2 -> di
     CLD     ;left-to-right
     MOV CL, 6   ;count in cl
    REPNE
     CMPSB     ;compare strings while not equal
           . . .
    CL = 5
    ZF flag = 1
    ;cmps_repne.asm
    ;use cmps with repne prefix
    ; -----------------------------------------------------
    .STACK
    ; -----------------------------------------------------
    .DATA
    STR1 DB 'ABCDEF $'
    STR2 DB 'AB1234 $'
    CL_RSLT DB 0DH, 0AH, 'CL = $'
    FLAGS  DB 0DH, 0AH, 'ZF flag =  $'
    ; -----------------------------------------------------
    .CODE
    BEGIN  PROC FAR

    ;set up pgm ds and es
      MOV AX, @DATA ;get addr of data seg
      MOV DS, AX   ;move addr to ds
      MOV ES, AX   ;move addr to es
    ; -----------------------------------------------------
      LEA SI, STR1  ;addr of str1 -> si
      LEA DI, STR2  ;addr of str2 -> di
      CLD ;left-to-right
      MOV CL, 6  ;count in cl
    REPNE
      CMPSB   ;comp while not equal
      PUSHF   ;push flags
      POP AX
      AND AL, 40H  ;isolate zf
      SHR AL, 6  ;shift right logical 6
      OR AL, 30H   ;add ascii bias
      MOV FLAGS+12, AL ;move zf to flag area
    ; -----------------------------------------------------
    ;display residual count
      OR CL, 30H   ;add ascii bias
      MOV CL_RSLT+7, CL ;move to result area
      MOV AH, 09H  ;display string
      LEA DX, CL_RSLT  ;addr of cl_rslt -> dx
      INT 21H   ;dos interrupt
    ; -----------------------------------------------------
    ;display flags
      MOV AH, 09H  ;display string
      LEA DX, FLAGS ;addr of flags -> dx
      INT 21H   ;dos interrupt
    BEGIN ENDP
      END BEGIN
  3. 13.9 Given the program segment shown below, obtain the count in register CL after the program executes.

    .DATA
    STR DB 'ABCDEFGHI $'
    CL_RSLT DB 0DH, 'CL =  $'
    FLAGS  DB 0DH, 0AH, 'ZF flag = $'

    ; -----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds and es
      MOV AX, @DATA  ;get addr of data seg
      MOV DS, AX  ;move addr to ds
      MOV ES, AX  ;move addr to es
    ; -----------------------------------------------------
      MOV AL, 'G'
      LEA DI, STR ;addr of str2 -> di
      CLD   ;left-to-right
      MOV CL, 9  ;count in cl

    REPNE
      SCASB   ;compare char while ≠
        . . .
    ; -----------------------------------------------------
    CL = 1
    ; -----------------------------------------------------

Chapter 14 Arrays

  1. 14.3 Write an assembly language module embedded in a C program that adds, subtracts, and multiplies two select floating-point numbers. Three positive and three negative floating-point numbers are to be defined, then used in the calculations. Perform two calculations on each arithmetic operation and display the corresponding results.

    //array_flp2.cpp
    //add, sub, and mul two floating-point numbers
    #include "stdafx.h"
    int main (void)

    {
    //define variables
      double  flp1 = 72.5,
       flp2 = -104.8,
       flp3 = -56.7,
       flp4 = 110.5,
       flp5 = -255.3,
       flp6 = 30.6;
      double sum1, sum2,
       diff1, diff2,
       prod1, prod2;
    //switch to assembly
      _asm
      {
    //addition -------------------------------------------
      FLD flp2  //(-104.8) -> ST(0)
      FADD flp3  //(-104.8) + (-56.7)
         //= (-161.5) -> ST(0)
      FST sum1  //(-161.5) -> sum1

      FLD flp4  //(110.5) -> ST(0)
      FADD flp5  //(110.5) +(-255.3)
         //= (-144.8) -> ST(0)
      FST sum2  //(-144.8) -> sum2
    //subtraction ----------------------------------------
      FLD flp5  //(-255.3) -> ST(0)
      FSUB flp4  //(-255.3) - (110.5)
         //= (-365.8) - > ST(0)
      FST diff1 //(-365.8) -> diff1
      FLD flp6  //(30.6) -> ST(0)
      FSUBflp2  //(30.6) - (-104.8)
        //= (135.4) - > ST(0)
      FST diff2 //(135.4) -> diff2
    //multiplication -------------------------------------
      FLD flp2 //(-104.8) -> ST(0)
      FMUL flp5 //(-104.8) x (-255.3)
        //= 26755.44 -> ST(0)
      FST prod1 //(26755.44) -> prod1

      FLD flp3 //(-56.7) -> ST(0)
      FMUL flp4 //(-56.7) x (110.5)
        //= -6265.35 -> ST(0)
      FST prod2 //(-6265.35) -> prod2
     }
    //display results
      printf ("(-104.8) + (-56.7) = %f\n", sum1);
      printf ("(110.5) + (-255.3) = %f\n\n", sum2);
      printf ("(-255.3) - (110.5) = %f\n", diff1);
      printf ("(30.6) - (-104.8) = %f\n\n", diff2);
      printf ("(-104.8) x (-255.3) = %f\n", prod1);
      printf ("(-56.7) x (110.5) = %f\n\n", prod2);
      return 0;
    }
    (-104.8) + (-56.7) = -161.500000
    (110.5) + (-255.3) = -144.800000

    (-255.3) - (110.5) = -365.800000
    (30.6) - (-104.8) = 135.400000

    (-104.8) x (-255.3) = 26755.440000
    (-56.7) x (110.5) = -6265.350000

    Press any key to continue . . . _
  2. 14.5 Write a C program that calculates the cubes of the integers 1 through 10 using an array, where array [0] contains a value of 1.

    //array_cubes.cpp
    //obtain the cubes of numbers 1 through 10

    #include "stdafx.h"
    int main (void)
    {
     int cubes[10]; //declare an array of 10 elements
     int i;  //declare an integer to count

    //initialize and print the array
      for (i=1; i<11; i++)
      {
      cubes[i-1] = i*i*i;
      printf ("cubes[%d] = %d\n", i-1, cubes[i-1]);
     }

     printf ("\n");
     return 0;
    }
    cubes[0] = 1
    cubes[1] = 8
    cubes[2] = 27
    cubes[3] = 64
    cubes[4] = 125
    cubes[5] = 216
    cubes[6] = 343
    cubes[7] = 512
    cubes[8] = 729
    cubes[9] = 1000

    Press any key to continue . . . _
  3. 14.8 Write a C program that loads a 3 × 4 array with the products of the indices, then display the array in a row–column format.

    //array_mul_indices.cpp
    //load a 3 x 4 array with the products of the indices,
    //then display the array in a row-column format

    #include "stdafx.h"

    int main (void)
    {
      int array_mul[3][4];
      int i, j;

      for (i=0;i<3; i++)  //i is row index
       for (j=0; j<4; j++) //j is column index
       array_mul[i][j] = i*j;

      for (i=0; i<3; i++)
      {
       for (j=0; j<4; j++)
       printf ("%4d", array_mul[i][j]);
       printf ("\n");
     }
      printf ("\n");
      return 0;
    }
    0 0 0 0
    0 1 2 3
    0 2 4 6
    Press any key to continue . . . _

Chapter 15 Macros

  1. 15.2 Write an assembly language program using a macro that sorts from two to ten single-digit integers in ascending numerical order that are entered from the keyboard. Enter several different sets of integers ranging from two integers to ten integers and display the results.

    ;macro_sort2.asm
    ;sort 2 -- 10 single-digit integers
    ;in ascending numerical order
    ; -----------------------------------------------------
    ;define the sort macro
    SORT MACRO
      LEA SI, OPFLD  ;addr of first byte -> si
      MOV DL, ACTLEN ;# of bytes -> dx
      MOV DH, 00H   ;... as loop ctr
      DEC DX    ;decrement loop ctr

    LP1: MOV CX, DX  ;cx is loop2 ctr

    LP2: MOV AL, [SI]  ;number -> al
      MOV BX, CX  ;bx is base addr
      CMP AL, [BX+SI] ;is the number <= to al?
      JBE NEXT   ;yes, get next number
      XCHG AL, [BX+SI]  ;# is !<=; put # in al
      MOV [SI], AL  ;put small # in opfld

    NEXT: LOOP LP2   ;loop until all #s
          ;... are compared
      INC SI    ;si points to next number
      DEC DX    ;decrement loop ctr
      JNZ LP1   ;compare remaining
          ;... numbers
      ENDM
    ; -----------------------------------------------------
    .STACK
    ; -----------------------------------------------------
    .DATA
    PARLST LABEL BYTE
    MAXLEN DB 15
    ACTLEN DB ?
    OPFLD DB 15 DUP(?)
    PRMPT DB 0DH, 0AH, ‘Enter numbers: $’
    RSLT  DB 0DH, 0AH, ‘Sorted numbers =    $’
    ; -----------------------------------------------------
    ; -----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV AX, @DATA  ;addr of data seg -> ax
      MOV DS, AX  ;move addr to ds
    ;read prompt
      MOV AH, 09H   ;display string
      LEA DX, PRMPT  ;put addr of prompt in dx
      INT 21H   ;dos interrupt

    ;keyboard request rtn to enter characters
      MOV AH, 0AH   ;buffered keyboard input
      LEA DX, PARLST ;put addr of parlst in dx
      INT 21H   ;dos interrupt

    ; -----------------------------------------------------
    ;call sort macro
      SORT

    ; -----------------------------------------------------
    ;set up src (opfld) and dst (rslt)
      LEA SI, OPFLD
      LEA DI, RSLT+19
      MOV CL, ACTLEN
      MOV CH, 00H

    ;move sorted numbers to result area
    RSLT_AREA:
      MOV BL, [SI]  ;opfld number to bl
      MOV [DI], BL  ;number to result area
      INC SI    ;set up next source
      INC DI    ;set up next destination
      LOOP RSLT_AREA ;loop if cl != 0

    ;display sorted numbers
      MOV AH, 09H   ;display string
      LEA DX, RSLT  ;put addr of rslt in dx
      INT 21H   ;dos interrupt
    BEGIN ENDP
      END BEGIN
    Enter numbers: 73 Sorted numbers = 37
    ------------------------------------------------------
    Enter numbers: 360 Sorted numbers = 036
    ------------------------------------------------------
    Enter numbers: 9845 Sorted numbers = 4589
    ------------------------------------------------------
    Enter numbers: 48632 Sorted numbers = 23468
    ------------------------------------------------------
    Enter numbers: 130474 Sorted numbers = 013447
    ------------------------------------------------------
    Enter numbers: 9766347 Sorted numbers = 3466779
    ------------------------------------------------------
    Enter numbers: 47589001 Sorted numbers = 00145789
    ------------------------------------------------------
    Enter numbers: 354657685 Sorted numbers = 345556678
    ------------------------------------------------------
    Enter numbers: 9876543210 Sorted numbers = 0123456789
  2. 15.5 Write a program that uses two macros. One macro generates an odd parity bit for an 8-bit code word that is entered from the keyboard. If the parity is odd, then display a 0; if the parity is even, then display a 1. The other macro removes all nonletters from data that are entered from the keyboard.

    ;macro_parity_ltrs2.asm
    ;use a macro to generate a parity bit for 8 bits
    ;... if parity is odd, display 0
    ;... if parity is even, display 1
    ;use a macro to remove all nonletters from data
    ;... entered from the keyboard

    ; -----------------------------------------------------
    ;define the parity macro
    PARITY  MACRO
    NEXTB:MOV AL, [SI] ;bit -> al
      CMP AL, 31H  ;is bit = 1?
      JNE ZERO  ;if bit = 0, jump
      XOR BL, 01H  ;if bit = 1, toggle parity
    ZERO: INC SI   ;si points to next bit
      LOOP NEXTB ;is cx != 0, get next bit
      ENDM

    ; -----------------------------------------------------
    ;define ltrs (remove nonletters) macro
    LTRS MACRO
    NEXTL:MOV AL, [SI] ;opfld char -> al
      CMP AL, 41H  ;compare to uppercase A
      JL LP1   ;if < A, jump to LP1
      CMP AL, 5AH  ;compare to uppercase Z
      JLE LP2  ;if >= A & <= Z, jump to LP2

      CMP AL, 7AH  ;compare to lowercase z
      JG LP1   ;if > z, jump to LP1
      CMP AL, 61H  ;compare to lowercase a
      JL LP1   ;if < a, jump to LP1

    LP2: MOV [DI], AL ;valid character -> dst
      INC DI   ;di -> next dst

    LP1: INC SI   ;get next char in opfld
      LOOP NEXTL
      ENDM

    ; -----------------------------------------------------
    .STACK
    ; -----------------------------------------------------
    .DATA
    PARLST   LABEL BYTE
    MAXLEN   DB 40
    ACTLEN   DB ?
    OPFLD  DB 40 DUP(?)
    PRMPT  DB 0DH, 0AH, 'Enter characters: $'
    RSLTP  DB 0DH, 0AH, 'Parity bit =  $'
    RSLTL  DB 0DH, 0AH, 'Letters =   $'

    ; -----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV AX, @DATA  ;addr of data seg -> ax
      MOV DS, AX  ;move addr to ds

    ;*****************************************************
    ;set up for the parity macro
    ;read prompt
      MOV AH, 09H   ;display string
      LEA DX, PRMPT  ;addr of prompt -> dx
      INT 21H   ;dos interrupt

    ;keyboard request to enter characters
      MOV AH, 0AH   ;buffered keyboard input
      LEA DX, PARLST ;addr of parlst -> dx
      INT 21H   ;dos interrupt
    ; -----------------------------------------------------
    ;initialize parity flag to 1 and count in cx to 8
    ;initialize source (si) and destination (di) addr
      MOV BL, 01H   ;set parity in bl to 1
      MOV CX, 08H   ;number of bits is 8
      LEA SI, OPFLD  ;addr of opfld -> si
      LEA DI, RSLTP+11  ;addr of result -> di

    ; -----------------------------------------------------
    ;call parity macro
     PARITY
    ; -----------------------------------------------------
      OR BL, 30H  ;add ascii bias to parity
      MOV [DI], BL  ;parity -> result area
    ; -----------------------------------------------------
    ;display result
      MOV AH, 09H   ;display string
      LEA DX, RSLTP  ;addr of result -> dx
      INT 21H   ;dos interrupt
    ;*****************************************************
    ;set up for the ltrs (remove nonletters) macro
    ;read prompt
      MOV AH, 09H   ;display string
      LEA DX, PRMPT  ;addr of prompt -> dx
      INT 21H   ;dos interrupt

    ;keyboard request to enter characters
      MOV AH, 0AH   ;buffered keyboard input
      LEA DX, PARLST ;addr of parlst -> dx
      INT 21H   ;dos interrupt

    ;get number of characters entered
      MOV CL, ACTLEN ;# of characters -> cl
      MOV CH, 00H   ;cx = 00 actlen

    ;set up source (opfld) and destination (rslt) addr
      LEA SI, OPFLD  ;source addr -> si
      LEA DI, RSLTL+11  ;destination addr -> di
    ; -----------------------------------------------------
    ;call ltrs (remove nonletters) macro
       LTRS

    ; -----------------------------------------------------
    ;display result
      MOV AH, 09H   ;display string
      LEA DX, RSLTL  ;addr of result -> dx
      INT 21H   ;dos interrupt
    BEGIN ENDP
      END BEGIN
    Enter characters: 11001010  //parity is even
    Parity bit = 1
    Enter characters: ab34deFG7H
    Letters = abdeFGH
    ------------------------------------------------------
    Enter characters: 01100111  //parity is odd
    Parity bit = 0
    Enter characters: A678Fth9jk0Lm
    Letters = AFthjkLm
    ------------------------------------------------------
    Enter characters: 01111111  //parity is odd
    Parity bit = 0
    Enter characters: 65abcdef89GH
    ------------------------------------------------------
    Enter characters: 00000000  //parity is even
    Parity bit = 1
    Enter characters: 1mno56PQr3
    Letters = mnoPQr
    ------------------------------------------------------
    Enter characters: 11110000  //parity is even
    Parity bit = 1
    Enter characters: 1a23455678
    Letters = a
    ------------------------------------------------------
    Enter characters: 00011111  //parity is odd
    Parity bit = 0
    Enter characters: 1234567890B
    Letters = B
    ------------------------------------------------------
    Enter characters: 00111100  //parity is even
    Parity bit = 1
    Enter characters: 54689v7675t99
    Letters = vt
    ------------------------------------------------------
    Enter characters: 10101010  //parity is even
    Parity bit = 1
    Enter characters: 456h8996
    Letters = h
    ------------------------------------------------------
    Enter characters: 00110011  //parity is even
    Parity bit = 1
    Enter characters: 1234567890
    Letters =
    ------------------------------------------------------
    Enter characters: 00011100  //parity is odd
    Parity bit = 0
    Enter characters: 6
    Letters =
    ------------------------------------------------------
    Enter characters: 11100000  //parity is odd
    Parity bit = 0
    Enter characters: 23vB^&JK(t
    Letters = vBJKt
  3. 15.8 Write a program using a macro with no parameters that multiplies two single-digit integers that are entered from the keyboard. Enter several integers and display the results.

    ;macro_mul2.asm
    ;obtain the product of two single-digit integers

    ; -----------------------------------------------------
    ;define the mult macro
    MULT MACRO
      MOV AL, OPFLD  ;get multiplicand
      AND AL, 0FH ;remove ascii bias
      MOV AH, OPFLD+1 ;get multiplier
      AND AH, 0FH ;remove ascii bias

    ;multiply the #s, adjust using aam, add ascii bias
      MUL AH  ;ax = al x ah
      AAM   ;ax = 0d 0d
      OR  AX, 3030H  ;add ascii bias
      MOV RSLT+12, AH ;high product -> rslt
      MOV RSLT+13, AL ;low product -> rslt
      ENDM

    ; -----------------------------------------------------
    .STACK

    ; -----------------------------------------------------
    .DATA
    PARLST  LABEL BYTE
    MAXLEN  DB 5
    ACTLEN  DB ?
    OPFLD   DB 5 DUP(?)
    PRMPT   DB 0DH, 0AH, 'Enter two 1-digit integers: $'
    RSLT  DB 0DH, 0AH, 'Product =  $'

    ; -----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV AX, @DATA  ;addr of data seg -> ax
      MOV DS, AX  ;move addr to ds
    ;read prompt
      MOV AH, 09H ;display string
      LEA DX, PRMPT  ;put addr of prompt in dx
      INT 21H  ;dos interrupt

    ;keyboard request rtn to enter characters
      MOV AH, 0AH ;buffered keyboard input
      LEA DX, PARLST ;put addr of parlst in dx
      INT 21H  ;dos interrupt

    ; -----------------------------------------------------
    ;call mult macro
      MULT
    ; -----------------------------------------------------
    ;display product
      MOV AH, 09H ;display string
      LEA DX, RSLT ;addr of rslt -> dx
      INT 21H  ;dos interrupt
    BEGIN ENDP
      END BEGIN
    Enter two single-digit integers: 99
    Product = 81
    ------------------------------------------------------
    Enter two single-digit integers: 87
    Product = 56
    ------------------------------------------------------
    Enter two single-digit integers: 39
    Product = 27
    ------------------------------------------------------
    Enter two single-digit integers: 73
    Product = 21
    ------------------------------------------------------
    Enter two single-digit integers: 08
    Product = 00
    ------------------------------------------------------
    Enter two single-digit integers: 60
    Product = 00
    ------------------------------------------------------
    Enter two single-digit integers: 45
    Product = 20

Chapter 16 Interrupts and Input/Output Operations

  1. 16.3 Explain why interrupt breakpoints occur only at the end of an instruction cycle.

    If interrupt breakpoints occurred during an instruction cycle, for example, at the end of a CPU cycle, then control would be transferred to the ISR and the current instruction would not be completed. Therefore, interrupt breakpoints occur only at the end of an instruction cycle, that is, when the current instruction has completed execution.

  2. 16.7 Explain why DMA access to main memory has a higher priority than central processing units access to main memory.

    Input/output devices equipped with DMA hardware have highest priority over central processing units when transferring data to or from main memory, because they are inherently slower and cannot have the data transfer stopped temporarily. Thus, data would be lost. Disk drives and tape drives are examples of I/O subsystems in this category.

Chapter 17 Additional Programming Examples

  1. 17.2 Write a program in assembly language — not embedded in a C program — that counts the number of times that a number occurs in an array of eight numbers. The first number entered from the keyboard is the number that is being compared to the remaining eight numbers. Display the result.

    ;count_occurrence2.asm
    ;count the number of times that a number
    ;occurs in an array of eight numbers.
    ;the first number entered from the keyboard
    ;is the number that is being compared to
    ;the remaining eight numbers
    ; -----------------------------------------------------
    .STACK

    ; -----------------------------------------------------
    .DATA
    PARLST   LABEL BYTE
    MAXLEN   DB 12
    ACTLEN   DB ?
    OPFLD  DB 12 DUP(?)
    PRMPT  DB 0DH, 0AH, 'Enter 9 single-digit integers: $'
    RSLT  DB 0DH, 0AH, 'Occurs = times $'

    ; -----------------------------------------------------
    .CODE
    BEGIN PROC FAR

    ;set up pgm ds
      MOV AX, @DATA  ;addr of data seg -> ax
      MOV DS, AX   ;put addr in ds
      LEA DI, RSLT + 11 ;put addr of rslt in di

    ;read prompt
     MOV  AH, 09H   ;display string
     LEA  DX, PRMPT  ;addr of prmpt -> dx
     INT  21H   ;dos interrupt
    ;keyboard rtn to enter characters
     MOV  AH, 0AH   ;buffered keyboard input
     LEA  DX, PARLST   ;load addr of parlst
     INT  21H   ;dos interrupt

    ;keyboard rtn to enter characters
      MOV  AH, 0AH   ;buffered keyboard input
      LEA  DX, PARLST  ;load addr of parlst
      INT  21H    ;dos interrupt
    ; -----------------------------------------------------
      MOV  DL, OPFLD  ;number to compare -> dl
      LEA  SI, OPFLD + 1  ;put addr of list in si
      MOV  CX, 8   ;qty of #s to comp -> cx
      MOV  AH, 30H   ;init # of occurrences

    LP1: MOV  AL, [SI]   ;move number to al
      CMP  DL, AL    ;compare dl to al
      JE INC_COUNT  ;if equal, jump
      INC  SI    ;point to next number
      LOOP LP1    ;loop to compare next #
      JMP  MOVE_COUNT  ;comparison is finished

    INC_COUNT:
      INC  AH    ;incr the occurrences
      INC  SI    ;point to next number
      LOOP LP1    ;if cx != 0,
           ;compare next number

    MOVE_COUNT:
      MOV  [DI], AH   ;# of occurrences
           ;-> result area
    ; ---- -------------------------------------------------
    ;display result
      MOV  AH, 09H   ;display string
      LEA  DX, RSLT   ;put addr of rslt in dx
      INT  21H    ;dos interrupt

    BEGIN ENDP
      END  BEGIN
    Enter 9 single-digit integers; 612634656
    Occurs = 3 times
    ------------------------------------------------------
    Enter 9 single-digit integers; 123151611
    Occurs = 4 times
    ------------------------------------------------------
    Enter 9 single-digit integers; 912345679
    Occurs = 1 times
    ------------------------------------------------------
    Enter 9 single-digit integers; 712345689
    Occurs = 0 times
    ------------------------------------------------------
    Enter 9 single-digit integers; 222222222
    Occurs = 8 times
    ------------------------------------------------------
    Enter 9 single-digit integers; 412344544
    Occurs = 4 times
  2. 17.6 Write an assembly language module embedded in a C program to obtain the sum of cubes for the numbers 1 through 5. Display the resulting sum of cubes.

    //sum_of_cubes7.cpp
    //obtain the sum of cubes for numbers 1 through 5
    #include "stdafx.h" int main (void)
    {
    //define variables
      unsigned char 
      n, sum;
      n = 1;
      sum = 1;

    //switch to assembly
      _asm
      {
    // ----------------------------------------------------
    LP1:  INC  n
      MOV  CX, 2
      MOV  AL, n
    LP2:  MUL  n
      LOOP LP2
      ADD  sum, AL
      CMP  n, 5
      JB LP1
     }
    //print sum
      printf ("Sum of cubes 1 through 5 = %d\n\n", sum);
      return 0;
    }
    Sum of cubes 1 through 5 = 225

    Press any key to continue . . . 
  3. 17.9 Write an assembly language module embedded in a C program to evaluate the expression shown below for Y using a floating-point number for the variable X. The range for X is –3.0 ≤ X ≤ +3.0. Enter several numbers for X and display the corresponding results.

    Y=X310X2+20X+30

    //eval_expr8.cpp
    //evaluate the following expression for Y using a
    //floating-point number for the variable X:
    //Y = X^3 -10X^2 + 20X + 30, where X has a
    //range of -3.0 <= X <= +3.0

    #include "stdafx.h"

    int main (void)
    {
    //define variables
      float flp_x, flp_rslt_x3, flp_rslt_10x2,
        flp_rslt_20x, flp_rslt_y;

      int ten;
      ten = 10;

      int twenty;
      twenty = 20;

      int thirty;
      thirty = 30;
      printf ("Enter a floating-point number for x: \n");
      scanf ("%f", &flp_x);

    //switch to assembly
      _asm
      {
    //calculate X^3
      FLD flp_x   //X -> ST(0)
      FMUL flp_x   //X^2 -> ST(0)
      FMUL flp_x   //X^3 -> ST(0)
      FST flp_rslt_x3  //ST(0) (X^3)
          //-> flp_rslt_x3
    //calculate 10X^2
      FLD  flp_x  //X -> ST(0)
      FMUL flp_x  //X^2 -> ST(0)
      FIMUL ten   //(10) x X^2 -> ST(0)
      FST  flp_rslt_10x2 //ST(0) (10X^2)
          //-> flp_rslt_10x2

    //calculate 20X
      FLD flp_x   //X -> ST(0)
      FIMUL twenty  //(20) x X -> ST(0)
      FST flp_rslt_20x //ST(0) (20X)
          //-> flp_rslt_20x

    //calculate Y
      FLD flp_rslt_x3  //(X^3) -> ST(0)
      FSUB flp_rslt_10x2  //(X^3) - (10X^2)
          //-> ST(0)
      FADD flp_rslt_20x //(X^3) - (10X^2)
          //+ (20X) -> ST(0)
      FIADD thirty  //(X^3) - (10X^2)
          //+ (20X) + (30)
          //-> ST(0)
      FST flp_rslt_y  //ST(0) (Y)
          //-> flp_rslt_y
     }
    //printf results
      printf("\nResult X^3 = %f\n\n", flp_rslt_x3);

      printf("\nResult 10X^2 = %f\n\n", flp_rslt_10x2) ;

      printf("\nResult 20X = %f\n\n", flp_rslt_20x);

      printf ("\nResult Y = %f\n\n", flp_rslt_y);

      return 0;
    }
    Enter a floating-point number for x:
    –1.0
    Result X^3 = –1.000000
    Result 10X^2 = 10.000000
    Result 20X = –20.000000
    Result Y = –1.000000
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    –2.0
    Result X^3 = –8.000000
    Result 10X^2 = 40.000000
    Result 20X = –40.000000
    Result Y = –58.000000
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    –3.0
    Result X^3 = –27.000000
    Result 10X^2 = 90.000000
    Result 20X = –60.000000
    Result Y = –147.000000
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    +1.0
    Result X^3 = 1.000000
    Result 10X^2 = 10.000000
    Result 20X = 20.000000
    Result Y = 41.000000
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    +2.0
    Result X^3 = 8.000000
    Result 10X^2 = 40.000000
    Result 20X = 40.000000
    Result Y = 38.000000
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    +3.0
    Result X^3 = 27.000000
    Result 10X^2 = 90.000000
    Result 20X = 60.000000
    Result Y = 27.000000
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    -1.125
    Result X^3 = -1.423828
    Result 10X^2 = 12.656250
    Result 20X = -22.500000
    Result Y = -6.580078
    Press any key to continue . . . _
    -------------------------------------------------
    Enter a floating-point number for x:
    +2.75
    Result X^3 = 20.796875
    Result 10X^2 = 75.625000
    Result 20X = 55.000000
    Result Y = 30.171875
    Press any key to continue . . . _
  4. 17.12 Given the program segment shown below, obtain the results for the following floating-point numbers:

    flp_num1 = 125.0, flp_num2 = 245.0
    flp_num1 = 650.0, flp_num2 = 375.0
    flp_num1 = 755.125, flp_num2 = 575.150
          . . .
    FLD flp_num1
    FSQRT  
    FLD flp_num2
    FSQRT  
    FSUBP  ST(1), ST(0) FST rslt
          . . .
    flp_num1 = 125.0, flp_num2 = 245.0
    Result = -4.472136
    flp_num1 = 650.0, flp_num2 = 375.0
    Result = 6.130181
    flp_num1 = 755.125,  flp_num2 = 575.150
    Result = 3.497252
  5. 17.14 Write an assembly language module embedded in a C program to calculate the tangent of the following angles using the sine and cosine of the angles:

    30,45,and 60

    //tan.cpp
    //calculate the tangent of the following angles:
    //30 deg, 45 deg, and 60 deg
    //using the sine and cosine of the angles
    //tangent = sine/cosine

    #include "stdafx.h"

    int main (void)

    {
    //define angles in radians
      double angle_30, angle_45, angle_60,
        rslt_30, rslt_45, rslt_60;
      angle_30 = 0.523598775; //30 deg must be
          //in radians
      angle_45 = 0.785398163; //45 deg must be
          //in radians
      angle_60 = 1.047197551; //60 deg must be
          //in radians
    //switch to assembly
     _asm
    {//calculate the tangent of 30 degrees
       FLD angle_30  //30 deg -> ST(0)
       FSIN   //sine 30 -> ST(0)

       FLD angle_30  //30 deg -> ST(0)
          //sine 30 -> ST(1)
     FCOS     //cos 30 -> ST(0)
     FDIVP  ST(1), ST(0  //sine 30 / cos 30
          //-> ST(1), pop
          //sine 30 / cos 30
          //-> ST(0)
     FST rslt_30    //store tangent 30

    //calculate the tangent of 45 degrees
      FLD   angle_45 //45 deg -> ST(0)
      FSIN      //sine 45 -> ST(0)
      FLD   angle_45 //45 deg -> ST(0)
          //sine 45 -> ST(1)
      FCOS      //cos 45 -> ST(0)
      FDIVP  ST(1), ST(0) //sine 45 / cos 45
          //-> ST(1), pop
          //sine 45 / cos 45
          //-> ST(0)
      FST   rslt_45  //store tangent 45

    //calculate the tangent of 60 degrees
      FLD  angle_60  //60 deg -> ST(0)
      FSIN      //sine 60 -> ST(0)

      FLD  angle_60  //60 deg -> ST(0)
          //sine 60 -> ST(1)
      FCOS      //cos 60 -> ST(0)
      FDIVP ST(1), ST(0) //sine 60 / cos 60
          //-> ST(1), pop
          //sine 60 / cos 60
          //-> ST(0)
      FST  rslt_60  //store tangent 60
    }
    //display results
      printf ("Tangent_30 = %f\n\n", rslt_30);

      printf ("Tangent_45 = %f\n\n", rslt_45);

      printf ("Tangent_60 = %f\n\n", rslt_60);

      return 0;
    }
    Tangent 30 = 0.577350

    Tangent 45 = 1.000000

    Tangent 60 = 1.732051

    Press any key to continue . . . _