I've been working on an assignment for my 8086 assembly language programming class and I have been stuck on it for the last day or so. We have to write a program (in 32-bit code) that will output a menu for the user, the user selects an option and is prompted to enter either a binary, decimal, or hexadecimal number (depending on which menu option they chose). Once the number has been entered, the program must then convert the given number into the other two bases and output all three numbers. I haven't finished the code for the conversions. I'm having issues understanding how to implement the code for conversions. I know how to do them on paper, but this seems to be another matter. Also, all binary number need to be LESS than 33 digits, decimal numbers LESS than 4294967295, and hex numbers LESS than 0FFFFFFFF. Here is a sample output of the program:
1) Enter a Binary Number
2) Enter a Decimal Number
3) Enter a Hexadecimal Number
4) Quit
Enter your choice --> 1
Enter a binary number (less than 33 digits) --> 10101010
Binary=10101010 Decimal=170 Hexadecimal=0AA
Here is the code I have done so far:
TITLE PROG2.asm ;File name of program
LF equ 0ah ;ASCII 10 - newline character
CR equ 0dh ;ASCII 13 - carriage return character
NEWLINE equ CR,LF ;Combine CR and LF for carriage return
DOUBLESPC equ NEWLINE,LF ;Combine NEWLINE and LF for double space
MAXSTR equ 256d ;Accept up to 256 character string
.586 ;Allow for Pentium instrucitons
.MODEL FLAT ;Memory model is FLAT (4GB)
INCLUDE io32.inc ;Include the 32 bit I/O procedures
.STACK 4096h ;4k hex bytes for stack
.DATA ;Data segment begins here
Intro BYTE NEWLINE,'WELCOME!',NEWLINE,\
'This program allows any user to enter ',\
'a binary, decimal, or hexadecimal number. The program ',\
'will then convert that number to the other two formats ',\
'and ',NEWLINE,\
'display the results on the screen.',DOUBLESPC,0
Error1 BYTE DOUBLESPC,'Error: Invalid input.',\
' Please try again.',DOUBLESPC,0
Error2 BYTE DOUBLESPC,'Error: Input too large.',\
' Please try again.',DOUBLESPC,0
Menu BYTE NEWLINE,' 1) Enter a Binary Number',\
NEWLINE,' 2) Enter a Decimal Number',\
NEWLINE,' 3) Enter a Hexadecimal Number',\
NEWLINE,' 4) Quit',NEWLINE,NEWLINE,0
Prompt BYTE NEWLINE,'Enter your choice --> ',0
BPrompt BYTE NEWLINE,NEWLINE,'Enter a binary number ',\
'(less than 33 digits) --> ',0
DPrompt BYTE NEWLINE,NEWLINE,'Enter a decimal number ',\
'(less than 4294967295d) --> ',0
HPrompt BYTE NEWLINE,NEWLINE,'Enter a hexadecimal number ',\
'(less than 0FFFFFFFFh) --> ',0
BinAns BYTE DOUBLESPC,'Binary=',0
DecAns BYTE DOUBLESPC,'Decimal=',0
HexAns BYTE DOUBLESPC,'Hexadecimal=0',0
TempChar BYTE ? ;Temporary character storage
BinVal DWORD 0h ;Will hold final Binary Value
DecVal DWORD 0h ;Will hold final Decimal Value
HexVal DWORD 0h ;Will hold final Hex Value
String BYTE MAXSTR dup(?) ;Holds max sring size
TempString BYTE MAXSTR DUP(0) ;Temporary string storage
TempInt DWORD 0h ;Temporary integer storage
KeyPress BYTE ? ;Temporary storage
TempNum DWORD ? ;Temporary number storage
Number DWORD 0h ;Holds number value
;************************** Main Body of Program *****************************
; Given : Nothing
; Process: Main Body - calls procedures to do the processing
; Return : Nothing
;*****************************************************************************
.CODE ;executable section begins here
_main:
lea esi,Intro ;point to intro string in data
call PrintString ;display the string
Repeat1:lea esi,Menu ;point to menu string in data
call PrintString ;display the string
lea esi,Prompt ;point to prompt message
call PrintString ;display the string
lea esi,TempNum ;point to storage for keypressed
call GetChar ; and get the char
Check1: cmp TempNum,'1' ;Test if 1 was typed
jne Check2 ; no, check for 2
call Binary ;If number equals 1 go to binary
jmp Repeat1 ;go to menu
Check2: cmp TempNum,'2' ;Test if 2 was typed
jne Check3 ; no, check for 3
call Decimal ;If number equals 2 go to Decimal
jmp Repeat1 ;go to menu
Check3: cmp TempNum,'3' ;Test if 3 was typed
jne Check4 ; no, check for 4
call Hexadecimal ;If number equals 3 go to hexadecimal
jmp Repeat1 ;go to menu
Check4: cmp TempNum,'4' ;Test if 4 was typed
je EndProgram ; yes, end the program
call MenuError ;go to error message for other inputs
EndProgram:
INVOKE ExitProcess,0 ;Exit program with return code 0
;********** Procedure to Convert Binary to Decimal & Hexadecimal **************
; Given : Menu option 1
; Process : Prompts user for binary number and calls 2 procedures to convert
; : from binary to decimal and hexadecimal
; Return : None
;******************************************************************************
Binary PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
lea esi,DPrompt ;point to dprompt message
call PrintString ;display the string
call GetNumBin ;Get user decimal number
cmp GetNumBin,'4294967295d' ;compare getnum to max input
jg TooLargeError ;if greater, go to TooLargeError
call ConvertB2D ;call convertb2d for binary to decimal
call ConvertB2H ;call convertb2h for binary to hex
call Repeat1 ;Go to Menu options
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Binary ENDP
;********** Procedure to Convert Decimal to Binary & Hexadecimal **************
; Given : Menu option 2
; Process : Prompts user for decimal number and calls 2 procedures to convert
; : from decimal to binary and hexadecimal
; Return : None
;******************************************************************************
Decimal PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
lea esi,DPrompt ;point to dprompt message
call PrintString ;display the string
call GetNumDec ;Get user decimal number
cmp GetNumDec,'4294967295d' ;compare getnum to max input
jg TooLargeError ;if greater, go to TooLargeError
call ConvertD2B ;call convertd2b for decimal to binary
call ConvertD2H ;call convertd2h for decimal to hex
call Repeat1 ;Go to Menu options
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Decimal ENDP
;********** Procedure to Convert Hexadecimal to Binary & Decimal **************
; Given : Menu option 3
; Process : Prompts user for hexadecimal number and calls 2 procedures to
; : convert from hexadecimal to binary and decimal
; Return : None
;******************************************************************************
Hexadecimal PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
lea esi,HPrompt ;point to hprompt
call PrintString ;display the string
call GetNumHex ;Get user Hex number
cmp GetNumHex,'4294967295d' ;compare getnum to max input
jg TooLargeError ;if greater, go to TooLargeError
call ConvertH2B ;call converth2b for hex to binary
call ConvertH2D ;call converth2d for hex to decimal
call Repeat1 ;Go to Menu options
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Hexadecimal ENDP
;********* Procedure to Print an Error for Invalid Menu Selection *************
; Given : Invalid menu option
; Process : Prints an error message and recalls the menu to display so the
; : user can input a valid selection
; Return : None
;******************************************************************************
MenuError PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
lea esi,Error1 ;point to error1 message
call PrintString ;display the string
call Repeat1 ;loops back to start of program
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
MenuError ENDP
;********** Procedure to Print an Error for Invalid Binary Input **************
; Given : Invalid menu option
; Process : Prints an error message and recalls the menu to display so the
; : user can input a valid selection
; Return : None
;******************************************************************************
TooLargeError PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
lea esi,Error2 ;point to error2 message
call PrintString ;display the string
call Repeat1 ;loops back to start of program
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
TooLargeError ENDP
;***************** Procedure to Convert Binary to Decimal *********************
; Given : User defined binary number
; Process : converts the binary number to decimal and prints the string
; :
; Return : None
;******************************************************************************
ConvertB2D PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
push 0h ;push 0h onto stack
mov eax,GetNumBin ;copy user number into eax
Loop1: cmp eax,30h ;loop condition comparison
je Print ;if equal, jump to print
Print: lea esi,DecAns ;point to decans
call PrintString ;display the string
pop edx ;display new user number(s)
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
ConvertB2D ENDP
;*************** Procedure to Convert Binary to Hexadecimal *******************
; Given : User defined binary number
; Process : Converts the binary number to hexadecimal and prints the string
; :
; Return : None
;******************************************************************************
ConvertB2H PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
push 0h ;push 0h onto stack
mov eax,GetNumBin ;copy user number into eax
Loop1: cmp eax,30h ;loop condition comparison
je Print ;if equal, jump to print
Print: lea esi,HexAns ;point to hexans
call PrintString ;display the string
pop edx ;display new user number(s)
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
ConvertB2H ENDP
;***************** Procedure to Convert Decimal to Binary *********************
; Given : User defined decimal number
; Process : Converts the decimal number to a binary number
; : and prints the string
; Return : None
;******************************************************************************
ConvertD2B PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
push 0h ;push 0h onto stack
mov ebx,2d ;copy 2d into ebx register
mov eax,GetNumDec ;copy user number into eax
Loop1: cmp eax,30h ;loop condition comparison
je Print ;if equal, jump to print
div ebx ;divide eax register by 2
push edx ;push edx onto stack
jmp Loop1 ;call loop1 to process next number
Print: lea esi,BinAns ;point to binans
call PrintString ;display the string
pop edx ;display new user number(s)
Loop2: cmp edx,0h ;compare edx register to 0h
je Done ; if equal, go to done
mov BinVal,edx ;copy edx into binval
lea esi,BinVal ;point to binval
call PutChar ;display the character
pop edx ;display new user number(s)
jmp Loop2 ;go to loop2 to process next number
Done: popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
ConvertD2B ENDP
;*************** Procedure to Convert Decimal to Hexadecimal ******************
; Given : User defined decimal number
; Process : Converts the decimal number to a hexadecimal number
; : and prints the string
; Return : None
;******************************************************************************
ConvertD2H PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
push 0h ;push 0h onto stack
mov ebx,16d ;copy 16d into ebx register
mov eax,GetNumDec ;copy user number into eax
Loop1: cmp eax,30h ;loop condition comparison
je Print ;if equal, jump to print
div ebx ;divide eax register by 16
cmp edx,39h ;compare cdx to 39h
jg Convert ;if greater, go to convert
push edx ; else, push edx to stack
Convert:cmp edx,41h ;compare edx to 41h
je Hex_A ; if equal, go to hex_a
cmp edx,42h ;compare edx to 42h
je Hex_B ; if equal, go to hex_b
cmp edx,43h ;compare edx to 43h
je Hex_C ; if equal, go to hex_c
cmp edx,44h ;compare edx to 44h
je Hex_D ; if equal, go to hex_d
cmp edx,45h ;compare edx to 45h
je Hex_E ; if equal, go to hex_e
cmp edx,46h ;compare edx to 46h
je Hex_F ; if equal, go to hex_f
Hex_A: push 41h ;push 41h on the stack
jmp Loop1 ;call loop1 to process next number
Hex_B: push 42h ;push 42h on the stack
jmp Loop1 ;call loop1 to process next number
Hex_C: push 43h ;push 43h on the stack
jmp Loop1 ;call loop1 to process next number
Hex_D: push 44h ;push 44h on the stack
jmp Loop1 ;call loop1 to process next number
Hex_E: push 45h ;push 45h on the stack
jmp Loop1 ;call loop1 to process next number
Hex_F: push 46h ;push 46h on the stack
jmp Loop1 ;call loop1 to process next number
Print: lea esi,HexAns ;point to hexans
call PrintString ;display the string
pop edx ;display new user number(s)
Loop2: cmp edx,0h ;compare edx to 0h
je Done ;if equal to 0h, go to done
mov HexVal,edx ;copy edx value into hexval
lea esi,HexVal ;point to hexval
call PutChar ;display the character
pop edx ;display new user number(s)
jmp Loop2 ;call loop2 to process next number
Done: popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
ConvertD2H ENDP
;*************** Procedure to Convert Hexadecimal to Binary *******************
; Given : User defined hexadecimal number
; Process : Converts the hexadecimal number to binary
; : and prints the string
; Return : None
;******************************************************************************
ConvertH2B PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
push 0h ;push 0h onto stack
mov eax,GetNumHex ;copy user number into eax
Loop1: cmp eax,30h ;loop condition comparison
je Print ;if equal, go to print
Print: lea esi,BinAns ;point to binans
call PrintString ;display the string
pop edx ;display new user number(s)
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
ConvertH2B ENDP
;*************** Procedure to Convert Hexadecimal to Decimal ******************
; Given : User defined hexadecimal number
; Process : Converts the hexadecimal number to decimal
; : and prints the string
; Return : None
;******************************************************************************
ConvertH2D PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
push 0h ;push 0h onto stack
mov eax,GetNumHex ;copy user number into eax
Loop1: cmp eax,30h ;loop condition comparison
je Print ;if equal, go to print
Print: lea esi,DecAns ;point to decans
call PrintString ;display the string
pop edx ;display new user number(s)
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
ConvertH2D ENDP
;**************** Procedure to ??????????????????????????? ********************
; Given :
; Process :
; :
; Return :
;******************************************************************************
MyProc PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
MyProc ENDP
;******************* Near procedure to print a string *************************
; This procedure uses a WHILE... loop to print a string of characters
; Given : The Address of the String to print on the STACK
; Process : Print the String by repeated calls to PrintChar procedure
; Return : Nothing
;******************************************************************************
MyPrintString PROC NEAR32 ;Define a NEAR32 procedure
pop eax ;Get RETURN address from Stack
pop ebx ;Get STRING address from Stack
push eax ;Put RETURN address back on Stack
While1: mov dl,[ebx] ;Contents of address pointed to by EBX
mov TempChar,dl ;Move the character to temporary store
cmp TempChar,0 ;While not end of the string
je StringEnd ; Jump to StringEnd on char = 0 (null)
lea esi,TempChar ;Address of character to print
call PutChar ;Go print a character
inc ebx ;Increment pointer to next character
jmp While1 ;Go to top of the loop
StringEnd:ret ;Return to calling procedure
MyPrintString ENDP ;Formal end of procedure
;********************** Procedure to Input the Number *************************
; Given : Nothing
; Process : Accept a string of ASCII digits and convert them to an integer
; Return : Return the integer in EAX register
;******************************************************************************
GetNumBin PROC NEAR32 ;Define a NEAR32 procedure
push ebx ;Save the contents of all registers
push ecx ; except for EAX, which will contain
push edx ; the integer number that was read
lea esi,TempString ;Pointer to temporary string
call GetString ; go get the string
lea esi,TempString ;Pointer to temporary string
lea edi,TempInt ;Pointer to integer storage
call Ascii2Bin ;Convert the string to integer
mov eax,TempInt ;Copy the integer to EAX
pop edx ;Restore the registers in reverse order
pop ecx ;
pop ebx ;
ret ;Return to Calling procedure
GetNumBin ENDP ;Formal end of procedure
;********************** Procedure to Input the Number *************************
; Given : Nothing
; Process : Accept a string of ASCII digits and convert them to an integer
; Return : Return the integer in EAX register
;******************************************************************************
GetNumDec PROC NEAR32 ;Define a NEAR32 procedure
push ebx ;Save the contents of all registers
push ecx ; except for EAX, which will contain
push edx ; the integer number that was read
lea esi,TempString ;Pointer to temporary string
call GetString ; go get the string
lea esi,TempString ;Pointer to temporary string
lea edi,TempInt ;Pointer to integer storage
call Ascii2Dec ;Convert the string to integer
mov eax,TempInt ;Copy the integer to EAX
pop edx ;Restore the registers in reverse order
pop ecx ;
pop ebx ;
ret ;Return to Calling procedure
GetNumDec ENDP ;Formal end of procedure
;********************** Procedure to Input the Number *************************
; Given : Nothing
; Process : Accept a string of ASCII digits and convert them to an integer
; Return : Return the integer in EAX register
;******************************************************************************
GetNumHex PROC NEAR32 ;Define a NEAR32 procedure
push ebx ;Save the contents of all registers
push ecx ; except for EAX, which will contain
push edx ; the integer number that was read
lea esi,TempString ;Pointer to temporary string
call GetString ; go get the string
lea esi,TempString ;Pointer to temporary string
lea edi,TempInt ;Pointer to integer storage
call Ascii2Hex ;Convert the string to integer
mov eax,TempInt ;Copy the integer to EAX
pop edx ;Restore the registers in reverse order
pop ecx ;
pop ebx ;
ret ;Return to Calling procedure
GetNumHex ENDP ;Formal end of procedure
;**************** Procedure to Convert ASCII to Integer ***********************
; Given : A pointer to the string to be Converted in the ESI register and a
; : pointer to the destination integer in EDI
; Process : Convert the string of ASCII digits to an integer and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Ascii2Bin PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
cld ;Set the direction flag for forward
mov ebx,0h ;Zero the EBX register
xor eax,eax ;Clear the EAX register
NextIn: lodsb ;Get a character from the string
cmp al,'0' ;If the character is less than 0, then
jb Done ; we have all the number and are Done
cmp al,'9' ;If the character is more than 9, then
ja Done ; we have all the number and are Done
and al,0Fh ;Mask out the high 4 bits, converting to Int
xor ah,ah ;Zero the high byte of AX
push eax ;Save the digit on the stack
mov eax,2d ;Place 10 decimal in AX to multiply by
mul ebx ;Multiply the number by 10
mov ebx,eax ;Get number from EAX and put in EBX
pop eax ;Get the digit back from the stack
add ebx,eax ;Add the digit to the number
jmp NextIn ;Get the next digit
Done: mov [edi],ebx ;Save NUMBER at address pointed to by EDI
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Ascii2Bin ENDP
;**************** Procedure to Convert Integer to ASCII ***********************
; Given : A pointer to the integer to be converted in the ESI register and a
; pointer to the output string in EDI
; Process : Convert the integer to a string of ASCII digits and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Bin2Ascii PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
cld ;Set the direction flag for forward
mov eax,[esi] ;copy the integer to eax
mov ecx,0h ;Zero the CX register for digit counter
mov ebx,2d ;Set up divisor of 10 decimal
NextOut:mov edx,0h ;Zero EDX reg for high order dword of div
div ebx ;Divide number in EAX by 10d
push edx ;Save remainder on the stack
inc ecx ;Count the digit
cmp eax,0h ;Is number in EAX greater than 0
ja NextOut ;Yes, get next digit
CharOut:pop eax ;Get number from the stack
or eax, 0030h ;Convert Int to Ascii by adding 30h
stosb ; and store in the destination string
dec ecx ;Reduce characters to print by one
jnz CharOut ;If CX > 0 loop to print next digit
mov al,0 ;Place a NULL in AL
stosb ; and null terminate the string
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Bin2Ascii ENDP
;**************** Procedure to Convert ASCII to Integer ***********************
; Given : A pointer to the string to be Converted in the ESI register and a
; : pointer to the destination integer in EDI
; Process : Convert the string of ASCII digits to an integer and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Ascii2Dec PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
cld ;Set the direction flag for forward
mov ebx,0h ;Zero the EBX register
xor eax,eax ;Clear the EAX register
NextIn: lodsb ;Get a character from the string
cmp al,'0' ;If the character is less than 0, then
jb Done ; we have all the number and are Done
cmp al,'9' ;If the character is more than 9, then
ja Done ; we have all the number and are Done
and al,0Fh ;Mask out the high 4 bits, converting to Int
xor ah,ah ;Zero the high byte of AX
push eax ;Save the digit on the stack
mov eax,10d ;Place 10 decimal in AX to multiply by
mul ebx ;Multiply the number by 10
mov ebx,eax ;Get number from EAX and put in EBX
pop eax ;Get the digit back from the stack
add ebx,eax ;Add the digit to the number
jmp NextIn ;Get the next digit
Done: mov [edi],ebx ;Save NUMBER at address pointed to by EDI
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Ascii2Dec ENDP
;**************** Procedure to Convert Integer to ASCII ***********************
; Given : A pointer to the integer to be converted in the ESI register and a
; pointer to the output string in EDI
; Process : Convert the integer to a string of ASCII digits and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Dec2Ascii PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
cld ;Set the direction flag for forward
mov eax,[esi] ;copy the integer to eax
mov ecx,0h ;Zero the CX register for digit counter
mov ebx,10d ;Set up divisor of 10 decimal
NextOut:mov edx,0h ;Zero EDX reg for high order dword of div
div ebx ;Divide number in EAX by 10d
push edx ;Save remainder on the stack
inc ecx ;Count the digit
cmp eax,0h ;Is number in EAX greater than 0
ja NextOut ;Yes, get next digit
CharOut:pop eax ;Get number from the stack
or eax, 0030h ;Convert Int to Ascii by adding 30h
stosb ; and store in the destination string
dec ecx ;Reduce characters to print by one
jnz CharOut ;If CX > 0 loop to print next digit
mov al,0 ;Place a NULL in AL
stosb ; and null terminate the string
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Dec2Ascii ENDP
;**************** Procedure to Convert ASCII to Integer ***********************
; Given : A pointer to the string to be Converted in the ESI register and a
; : pointer to the destination integer in EDI
; Process : Convert the string of ASCII digits to an integer and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Ascii2Hex PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
cld ;Set the direction flag for forward
mov ebx,0h ;Zero the EBX register
xor eax,eax ;Clear the EAX register
NextIn: lodsb ;Get a character from the string
cmp al,'0' ;If the character is less than 0, then
jb Done ; we have all the number and are Done
cmp al,'9' ;If the character is more than 9, then
ja Done ; we have all the number and are Done
and al,0Fh ;Mask out the high 4 bits, converting to Int
xor ah,ah ;Zero the high byte of AX
push eax ;Save the digit on the stack
mov eax,16d ;Place 10 decimal in AX to multiply by
mul ebx ;Multiply the number by 10
mov ebx,eax ;Get number from EAX and put in EBX
pop eax ;Get the digit back from the stack
add ebx,eax ;Add the digit to the number
jmp NextIn ;Get the next digit
Done: mov [edi],ebx ;Save NUMBER at address pointed to by EDI
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Ascii2Hex ENDP
;**************** Procedure to Convert Integer to ASCII ***********************
; Given : A pointer to the integer to be converted in the ESI register and a
; pointer to the output string in EDI
; Process : Convert the integer to a string of ASCII digits and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Hex2Ascii PROC NEAR32
pushad ;Save the contents of all registers
pushfd ;
cld ;Set the direction flag for forward
mov eax,[esi] ;copy the integer to eax
mov ecx,0h ;Zero the CX register for digit counter
mov ebx,16d ;Set up divisor of 10 decimal
NextOut:mov edx,0h ;Zero EDX reg for high order dword of div
div ebx ;Divide number in EAX by 10d
push edx ;Save remainder on the stack
inc ecx ;Count the digit
cmp eax,0h ;Is number in EAX greater than 0
ja NextOut ;Yes, get next digit
CharOut:pop eax ;Get number from the stack
or eax, 0030h ;Convert Int to Ascii by adding 30h
stosb ; and store in the destination string
dec ecx ;Reduce characters to print by one
jnz CharOut ;If CX > 0 loop to print next digit
mov al,0 ;Place a NULL in AL
stosb ; and null terminate the string
popfd ;Restore the registers
popad ;
ret ;Return to Calling procedure
Hex2Ascii ENDP
Public _main
END ;Code segment ends
Hi usafman,
Welcome to the Forum :thumbu
There is a "no homework" rule in place, but you have invested quite a bit, so I guess we can skip the reminder. I have adjusted the package slightly so that it assembles. links and runs.
Quote call GetNumDec ;Get user decimal number
; cmp GetNumDec, 4294967295 ;compare getnum to max input
cmp eax, 4294967295 ;compare getnum to max input
Check these parts in particular. GetNum*** return their values in eax, so that had to be corrected. But the comparison doesn't make sense, since 4294967295 is -1 or 0ffffffffh, the highest value a reg32 can assume. For testing, just comment out like this:
;jg TooLargeErrorHope this gets you started,
jj
Quotecmp eax, 4294967295 ;compare getnum to max input
In your case, such an instruction is totally useless. You are specifying that the input can be as large as can fit in 32 bits. It is thus absolutely impossible that the input returned from your functions as a 32-bit value could exceed the maximum allowed. Any input exceeding that maximum must be detected in the input conversion functions.
For the bin and hex inputs, you could simply check that the number of characters don't exceed the maximum before conversion. For the decimal input, you will have to insert a check in the Ascii2Dec conversion function.
Your three Ascii2xxx functions have all been more or less "copy-paste". Have another critical look at them. For instance, the input for a binary number should only have 0s and 1s (you are allowing all the other digits up to 9). The input for hex numbers can also contains the letters A-F (or even a-f); you are terminating the conversion whenever you encounter such characters.
I put that check in because I wanted to display an error whenever the user put in a number that was bigger than a 32-bit value; however, my professor hasn't gone over how to do such things yet so I wasn't exactly sure how to accomplish that. Thanks for the help; I greatly appreciate it.
what Ray is saying is, you can't make that check after-the-fact
you have to make those tests in the GetNumDec, GetNumBin, and GetNumHex routines, during entry
you can either allow the user to enter numbers that are too large and report an "overflow" condition
or, you can play with the keyboard stuff and prevent the user from doing so
Yes, it's akin to checking if the water level in a bucket exceeds the height of the bucket. You need to observe the water on the floor, not the column hanging over the confines of the bucket.
You might also want to look at why you need to push/pop the entire register set, and in other situations not preserving EBX,ESI,EDI.
I understand from a "military grade" perspective knowing which registers are altered by a procedure call is an important part of documenting it's behaviour, but pushing everything kind of abdicates analyzing what you're actually really using, or at least masks potential problems.
I have gone through my code and changed a lot of it. I now have all the conversions working! Now I just have to add in the error checking...
TITLE PROG2.asm ;File name of program
;
LF equ 0ah ;ASCII 10 - newline character
CR equ 0dh ;ASCII 13 - carriage return character
NEWLINE equ CR,LF ;Combine CR and LF for carriage return
DOUBLESPC equ NEWLINE,LF ;Combine NEWLINE and LF for double space
MAXSTR equ 256d ;Accept up to 256 character string
;
.586 ;Allow for Pentium instrucitons
.MODEL FLAT ;Memory model is FLAT (4GB)
INCLUDE io32.inc ;Include the 32 bit I/O procedures
INCLUDE debugger.inc ;Include the debugger procedures
.STACK 4096h ;4k hex bytes for stack
.DATA ;Data segment begins here
Intro BYTE NEWLINE,'This program allows users to enter a binary, ',\
'decimal, or hexadecimal number and converts that ',\
'number to the other two forms and then displays the ',\
'result.',NEWLINE,0
Menu BYTE DOUBLESPC,'1) Enter a Binary Number',\
NEWLINE,'2) Enter a Decimal Number',\
NEWLINE,'3) Enter a Hexadecimal Number',\
NEWLINE,'4) Quit',\
DOUBLESPC,'Enter your choice --> ',0
InvalidSelect BYTE DOUBLESPC,'Error: Invalid input.',0
TooLarge BYTE DOUBLESPC,'Error: Input too large. Try again please.',0
BPrompt BYTE DOUBLESPC,'Enter a binary (less than 33 digits) --> ',0
DPrompt BYTE DOUBLESPC,'Enter a decimal (less than 4294967295d) --> ',0
HPrompt BYTE DOUBLESPC,'Enter a hexadecimal (less than 0FFFFFFFFh) --> ',0
BinAns BYTE ' Binary = ',0
DecAns BYTE ' Decimal = ',0
HexAns BYTE ' Hexadecimal = ',0
NLine BYTE LF,0 ;For adding a blank line
CharTyped BYTE ? ;Holds menu selection
TempString BYTE MAXSTR dup (0) ;Holds user defined number string
TempInt DWORD 0h ;For holding temp values
BinValIn DWORD 0b ;For Bin value input
BinValOut DWORD 0b ;For Bin value output
DecValIn DWORD 0d ;For Dec value input
DecValOut DWORD 0d ;For Dec value output
HexValIn DWORD 0h ;For Hex value input
HexValOut DWORD 0h ;For Hex value output
;************************** Main Body of Program ******************************
; Given : Nothing
; Process: Main Body - calls procedures to do the processing
; Return : Nothing
;******************************************************************************
.CODE ;executable section begins here
_main: ;start of main
lea esi,Intro ;point to intro statement
call PrintString ; display the string
StartProg: lea esi,Menu ;point to menu statement
call PrintString ; display the string
lea esi,CharTyped ;point to storage for chartyped
call GetChar ;get the character
call MenuCompInput ;checks the user input & completes the
; selected conversions
jmp StartProg ;loop back to start of program
ExitProg: INVOKE ExitProcess,0 ;exit with return code 0
;**************** Procedure to Check the user selection ***********************
; Given : User selection
; Process : Prints the menu for the conversion program and obtains
; : input from user via keyboard
; Return : Nothing
;******************************************************************************
MenuCompInput PROC NEAR32 ;Formal start of procedure
cmp CharTyped,'1' ;Compare CharTyped with '1'
je Bin1 ;if even Jump to Bin
jb MenuError ;if below Jump to Err
cmp CharTyped,'2' ;Compare CharTyped with '2'
je Dec1 ;if even jump to Deci
cmp CharTyped,'3' ;Compare CharTyped with '3'
je Hex1 ;if even jump to Hexa
cmp CharTyped,'4' ;Compare CharTyped with '4'
je ExitProg ;if even jump to ByeBye
ja MenuError ;if above jump to menuerror
Bin1: call Binary ;call Convert_Binary_Input
ret ;Return to calling Procedure
Dec1: call Decimal ;call Convert_Decimal_Input
ret ;return to calling procedure
Hex1: call Hexadecimal ;call Convert_Hex_Input
ret ;Return to calling procedure
MenuError: ;
lea esi,InvalidSelect ;Point to Invalid_Input
call PrintString ;Print the String
Done: ret ;Return to calling Procedure
MenuCompInput ENDP ;Formal end to procedure
;********** Procedure to Convert Binary to Decimal & Hexadecimal **************
; Given : Menu option 1
; Process : Prompts user for binary number and calls 2 procedures to convert
; : from binary to decimal and hexadecimal
; Return : None
;******************************************************************************
Binary PROC NEAR32 ;Formal start of procedure
pushad ;save contents of registers
pushfd ;save contents of flags
Jump1: mov edx,30h ;copy zero into edx register
lea esi,BPrompt ;point to bprompt
call PrintString ;print the string
lea esi,TempString ;point to tempstring
call GetString ;get ascii version of the number
lea esi,TempString ;point to tempstring
lea edi,BinValIn ;point to binvalin
call Ascii2Bin ;convert ascii number to an integer
cmp edx,30h ;compare edx to zero
ja Error1 ; if above, jump to error1
lea esi,NLine ;point to nline string
call PrintString ; display the string
lea esi,BinAns ;point to binans output string
call PrintString ; display the string
lea esi,TempString ;point to user defined decimal number
call PrintString ; display the string
call ConvertB2D ;call convertb2d
call ConvertB2H ;call convertb2h
jmp Done1 ;jump to Done1
Error1: lea esi,TooLarge ;point to TooLarge
call PrintString ; display the string
mov edx,0h ;copy 0h into edx register
jmp Jump1 ;jump to jump1
Done1: popfd ;restore flags
popad ;restore registers
ret ;return to calling procedure
Binary ENDP ;Formal end to procedure
;***************** Procedure to Convert Binary to Decimal *********************
; Given : User defined binary number
; Process : converts the binary number to decimal and prints the string
; Return : None
;******************************************************************************
ConvertB2D PROC NEAR32 ;Formal start of procedure
lea esi,BinValIn ;Point to integer to convert
lea edi,TempString ;Point to storage
call Dec2Ascii ;convert the number
lea esi,DecAns ;point to decans output string
call PrintString ; display the string
lea esi,TempString ;point to new converted number
call PrintString ; display the string
ret ;return to calling procedure
ConvertB2D ENDP ;Formal end to procedure
;*************** Procedure to Convert Binary to Hexadecimal *******************
; Given : User defined binary number
; Process : Converts the binary number to hexadecimal and prints the string
; Return : None
;******************************************************************************
ConvertB2H PROC NEAR32 ;Formal start of procedure
lea esi,BinValIn ;Point to integer to convert
lea edi,TempString ;Point to storage
call Hex2Ascii ;convert the number
lea esi,HexAns ;point to hexans output string
call PrintString ; display the string
lea esi,TempString ;point to new converted number
call PrintString ; display the string
ret ;return to calling procedure
ConvertB2H ENDP ;Formal end to procedure
;********** Procedure to Convert Decimal to Binary & Hexadecimal **************
; Given : Menu option 2
; Process : Prompts user for decimal number and calls 2 procedures to convert
; : from decimal to binary and hexadecimal
; Return : None
;******************************************************************************
Decimal PROC NEAR32 ;Formal start of procedure
pushad ;save contents of registers
pushfd ;save contents of flags
Jump2: mov edx,30h ;copy zero into edx register
lea esi, DPrompt ;point to dprompt
call PrintString ;print the string
lea esi,TempString ;point to tempstring
call GetString ;get ascii version of the number
lea esi,TempString ;point to tempstring
lea edi,DecValIn ;point to DecValIn
call Ascii2Dec ;convert ascii number to an integer
cmp edx,30h ;compare edx to zero
ja Error2 ; if above, jump to error2
lea esi,NLine ;point to nline string
call PrintString ; display the string
lea esi,DecAns ;point to decans output string
call PrintString ; display the string
lea esi,TempString ;point to user defined decimal number
call PrintString ; display the string
call ConvertD2B ;call convertd2b
call ConvertD2H ;call convertd2h
jmp Done2 ;jump to Done
Error2: lea esi,TooLarge ;point to TooLarge
call PrintString ; display the string
mov edx,0h ;copy 0h into edx register
jmp Jump2 ;jump to jump1
Done2: popfd ;restore flags
popad ;restore registers
ret ;return to calling procedure
Decimal ENDP ;Formal end to procedure
;***************** Procedure to Convert Decimal to Binary *********************
; Given : User defined decimal number
; Process : Converts the decimal number to a binary number
; : and prints the string
; Return : None
;******************************************************************************
ConvertD2B PROC NEAR32 ;Formal start of procedure
lea esi,DecValIn ;point to integer to convert
lea edi,TempString ;point to string storage
call Bin2Ascii ;go convert the number
lea esi,BinAns ;point to binans output string
call PrintString ; display the string
lea esi,TempString ;point to new converted binary number
call printString ; display the string
ret ;Return to Calling Procedure
ConvertD2B ENDP ;Formal end to procedure
;*************** Procedure to Convert Decimal to Hexadecimal ******************
; Given : User defined decimal number
; Process : Converts the decimal number to a hexadecimal number
; : and prints the string
; Return : None
;******************************************************************************
ConvertD2H PROC NEAR32 ;Formal start of procedure
lea esi,DecValIn ;Point to integer to convert
lea edi,TempString ;Point to storage
call Hex2Ascii ;convert the number
lea esi,HexAns ;point to hexans output string
call PrintString ; display the string
lea esi,TempString ;point to new converted number
call PrintString ; display the string
ret ;return to calling procedure
ConvertD2H ENDP ;Formal end to procedure
;********** Procedure to Convert Hexadecimal to Binary & Decimal **************
; Given : Menu option 3
; Process : Prompts user for hexadecimal number and calls 2 procedures to
; : convert from hexadecimal to binary and decimal
; Return : None
;******************************************************************************
Hexadecimal PROC NEAR32 ;Formal start of procedure
pushad ;save contents of registers
pushfd ;save contents of flags
Jump3: mov edx,30h ;copy zero into edx register
lea esi, HPrompt ;point to hprompt
call PrintString ;print the string
lea esi,TempString ;point to tempstring
call GetString ;get ascii version of the number
lea esi,TempString ;point to tempstring
lea edi,HexValIn ;point to hexvalin
call Ascii2Hex ;convert ascii number to an integer
cmp edx,30h ;compare edx to zero
ja Error3 ; if above, jump to error3
lea esi,NLine ;point to new line string
call PrintString ; display the string
lea esi,HexAns ;point to hexans output string
call PrintString ; display the string
lea esi,TempString ;point to user defined decimal number
call PrintString ; display the string
call ConvertH2B ;call converth2b
call ConvertH2D ;call converth2d
jmp Done3 ;jump to Done
Error3: lea esi,TooLarge ;point to TooLarge
call PrintString ; display the string
mov edx,0h ;copy 0h into edx register
jmp Jump3 ;jump to jump1
Done3: popfd ;restore flags
popad ;restore registers
ret ;return to calling procedure
Hexadecimal ENDP ;Formal end to procedure
;*************** Procedure to Convert Hexadecimal to Binary *******************
; Given : User defined hexadecimal number
; Process : Converts the hexadecimal number to binary
; : and prints the string
; Return : None
;******************************************************************************
ConvertH2B PROC NEAR32 ;Formal start of procedure
lea esi,HexValIn ;Point to integer to convert
lea edi,TempString ;Point to storage
call Bin2Ascii ;convert the number
lea esi,BinAns ;point to binans output string
call PrintString ; display the string
lea esi,TempString ;point to new converted number
call PrintString ; display the string
ret ;return to calling procedure
ConvertH2B ENDP ;Formal end to procedure
;*************** Procedure to Convert Hexadecimal to Decimal ******************
; Given : User defined hexadecimal number
; Process : Converts the hexadecimal number to decimal
; : and prints the string
; Return : None
;******************************************************************************
ConvertH2D PROC NEAR32 ;Formal start of procedure
lea esi,HexValIn ;Point to integer to convert
lea edi,TempString ;Point to storage
call Dec2Ascii ;convert the number
lea esi,DecAns ;point to decans output string
call PrintString ; display the string
lea esi,TempString ;point to new converted number
call PrintString ; display the string
ret ;return to calling procedure
ConvertH2D ENDP ;Formal end to procedure
;**************** Procedure to Convert ASCII to Integer ***********************
; Given : A pointer to the string to be Converted in the ESI register and a
; : pointer to the destination integer in EDI
; Process : Convert the string of ASCII digits to an integer and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Ascii2Bin PROC NEAR32 ;Formal start of procedure
pushad ;Save the contents of all registers
pushfd ;Save the contents of the flag register
cld ;Set the direction flag for forward
mov ebx,0h ;Zero the EBX register
xor eax,eax ;Clear the EAX register
NextIn: lodsb ;Get a character from the string
cmp al,'0' ;If the character is less than 0, then
jb Done ; if below, jump to done
cmp al,'1' ;If the character is more than 1, then
ja Done ; if above, jump to done
and al,0Fh ;Mask out the high 4 bits, convert to Int
xor ah,ah ;Zero the high byte of AX
push eax ;Save the digit on the stack
mov eax,2d ;Place 2 decimal in AX to multiply by
mul ebx ;Multiply the number by 10
mov ebx,eax ;Get number from EAX and put in EBX
pop eax ;Get the digit back from the stack
add ebx,eax ;Add the digit to the number
jmp NextIn ;Get the next digit
Done: mov [edi],ebx ;Save NUMBER at address pointed to by EDI
popfd ;Restore the registers
popad ;Restore the register
ret ;Return to Calling procedure
Ascii2Bin ENDP ;Formal end to procedure
;**************** Procedure to Convert Binary to ASCII ************************
; Given : A pointer to the integer to be converted in the ESI register and a
; pointer to the output string in EDI
; Process : Convert the integer to a string of ASCII digits and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Bin2Ascii PROC NEAR32 ;Formal start of procedure
pushad ;Save the contents of all registers
pushfd ;Save the contents of the flag register
cld ;Set the direction flag for forward
mov eax,[esi] ;copy the integer to eax
mov ecx,0h ;Zero the CX register for digit counter
mov ebx,2d ;Set up divisor of 2 decimal
NextOut:mov edx,0h ;Zero EDX reg for high order dword of div
div ebx ;Divide number in EAX by 2d
push edx ;Save remainder on the stack
inc ecx ;Count the digit
cmp eax,0h ;Is number in EAX greater than 0
ja NextOut ;Yes, get next digit
CharOut:pop eax ;Get number from the stack
or eax, 0030h ;Convert Int to Ascii by adding 30h
stosb ; and store in the destination string
dec ecx ;Reduce characters to print by one
jnz CharOut ;If CX > 0 loop to print next digit
mov al,0 ;Place a NULL in AL
stosb ; and null terminate the string
popfd ;Restore the registers
popad ;Restore the register
ret ;Return to Calling procedure
Bin2Ascii ENDP ;Formal end to procedure
;**************** Procedure to Convert Integer to ASCII ***********************
; Given : A pointer to the integer to be converted in the ESI register and a
; pointer to the output string in EDI
; Process : Convert the integer to a string of ASCII digits and stores the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Dec2Ascii PROC NEAR32 ;Formal start of procedure
pushad ;Save the contents of all registers
pushfd ;Save the content of flag register
cld ;Set the direction flag for forward
mov eax,[esi] ;copy the integer to eax
mov ecx,0h ;Zero the CX register for digit counter
mov ebx,10d ;Set up divisor of 10 decimal
NextOut:mov edx,0h ;Zero EDX reg for high order dword of div
div ebx ;Divide number in EAX by 10d
push edx ;Save remainder on the stack
inc ecx ;Count the digit
cmp eax,0h ;Is number in EAX greater than 0
ja NextOut ;Yes, get next digit
CharOut:pop eax ;Get number from the stack
or eax, 0030h ;Convert Int to Ascii by adding 30h
stosb ; and store in the destination string
dec ecx ;Reduce characters to print by one
jnz CharOut ;If CX > 0 loop to print next digit
mov al,0 ;Place a NULL in AL
stosb ; and null terminate the string
popfd ;Restore the registers
popad ;Restore the register
ret ;Return to Calling procedure
Dec2Ascii ENDP ;Formal end to procedure
;**************** Procedure to Convert ASCII to Decimal ***********************
; Given : A pointer to the string to be Converted in the ESI register and a
; : pointer to the destination integer in EDI
; Process : Convert the string of ASCII digits to an integer and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Ascii2Dec PROC NEAR32 ;Formal start of procedure
pushad ;Save the contents of all registers
pushfd ;Save the contents of flag register
cld ;Set the direction flag for forward
mov ebx,0h ;Zero the EBX register
xor eax,eax ;Clear the EAX register
NextIn: lodsb ;Get a character from the string
cmp al,'0' ;If the character is less than 0, then
jb Done ; if below, jump to done
cmp al,'9' ;If the character is more than 9, then
ja Done ; if above, jump to done
and al,0Fh ;Mask out the high 4 bits, converting to Int
xor ah,ah ;Zero the high byte of AX
push eax ;Save the digit on the stack
mov eax,10d ;Place 10 decimal in AX to multiply by
mul ebx ;Multiply the number by 10
mov ebx,eax ;Get number from EAX and put in EBX
pop eax ;Get the digit back from the stack
add ebx,eax ;Add the digit to the number
jmp NextIn ;Get the next digit
Done: mov [edi],ebx ;Save NUMBER at address pointed to by EDI
popfd ;Restore the registers
popad ;Restore the register
ret ;Return to Calling procedure
Ascii2Dec ENDP ;Formal end to procedure
;**************** Procedure to Convert ASCII to Hex ***************************
; Given : A pointer to the string to be Converted in the ESI register and a
; : pointer to the destination integer in EDI
; Process : Convert the string of ASCII digits to an integer and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Ascii2Hex PROC NEAR32 ;Formal start of procedure
pushad ;Save the contents of all registers
pushfd ;Save the contents of flag register
cld ;Set the direction flag for forward
mov ebx,0h ;Zero the EBX register
xor eax,eax ;Clear the EAX register
NextIn: lodsb ;Get a character from the string
cmp al,'0' ;If the character is less than 0, then
jb Done ; we have all the number and are Done
cmp al,'9' ;If the character is more than 9, then
jbe Convert1 ; we have all the number and are Done
cmp al,'A' ;compare al register to A
jb Done ; if below, jump to done
cmp al,'F' ;compare al register to F
jbe Convert2 ; if below/equal, jump to convert2
jmp Done ;jump to done
Upper: cmp al,'a' ;compare al register to a
jb Done ; if below, jump to done
cmp al,'f' ;compare al register to f
jbe Convert3 ; if below/equal to convert3
ja Done ;jump to done
Convert3: ;
sub al,20h ;sub 20h to convert to uppercase
Convert2: ;
sub al,7d ;subtract 7 from al
Convert1: ;
and al,0Fh ;Mask out the high 4 bits, converting to Int
xor ah,ah ;Zero the high byte of AX
push eax ;Save the digit on the stack
mov eax,16d ;Place 16 decimal in AX to multiply by
mul ebx ;Multiply the number by 16
mov ebx,eax ;Get number from EAX and put in EBX
pop eax ;Get the digit back from the stack
add ebx,eax ;Add the digit to the number
jmp NextIn ;Get the next digit
Done: mov [edi],ebx ;Save NUMBER at address pointed to by EDI
popfd ;Restore the registers
popad ;Restore the register
ret ;Return to Calling procedure
Ascii2Hex ENDP ;Formal end to procedure
;**************** Procedure to Convert Hex to ASCII ***************************
; Given : A pointer to the integer to be converted in the ESI register and a
; pointer to the output string in EDI
; Process : Convert the integer to a string of ASCII digits and store the
; : string in the address pointed to by EDI. No registers are changed
; : and the flags are not affected.
; Return : Nothing
;******************************************************************************
Hex2Ascii PROC NEAR32 ;Formal start of procedure
pushad ;Save the contents of all registers
pushfd ;Save the contents of flag register
cld ;Set the direction flag for forward
mov eax,[esi] ;copy the integer to eax
mov ecx,0h ;Zero the ECX register for digit counter
mov ebx,16d ;Set up divisor of 16 decimal
NextOut:mov edx,0h ;Zero EDX reg for high order dword of div
div ebx ;Divide number in EAX by 16d
push edx ;Save remainder on the stack
inc ecx ;Count the digit
cmp eax,0h ;Is number in EAX greater than 0
ja NextOut ;Yes, get next digit
CharOut:pop eax ;Get number from the stack
or eax, 0030h ;Convert Int to Ascii by oring with 30h
cmp eax,39h ;compare eax to 9
jbe SaveNum ; if below/equal, store it
add eax, 07h ; otherwise add 7
SaveNum:stosb ; and store in the destination string
dec ecx ;Reduce characters to print by one
jnz CharOut ;If CX > 0 loop to print next digit
mov al,0 ;Place a NULL in AL
stosb ; and null terminate the string
popfd ;Restore the registers
popad ;Restore the register
ret ;Return to Calling procedure
Hex2Ascii ENDP ;Formal end to procedure
Public _main ;
END ;Code segment ends
:U
If I wanted to make a check to see if the carry flag has been set, i would use jc. If I wanted to reset the carry flag to zero; however, what register would I have to reset?
CLC = clear carry
STC = set carry
CMC = compliment carry (invert)
Hi,
As well as the instructions that Dave mention that directly
affect the carry flag, you can use many other instructions to
reset the carry flag to zero. The Boolean logic ones (AND,
OR, and the like) set the carry flag to zero. And you can use
a contrived arithmatic instruction to set or reset carry as well.
Nit. it's complement in CMC, not an attempt at flattery.
Cheers,
Steve N.
that is true, however, it may not be worth the effort - lol
there are times when you were going to perform an operation, anyways
in those cases, it is reasonable to note the state of carry
for example, if we come to a spot in the code where we want to insure the carry flag is cleared
near the same spot, we want to zero out a register
xor eax,eax
EAX becomes 0, but also, the carry flag is cleared
the same is true for
sub eax,eax
however, it is worth noting that most logical operations always clear the carry flag
while most math operations clear or set the flag according to the operation
by "logical", i mean OR, AND, XOR
by "math", i mean ADD, SUB, ADC, SBB
the NEG (math) and NOT (logical) instructions have special behaviour with regard to the flags