Intel 80x86 Assembler Programming Assignments

written by Keith Fenske
Copyright (c) 2002 by Keith Fenske.  All rights reserved.

Intel 80x86 assembler is a low-level machine programming language for IBM PC compatible computers such as those running Linux, MS-DOS, or Windows.  The examples below are written for NASM, a free portable assembler.  "The Art of Assembly Language Programming" is a good on-line resource written by Randall Hyde.  For DOS INT 21h function codes, refer to Ralf Brown's Interrupt List, or to summarized lists such as the one by Barry Wilks.
 
print name and age on standard output assignment solution
convert unsigned binary number to ASCII assignment solution
convert signed binary number to ASCII assignment solution
read input and print left/center/right aligned assignment solution
read unsigned decimal number and print in hexadecimal assignment solution
Fibonacci sequence using recursive subroutine calls assignment solution
Fibonacci sequence using loops and an array assignment solution


print name and age on standard output

Write an Intel 80x86 assembly language program to print two lines of output with your name and your age.  The first line will have your name and the second line will have your age.  Use complete sentences as in the following example:
My name is Keith Fenske.
I am 21 years old.
Write both lines as a single string using one call to the DOS function code 40h.  (Refer to your DOS documentation.)

convert unsigned binary number to ASCII

Write an Intel 80x86 assembly language program to convert an unsigned binary number into printed decimal form (ASCII).  The binary number must be 16 bits (one word).  Put the number in a word declared in your program.  Don't ask the user for input.  Change the number several times to test that your program works correctly.

Print the decimal form as part of a proper English sentence.  For example, if the number is 1342, you should print:

The unsigned decimal number is 01342.
You may print leading zeros (that is, the "0" in front of "1342").  The required assembly concepts are: basic instructions, loops, and documentation for the DIV/IDIV instruction.  If the divide instructions are not in your textbook, then look at the on-line help in NASM-IDE.

Suggestion:  Once your program correctly converts unsigned 16-bit binary numbers, write a new version that converts unsigned 32-bit binary numbers.  Hint: a 16-bit number loops 5 times for a maximum of 5 decimal digits, while a 32-bit number loops 10 times.


convert signed binary number to ASCII

You have already written a program to convert an unsigned binary number into printed decimal form (ASCII).  Copy that program into a new file, and change the new program to print a signed 16-bit binary number in decimal form.  For negative numbers, print a leading minus sign ("-").  Use leading spaces instead of leading zeros.  For example, if the number is -278, you should print:
The signed decimal number is   -278.
Note that the minus sign goes in front of the first non-zero digit.  If the number is positive, then print a space instead of a sign.  For example, if the number is 32767, you should print:
The signed decimal number is  32767.
Suggestion:  This program will use a 16-bit integer division instruction.  Once the 16-bit version works correctly, make two new versions: one to print a signed 8-bit number using 8-bit division, and another to print a signed 32-bit number using 32-bit division.

read input and print left/center/right aligned

This assignment has three parts.  The same program is used for all three parts.  Please finish part #1 before starting part #2, and finish part #2 before starting part #3.


Part #1 (Buffered Input):

Write an Intel 80x86 assembly language program to read a line of input from the user (keyboard), and then print the same line again as output.  Buffered input is done with the DOS function code AH=0Ah.  Please read your INT 21h documentation.

Here is an example.  First, prompt the user for input with a message like this:

Please type a line of text:
Let the user type a line of text, for example:
My name is Keith.
Then your program repeats the same text:
You typed, "My name is Keith."
Your printed output should be done with a single call to the DOS "write string" function code 40h.  That means, you must construct an output string from three parts:

Part #2 (Read-Print Loop)

Change your program from part #1 to read input in a loop, until the input is empty: no characters, only the Enter key.

Here is an example.  First, prompt the user for input with a message like this:

Please type a line of text,
or an empty line (Enter key only) to quit:
Let the user type a line of text, for example:
My name is Keith.
Your program repeats the same text:
You typed, "My name is Keith."
Then go back and ask for more input:
Please type a line of text,
or an empty line (Enter key only) to quit:
When the user types an empty line, print a good-bye message before exiting.  Here is an example:
Thank you for typing to me!

Part #3 (Complete Program)

