CIS-77 Home http://www.c-jump.com/CIS77/CIS77syllabus.htm
The purpose of this lab assignment is to experiment with
console I/O
integer addition and subtraction instructions.
You can continue using Microsoft VC++ project created earlier.
For related topics, see CPU Flags and Data Manipulation presentation ( slide version ).
In order to write useful programs, we need to be able to handle console input and output.
For example, a typical numeric input function
Accepts a string of character codes representing a number.
Converts the characters to a 2's complement in a register.
Stores the value in a memory location associated with some variable name.
A numeric output function
Starts with a 2's complement number in a register.
Converts value to a string of characters that represent the number.
Outputs the string.
The file IO.H ( download ) provides a set of macro definitions for
console I/O and
numeric conversions.
Each macro looks much like an 80×86 instruction, but actually expands to several instructions, including calls to external procedures that do most of the work.
The source code for all external procedures is in the file IO.ASM ( download )
Sample program M08.ASM ( download ) demonstrates usage of IO.H facilities.
; CIS-77 ; M08.ASM ; Demo program of IO.H and IO.ASM usage .386 ; Tells MASM to use Intel 80386 instruction set. .MODEL FLAT ; Flat memory model option casemap:none ; Treat labels as case-sensitive INCLUDE IO.H ; header file for input/output .CONST ; Constant data segment TXTPROMPT BYTE "Please enter up to 10 characters of text: ", 0 TXTENTERED BYTE " You've entered: ", 0 TXTLENGTH BYTE " Number of characters entered: ", 0 INPROMPT BYTE " Please enter an integer: ", 0 ENDL BYTE ";", 13, 10, 0 OVERFLOW BYTE "*** Bad number, please try again!", 0 .STACK 100h ; (default is 1-kilobyte stack) .DATA ; Begin initialized data segment buffer BYTE 12 DUP (?) dtoa_buffer BYTE 11 DUP (?) atoa_buffer BYTE 6 DUP (?) .CODE ; Begin code segment _main PROC ; Beginning of code output TXTPROMPT ; Please enter up to 10 characters of text... input buffer, 12 ; ...read zero to 10 ASCII characters output TXTENTERED ; ...You've entered... output buffer ; ...print the input output ENDL ; new line szlen buffer ; Calculate length of user input, put result in eax dtoa dtoa_buffer, eax ; convert 32-bit signed integer to string output TXTLENGTH ; Number of characters entered... output dtoa_buffer ; ...print numeric result output ENDL ; new line itoa atoa_buffer, ax ; Convert 16-bit signed integer to string output TXTLENGTH ; Number of characters entered... output atoa_buffer ; ...print numeric result output ENDL ; new line @@: output INPROMPT ; Please enter an integer... input buffer, 12 ; ...read zero to 10 ASCII characters atoi buffer ; convert "[+/-]123" to 2's complement (result in AX) jno @F ; check overflow flag output OVERFLOW ; print error message output ENDL ; new line jmp @B ; back to the prompt @@: itoa atoa_buffer, ax ; Convert 16-bit signed integer to string output TXTENTERED ; ...You've entered... output atoa_buffer ; print result output ENDL ; new line ret _main ENDP END _main ; Marks the end of the module and sets the program entry point label
The output macro displays a string of characters starting at source location in the data segment:
output source
where source is the beginning of a null-terminated string in memory.
For example:
.CONST ; Constant data segment TXTPROMPT BYTE "HELLO", 0 ENDL BYTE 13, 10, 0 .. .CODE ; Code segment .. output TXTPROMPT ; print HELLO output ENDL ; print new line ..
Characters starting at source address are displayed until a null character is reached.
The null character terminates the output.
Flags or registers affected: none.
Inputs a string of characters from the keyboard.
It has two parameters, destination and length:
input destination, length
where
destination operand references a string of bytes in the data segment
length operand references the number of bytes reserved in the destination string.
For example,
.DATA ; Begin initialized data segment buffer BYTE 12 DUP (?) .. .CODE ; Code segment .. input buffer, 12 ; Read zero to 10 ASCII characters ..
Important: The destination string should be at least two bytes longer than the actual number of characters to be entered.
This allows for the operating system to add carriage return and line feed characters when user presses the Enter key.
The input macro automatically replaces the carriage return character by a null byte.
The result is a null-terminated string stored at the destination.
The input macro updates memory at the specified destination.
Flags or registers affected: none.
The szlen macro calculates the length of null-terminated string in memory:
szlen source
where source is the beginning of a null-terminated string in memory.
.DATA ; Begin initialized data segment
buffer BYTE 12 DUP (?)
..
.CODE ; Code segment
..
input buffer, 12 ; Read zero to 10 ASCII characters
szlen buffer ; Calculate user input length (result in EAX.)
..
The length is returned in EAX.
Flags affected: none.
The dtoa converts 32-bit signed integer (doubleword) to eleven-byte-long ASCII string at destination,
dtoa destination, source
where
destination operand is a string of exactly 11 ASCII characters in the data segment.
source operand is normally a register or memory operand.
.DATA ; Begin initialized data segment
minus_one DWORD 0FFFFFFFFh
dtoa_buffer BYTE 11 DUP (?)
..
.CODE ; Code segment
..
dtoa dtoa_buffer, eax ; Convert EAX value to string
output dtoa_buffer ; Print result
..
dtoa dtoa_buffer, [minus_one]
output dtoa_buffer ; Print result
..
The name dtoa stands for double to ASCII.
The result represents signed integer in the decimal number system.
The destination is always 11-byte area of storage in the data segment reserved with a BYTE directive.
The resulting string of characters has leading blanks if decimal number is shorter than 11 characters:
If the number is negative, a minus sign is immediately preceding the digits.
Since the decimal range for a word-length 2's complement number is
-2,147,483,648 to 2,147,483,647
there is no danger of generating too many characters to fit in an 11-byte-long field.
A positive number will always have at least one leading blank.
Flags or registers affected: none.
The atod converts an ASCII string at source to 32-bit signed integer number:
atod source
where source is a null-terminated string in the following format:
optional leading blanks (space characters, ASCII codes 20h)
optional + or - sign, followed by
digits
The resulting 2's complement number is put in EAX:
.DATA ; Begin initialized data segment
buffer BYTE 12 DUP (?)
..
.CODE ; Code segment
..
input buffer, 12 ; Read zero to 10 ASCII characters
atod buffer ; Convert string to 2's complement number
jno @F ; Check the overflow flag
; Handle input error:
..
@@:
; Success: result of conversion is in EAX
..
The offset of the terminating non-digit character is put in ESI.
If no input error detected,
The overflow flag OF is cleared.
Other flags are set accordingly to the result in EAX:
SF is 1 if the number is negative, and 0 otherwise.
ZF is 1 if the number is 0, and 0 if the number is nonzero.
PF reflects the parity of the number returned in EAX.
In addition, CF is 0 and DF is unchanged.
If input error is detected,
The overflow flag OF is set to 1.
EAX register contains zero.
Input error occurs if the source has no digits or is out of the range
-2,147,483,648 to 2,147,483,647
Once a digit code is encountered, atod continues scanning until any character other than a digit is encountered. Such a character terminates the scan.
The atod macro will typically be used immediately after the input macro.
The input macro produces a string of ASCII codes, including a trailing null character.
When atod is applied to the string, the null character serves as a terminating character for the scan.
If atod is applied to a string that comes from some source other than input, the programmer must ensure that the string has some trailing non-digit character to prevent atod from scanning too far.
The
atoi (ASCII to integer), and
itoa (integer to ASCII)
macros are the word-length (16-bit) versions of atod and dtoa.
The atoi macro scans a string of characters and produces the corresponding word-length 2's complement value in AX.
The itoa macro takes the 2's complement value stored in a word-length source and produces a string of exactly six characters representing this value in decimal format.
The macros are useful when dealing with values in the range
-32,768 to 32,767.
Sample program ATOI_ITOA_DEMO.ASM ( download ) demonstrates usage of atoi and itoa Macros:
.DATA ; Begin initialized data segment
buffer BYTE 8 DUP (?)
..
.CODE ; Code segment
..
input buffer, 8 ; Read zero to 6 ASCII characters
atoi buffer ; Convert string to 2's complement number
jno @F ; Check the overflow flag
; Handle input error:
..
@@:
; Success: result of conversion is in AX
itoa buffer, ax ; Convert 16-bit signed integer to string
..
; CIS-77 ; ATOI_ITOA_DEMO.ASM ; ATOI and ITOA usage demo program .386 ; Tells MASM to use Intel 80386 instruction set. .MODEL FLAT ; Flat memory model option casemap:none ; Treat labels as case-sensitive INCLUDE IO.H ; header file for input/output .CONST ; Constant data segment TXTPROMPT BYTE "Please enter a number between -32768 and +32767: ", 0 TXTENTERED BYTE "You've entered: ", 0 ENDL BYTE 13, 10, 0 OVERFLOW BYTE "*** Bad number, please try again!", 0 .STACK 100h ; (default is 1-kilobyte stack) .DATA ; Begin initialized data segment buffer BYTE 8 DUP (?) .CODE ; Begin code segment _main PROC ; Beginning of code @@: output TXTPROMPT ; Please enter a number... input buffer, 8 ; Read zero to 6 ASCII characters atoi buffer ; Convert string to 2's complement number jno @F ; Check the overflow flag ; Handle input error: output OVERFLOW ; print error message output ENDL ; print new line jmp @B ; back to the prompt @@: ; Success: result of conversion is in AX itoa buffer, ax ; Convert 16-bit signed integer to string output TXTENTERED ; You've entered... output buffer ; print result output ENDL ; print new line ret _main ENDP END _main ; Marks the end of the module and sets the program entry point label
Write an assembly program that
Inputs two 8-bit unsigned integers from the user, calculates the sum of the two numbers, and prints the result on the screen.
Inputs two 32-bit signed integers from the user, calculates their difference, and prints the result.
Make sure that the program handles every possible error condition that you can think of:
Bad input formats.
Sum and difference overflow conditions .
In case of an error, have the user retry the input and repeat the calculation.
Every CPU instruction in your program must have a brief comment!
The penalty for not following this rule is 15 pts deduction...
What to submit:
Submit only your ASM source file (not the EXE or project.)