News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Need Help with Assembly Program

Started by usafman2006, October 11, 2011, 04:24:03 PM

Previous topic - Next topic

usafman2006

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

jj2007

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 TooLargeError

Hope this gets you started,
jj

raymond

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.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

usafman2006

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.

dedndave

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

clive

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.
It could be a random act of randomness. Those happen a lot as well.

usafman2006

#6
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


usafman2006

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?

dedndave

CLC = clear carry
STC = set carry
CMC = compliment carry (invert)

FORTRANS

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.

dedndave

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