Appendix B
1.5 Convert the octal number 173.258 to decimal.
1.9 Add the following binary numbers to yield a 12-bit sum:
1.16 Multiply the unsigned binary numbers 11112 and 00112.

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 |
1.21 Add the following BCD numbers:
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.
(a)
(b)
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 |
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
3.6 Differentiate between the operation of the following two move instructions:
(a) MOV EBX, 1234ABCDH
(b) MOV [EBX], 1234H
(a) Moves the immediate value of 1234ABCDH to register EBX.
(b) Moves the immediate value of 1234H to the address pointed to by register EBX.
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.444445Press any key to continue . . . _
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.1667Press any key to continue . . . _
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.18 To what does the expression 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 = 16Press any key to continue . . . _
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 3Press any key to continue . . . _
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 100Press any key to continue . . . _
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;
}
AAAAAAAAAAAAAAAAAAAAAAAAAPress any key to continue . . . _
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 edcbaabcde 12345Press any key to continue . . . _
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 = 52Press any key to continue . . . _
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.
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.
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 |
5.4 Convert the positive 2s complement numbers shown below to negative numbers in 2s complement representation.
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 = –128Press any key to continue . . . _
------------------------------------------------------
Enter two signed integers:
555 444
Result = 555Press any key to continue . . . _
------------------------------------------------------
Enter two signed integers:
–400 400
Result = 400Press any key to continue . . . _
------------------------------------------------------
Enter two signed integers:
750 750
Result = 750Press any key to continue . . . _
------------------------------------------------------
Enter two signed integers:
–800 –800
Result = –800Press any key to continue . . . _
------------------------------------------------------
Enter two signed integers:
–100 –101
Result = –100Press any key to continue . . . _
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 positivePress any key to continue . . . _
-----------------------------------------------------
Enter two signed integers:
28000 30000 //6D60H 7530H
Result = 2800 //Difference = F830H
//Sign is negativePress any key to continue . . . _
-----------------------------------------------------
Enter two signed integers:
-4500 -6000 //EE6CH E890H
Result = -6000 //Difference = 05DCH
//Sign is positivePress any key to continue . . . _
-----------------------------------------------------
Enter two signed integers:
-6000 -4500 //E890H EE6CH
Result = -6000 //Difference = FA24H
//Sign is negativePress any key to continue . . . _
-----------------------------------------------------
Enter two signed integers:
750 -600 //02EEH FDA8H
Result = -600 //Difference = 0546H
//Sign is positivePress any key to continue . . . _
-----------------------------------------------------
Enter two signed integers:
-600 750 //FDA8H 02EEH
Result = -600 //Difference = FABAH
//Sign is negativePress any key to continue . . .
6.3 Determine if an overflow occurs for the operation shown below. The operands are signed numbers in 2s complement representation.

