; CIS-261
; implementation of I/O procedures called by macros in io.obj
; flat memory model version
.386
.MODEL FLAT
PUBLIC itoaproc, atoiproc, dtoaproc, atodproc, outproc, inproc, szlenproc
.CODE
; itoaproc(source, dest)
; convert integer (source) to string of 6 characters at given destination address
itoaproc PROC NEAR32
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
push eax ; Save registers
push ebx ; used by
push ecx ; procedure
push edx
push edi
pushf ; save flags
mov ax, [ebp+12] ; first parameter (source integer)
mov edi, [ebp+8] ; second parameter (dest offset)
ifSpecial: cmp ax,8000h ; special case -32,768?
jne EndIfSpecial ; if not, then normal case
mov BYTE PTR [edi],'-' ; manually put in ASCII codes
mov BYTE PTR [edi+1],'3' ; for -32,768
mov BYTE PTR [edi+2],'2'
mov BYTE PTR [edi+3],'7'
mov BYTE PTR [edi+4],'6'
mov BYTE PTR [edi+5],'8'
jmp ExitIToA ; done with special case
EndIfSpecial:
mov dx, ax ; save source number
mov al,' ' ; put blanks in
mov ecx,5 ; first five
cld ; bytes of
rep stosb ; destination field
mov ax, dx ; copy source number
mov cl,' ' ; default sign (blank for +)
IfNeg: cmp ax,0 ; check sign of number
jge EndIfNeg ; skip if not negative
mov cl,'-' ; sign for negative number
neg ax ; number in AX now >= 0
EndIfNeg:
mov bx,10 ; divisor
WhileMore: mov dx,0 ; extend number to doubleword
div bx ; divide by 10
add dl,30h ; convert remainder to character
mov [edi],dl ; put character in string
dec edi ; move forward to next position
cmp ax,0 ; check quotient
jnz WhileMore ; continue if quotient not zero
mov [edi],cl ; insert blank or "-" for sign
ExitIToA: popf ; restore flags and registers
pop edi
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret 6 ;exit, discarding parameters
itoaproc ENDP
; dtoaproc(source, dest)
; convert double (source) to string of 11 characters at given offset in DS (dest)
dtoaproc PROC NEAR32
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
push eax ; Save registers
push ebx ; used by
push ecx ; procedure
push edx
push edi
pushf ; save flags
mov eax, [ebp+12] ; first parameter (source double)
mov edi, [ebp+8] ; second parameter (dest addr)
ifSpecialD: cmp eax,80000000h ; special case -2,147,483,648?
jne EndIfSpecialD ; if not, then normal case
mov BYTE PTR [edi],'-' ; manually put in ASCII codes
mov BYTE PTR [edi+1],'2' ; for -2,147,483,648
mov BYTE PTR [edi+2],'1'
mov BYTE PTR [edi+3],'4'
mov BYTE PTR [edi+4],'7'
mov BYTE PTR [edi+5],'4'
mov BYTE PTR [edi+6],'8'
mov BYTE PTR [edi+7],'3'
mov BYTE PTR [edi+8],'6'
mov BYTE PTR [edi+9],'4'
mov BYTE PTR [edi+10],'8'
jmp ExitDToA ; done with special case
EndIfSpecialD:
mov edx, eax ; save source number
mov al,' ' ; put blanks in
mov ecx,10 ; first ten
cld ; bytes of
rep stosb ; destination field
mov eax, edx ; copy source number
mov cl,' ' ; default sign (blank for +)
IfNegD: cmp eax,0 ; check sign of number
jge EndIfNegD ; skip if not negative
mov cl,'-' ; sign for negative number
neg eax ; number in EAX now >= 0
EndIfNegD:
mov ebx,10 ; divisor
WhileMoreD: mov edx,0 ; extend number to doubleword
div ebx ; divide by 10
add dl,30h ; convert remainder to character
mov [edi],dl ; put character in string
dec edi ; move forward to next position
cmp eax,0 ; check quotient
jnz WhileMoreD ; continue if quotient not zero
mov [edi],cl ; insert blank or "-" for sign
ExitDToA: popf ; restore flags and registers
pop edi
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret 8 ;exit, discarding parameters
dtoaproc ENDP
; atoiproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an integer value which is returned in AX.
; Leading blanks are skipped. A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit, and the address of
; the terminating character is in ESI.
; The following...
; CIS-261
; M08.ASM
; Demo program of IO.H and IO.ASM usage
; @topic W080093 IO.H and IO.ASM usage demo
; @brief Console Input/Output OUTPUT, INPUT, SZLEN, DTOA, ITOA, ATOI 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
intro1 BYTE "Jeramy Brian", 0
intro2 BYTE "Assignment M08", 0
intro3 BYTE "1. Inputs two 8-bit unsigned integers from the user, calculates the sum of the two numbers, and prints the result on the screen.", 0
addPrompt1 BYTE "Please enter two numbers in the range [0, 255], in the format '1 + 2': ", 0
addPrompt2 BYTE "Would you like to add more numbers (y/N): ", 0
addError1 BYTE "ERROR :: OVERFLOW :: (BYTE, DWORD) :: (", 0
addError2 BYTE "ERROR :: This number is too big. ::", 0
intro4 BYTE "2. Inputs two 32-bit signed integers from the user, calculates their difference, and prints the result.", 0
subPrompt1 BYTE "Please enter two numbers in the range [-2147483648, 2147483647], in the format '1 - 2': ", 0
subPrompt2 BYTE "Would you like to subtract more numbers (y/N): ", 0
subError1 BYTE "ERROR :: OVERFLOW :: (SDWORD) :: (", 0
exitPrompt BYTE "Press enter to exit...", 0
ENDL BYTE 13, 10, 0
equals BYTE " = ", 0
subtract BYTE "-", 0
addition BYTE "+", 0
genError BYTE "ERROR :: That entry could not be understood. :: ", 0
contPrompt BYTE "Press 'Enter' to continue...", 0
errorFrm1 BYTE ", ", 0
errorFrm2 BYTE ")", 0
numbers BYTE "0123456789", 0 ;Second 0 is a place holder
space BYTE " ", 0
.STACK 100h ; (default is 1-kilobyte stack)
.DATA ; Begin initialized data segment
dtoa_buffer BYTE 11 DUP (?), 0
atoa_buffer BYTE 6 DUP (?), 0
addBuffer BYTE 12 DUP (?)
add1Str BYTE 3 DUP (?), 0
add1 BYTE ?
add2Str BYTE 3 DUP (?), 0
add2 BYTE ?
addAns BYTE ?
addAnsStr BYTE 3 DUP (?), 0
addOFAnsStr BYTE 6 DUP (?), 0
addErrAns DWORD ?
;BOOL Value for code reuse
isSub BYTE 0
subBuffer BYTE 26 DUP (?)
sub1Str BYTE 11 DUP (?)
sub1 SDWORD ?
sub2Str BYTE 11 DUP (?)
sub2 SDWORD ?
subAns SDWORD ?
subAnsStr BYTE 26 DUP (?)
tmpAddr DWORD ?
numCounter DWORD 0
strCounter DWORD 0
strLength DWORD 0
numCounter1 DWORD 0
numCounter2 DWORD 0
ansCounter DWORD 0
tmpCounter DWORD 0
tmpStr BYTE ?
doItAgainCntr DWORD 0
doItAgainBuffer BYTE 6 DUP (?)
.CODE ; Begin code segment
_main PROC ; Beginning of code
output intro1 ; My name
output ENDL ; Start New Line
output intro2 ; The assignment
output ENDL ; Start New Line
output intro3 ; First part of assignment
output ENDL ; Start New Line
output ENDL ; Start New Line
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
addFunc:
output addPrompt1 ; Give user instructions
input addBuffer, 12 ; ...read zero to 10 ASCII characters
output ENDL ; Start New Line
szlen addBuffer ; get the length of the input
mov strLength, eax ; put the length in a variable
mov tmpCounter, eax ; set the length to a variable that is going to be decrimented
mov tmpAddr, OFFSET add1Str ; set the address of add1Str to a temp value that can be incremented
lea edx, ds:[addBuffer] ; load the address of the addBuffer into edx
jmp compAdd ; jump to the comp add 'function' this is to compare the entries on the buffer string to values we are looking for
;make sure we have a '+' symbol
compAdd:
mov al, addition ; load the addition value into eax
mov bl, [edx] ; move the value stored in the eax register to bl
cmp al, bl ...