Change your program from part #2 to read a line of input from the user (keyboard), and print the same line three different ways: Input is read in a loop, until the input is empty: no characters, only the Enter key.  Here is an example.  First, prompt the user for input with a message like this:
Please type a line of text,
or an empty line (Enter key only) to quit:
Let the user type a line of text, for example:
My name is Keith.
Then your program prints the same text with left alignment:
Left aligned text with right fill:
|My name is Keith.***********************************|
The "*" characters are called the "fill" characters because they fill the line to its maximum size.  The "|" characters are only to show you the beginning and end of the lines.  Next, print the same text with center alignment:
Center aligned text with left/right fill:
|*****************My name is Keith.******************|
Half of the fill characters go on the left, and half go on the right.  (Question: what do you do if the number of fill characters is odd?)  Then print the same text with right alignment:
Right aligned text with left fill:
|***********************************My name is Keith.|
Finally, go back and ask the user for more input:
Please type a line of text,
or an empty line (Enter key only) to quit:
Note: for center alignment, use SHR to divide by two.  You don't need the DIV or IDIV instructions.  Test your program with input that has one character, two characters, three characters, the maximum input length, the maximum minus one, the maximum minus two, etc.

read unsigned decimal number and print in hexadecimal

Write an Intel 80x86 assembly language program to read an unsigned decimal number from the user (keyboard), and then print the same number in hexadecimal.  Input is read in a loop, until the input is empty (no characters, only the Enter key), or when the number is zero.

Your program must check for errors:

To help you, here is an example:
Please type an unsigned decimal number from 1 to 65535,
or the number 0 to quit: 4095
Your number is 0FFF in hexadecimal.

Please type an unsigned decimal number from 1 to 65535,
or the number 0 to quit: 99999
Sorry, your number is too big.

Please type an unsigned decimal number from 1 to 65535,
or the number 0 to quit: 2204x3.6=?
Sorry, your input is not an unsigned decimal number from 0 to 65535.
Please type only digits from 0 to 9 and then press the Enter key.
Please do not type spaces or other punctuation characters.

Please type an unsigned decimal number from 1 to 65535,
or the number 0 to quit: 0
See you later!
Suggestion:  After your program correctly does unsigned 16-bit numbers, write a new version to do unsigned 32-bit numbers.

Fibonacci sequence using recursive subroutine calls

Write an Intel 80x86 assembly language program to compute the Fibonacci sequence using recursive subroutine calls and the stack.  For this assignment, let the Fibonacci function be defined as:
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)
Please note this definition is unusual in that the function is defined starting at f(0) instead of f(1).  The first few elements of the sequence are 1, 1, 2, 3, 5, 8, 13, 21, etc.

You must write a subroutine that takes the parameter n in the 32-bit EAX register and returns the function value in the same EAX register.  This function must be recursive.  To compute f(n) when n>1, the function must call itself twice: once for the value of f(n-1) and once for the value of f(n-2).

The initial function parameter n may be a constant declared in your program.  Don't ask the user for input.  Change the number several times to test that your program works correctly.

Print the function result as part of a proper English sentence.

Questions:

A second version of this program will be faster but more difficult to write.

Fibonacci sequence using loops and an array

Write a second Intel 80x86 assembly language program to compute the Fibonacci sequence using loops and an array.  The first version of this assignment was limited by the number of subroutine calls, with an O(2n) order of complexity.  This second version uses a much faster O(n) loop to calculate the same result.  An equivalent pseudo-code program for this version is:
array[0] = 1;
array[1] = 1;
for (i = 2; i <= n; i ++)
   array[i] = array[i-1] + array[i-2];
Use unsigned 32-bit integers for the array.  Each element in the array will be 4 bytes long, so to calculate the address of an element in the array, the array index must be multiplied by 4.  That is, the address of array[1] is the address of the array plus 4 bytes.  The address of array[2] is the address of the array plus 8.  And so on.

Similar to the first version, the initial function parameter n may be a constant declared in your program.  Don't ask the user for input.  Change the number several times to test that your program works correctly.  Print the function result as part of a proper English sentence.

Once your program is working correctly, compare the time taken by this program for large values of n, as compared to the first version using recursive subroutines.


Copyright (c) 2002 by Keith Fenske.  All rights reserved.