No overflow, because
6.7 Determine whether the conditional jump instructions shown below will cause a jump to DEST.
(a) 004FH + 200D JS DEST
004FH + 00C8H = 0117H
Sign is positive; therefore no jump.
(b) FF38H + 200D JZ DEST
FF38H + 00C8H = 1 ← 0000H
Result is zero; therefore, a jump will occur.
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).
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.7.3 Determine the result of each instruction for the following program segment:

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.

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
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 4sum of four integers = 10Press any key to continue . . . _
-----------------------------------------------------
Enter four decimal integers:
25 50 75 100sum of four integers = 250Press any key to continue . . . _
-----------------------------------------------------
Enter four decimal integers:
1000 2000 3000 4000sum of four integers = 10000Press any key to continue . . . _
-----------------------------------------------------
Enter four decimal integers:
37 1200 750 875sum of four integers = 2862Press any key to continue . . . _
8.3 Using only logic instructions, write one instruction for each of the following parts that will perform the indicated operations.
(a) Set the low-order four bits of register AX.
OR AX, 000FH(b) Reset the high-order three bits of register AX.
AND AX, 1FFFH(c) Invert bits 7, 8, and 9 of register AX.
XOR AX, 0380H8.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:
00A07000Bit is in position 15 -- 0Press any key to continue . . . _
------------------------------------------------------
Enter an 8-digit hexadecimal number:
7BC68000Bit is in position 15 -- 0Press any key to continue . . . _
------------------------------------------------------
Enter an 8-digit hexadecimal number:
FFFF0001Bit is in position 15 -- 0Press any key to continue . . . _
------------------------------------------------------
Enter an 8-digit hexadecimal number:
80D10000Bit is in position 31 -- 16Press any key to continue . . . _
------------------------------------------------------
Enter an 8-digit hexadecimal number:
0DC00000Bit is in position 31 -- 16Press any key to continue . . . _
------------------------------------------------------
Enter an 8-digit hexadecimal number:
80000000Bit is in position 31 -- 16Press any key to continue . . . _
------------------------------------------------------
Enter an 8-digit hexadecimal number:
00000000BSF opnd has no 1sPress any key to continue . . . _
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:
FFFFA85BSAL result = 85B00000
SAL flags = 86SAR result = FFFFFFFF
SAR flags = 87Press any key to continue . . . _
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:
8SAL result = 64
SAR result = 1Press any key to continue . . . _
------------------------------------------------------
Enter a decimal number:
–8SAL result = –64
SAR result = –1Press any key to continue . . . _
------------------------------------------------------
Enter a decimal number:
–10SAL result = –80
SAR result = –2 //1.25; 1111 ... 1111 0110
//1111 ... 1111 1110
Press any key to continue . . . _
------------------------------------------------------
Enter a decimal number:
25SAL result = 200
SAR result = 3 //3.125; 0000 ... 0001 1001
//0000 ... 0000 0011
Press any key to continue . . . _
------------------------------------------------------
Enter a decimal number:
–25SAL result = –200
SAR result = –4 //–3.125; 1111 ... 1110 0111
//1111 ... 1111 1100
Press any key to continue . . . _
------------------------------------------------------
Enter a decimal number:
500SAL result = 4000
SAR result = 62 //62.5; 0000 ... 0001 1111 0100
//0000 ... 0000 0011 1110
Press any key to continue . . . _
------------------------------------------------------
Enter a decimal number:
1000SAL result = 8000
SAR result = 125Press any key to continue . . . _
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 |
9.3 Indicate whether an overflow occurs for the operation shown below. The numbers are in radix complementation for radix 3.

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 .
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 = 0Press any key to continue . . . _
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 diLP1: 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, jumpLP4: MOV [DI], AL ;move valid char to dst
INC DI ;inc di to next dstLP2: INC SI ;addr of next character
LOOP LP1 ;jump, get char in opfld;display result
MOV AH, 09H
LEA DX, RSLT
INT 21HBEGIN 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 =
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

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 interruptBEGIN ENDP
END BEGIN
Enter characters: aBCdeFGh
Result = HGFEDCBA
------------------------------------------------------
Enter characters: ihgfedcba
Result = ABCDEFGHI
------------------------------------------------------
Enter characters: ABCDEFGHIJ
Result = JIHGFEDCBA
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:
Search the list to find the smallest number.
After finding the smallest number, exchange this number with the first number.
Search the list again to find the next smallest number, starting with the second number.
Then exchange this (second smallest) number with the second number.
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 - 1LP1: MOV CX, DX ;cx is loop2 ctrLP2: 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 bufferNEXT: 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 interruptBEGIN ENDP
END BEGIN
Enter numbers: 7658943034
Sorted numbers = 0334456789
------------------------------------------------------
Enter numbers: 7548391235
Sorted numbers = 1233455789
------------------------------------------------------
Enter numbers: 9876543210
Sorted numbers = 0123456789
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 1AX = 0000 0001 0000 0000
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:
450Multiplicand = 450
Multiplier = 10
Product = 4500Press any key to continue . . . _
------------------------------------------------------
Enter a signed decimal multiplicand:
–5Multiplicand = –5
Multiplier = 10
Product = –50Press any key to continue . . . _
------------------------------------------------------
Enter a signed decimal multiplicand:
6000Multiplicand = 6000
Multiplier = 10
Product = 60000Press any key to continue . . . _
------------------------------------------------------
Enter a signed decimal multiplicand:
–6000Multiplicand = –6000
Multiplier = 10
Product = –60000Press any key to continue . . . _
------------------------------------------------------
Enter a signed decimal multiplicand:
65535Multiplicand = 65535
Multiplier = 10
Product = 655350Press any key to continue . . . _
------------------------------------------------------
Enter a signed decimal multiplicand:
–65535Multiplicand = –65535
Multiplier = 10
Product = –655350Press any key to continue . . . _
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 20Dividend = 450
Divisor = 20Quotient = 22
Remainder = 10Press any key to continue . . . _
------------------------------------------------------
Enter a decimal dividend and divisor:
25000 250Dividend = 25000
Divisor = 250Quotient = 100
Remainder = 0Press any key to continue . . . _
------------------------------------------------------
Enter a decimal dividend and divisor:
25000 30Dividend = 25000
Divisor = 30Quotient = 833
Remainder = 10Press any key to continue . . . _
------------------------------------------------------
Enter a decimal dividend and divisor:
4660 86Dividend = 4660
Divisor = 86Quotient = 54
Remainder = 16Press any key to continue . . . _
9.38 Write an assembly language module embedded in a C program that evaluates the expression shown below, where , , , and .
//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 = 12CPress any key to continue . . . _
10.5 In each part below, assume that the following instructions are executed:
ADD AL, BL
DAA
(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.
(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 . . . _
10.8 Perform a subtraction and adjustment of the following two operands: 07 – 09. Show the details of the subtraction and adjustment.

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.

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

;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
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 . . . _
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
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.

Add bias: (for unnormalized fraction) Normalize: shift fraction left 4 to yield an implied 1

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 5flp_rslt1 = 2.300000
flp_rslt2 = 6.900000
flp_rslt3 = 11.900000Press any key to continue . . . _
------------------------------------------------------
Enter 3 floating-point numbers and 1 integer:
32.456 45.789 16.123 10flp_rslt1 = 45.789001
flp_rslt2 = 94.368004
flp_rslt3 = 104.368004Press any key to continue . . . _


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

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 5flp_rslt1 = 2.300000
flp_rslt2 = 9.384001
flp_rslt3 = 46.920002Press any key to continue . . . _
------------------------------------------------------
Enter 3 floating-point numbers and 1 integer:
32.4 45.7 16.1 10flp_rslt1 = 45.700001
flp_rslt2 = 23838.949219
flp_rslt3 = 238389.500000Press any key to continue . . . _
------------------------------------------------------
Enter 3 floating-point numbers and 1 integer:
–23.6 +28.5 –27.4 –12flp_rslt1 = 28.500000
flp_rslt2 = 18429.240234
flp_rslt3 = –221150.875000Press any key to continue . . . _

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.
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.

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.0Equivalent resistance = 333.333344 ohmsPress any key to continue . . . _
------------------------------------------------------
Enter three resistor values:
72.25 1000 64.38Equivalent resistance = 32.923325 ohmsPress any key to continue . . . _
------------------------------------------------------
Enter three resistor values:
750.0 75000.0 3600.0Equivalent resistance = 615.595032 ohmsPress any key to continue . . . _
------------------------------------------------------
Enter three resistor values:
1.0 2.0 3.0Equivalent resistance = 0.545455 ohmsPress any key to continue . . . _
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.
//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.0Result = 0.015915Press any key to continue . . . _
------------------------------------------------------
Enter two floating-point numbers:
20.0 30.0Result = 0.006497Press any key to continue . . . _
------------------------------------------------------
Enter two floating-point numbers:
0.5 0.5Result = 0.318310Press any key to continue . . . _
------------------------------------------------------
Enter two floating-point numbers:
0.05 0.08Result = 2.516461Press any key to continue . . . _
------------------------------------------------------
Enter two floating-point numbers:
0.05 0.05Result = 3.183099Press any key to continue . . . _
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
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 21HBEGIN 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
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
; -----------------------------------------------------
//12121278913.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
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
; -----------------------------------------------------
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.350000Press any key to continue . . . _
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 . . . _
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 . . . _
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
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
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
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.
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.
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 BEGINEnter 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 times17.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 . . . 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.
//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 . . . _
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
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:
//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 . . . _