1

I am making a program in assembly language to convert Decimal number (from user) into Hexa. I am almost completed it but i am facing a issue. Basically issue is that I am taking a input(Decimal) and than convert it into Hexa and printing it but my output replace the input value and showing me output in the same line. I need help to solve this issue. I also attached my code below.

.model small
.stack 100h
.data
Menu db 10, 13, 'Enter a choice (1 or 2):'
     db 10, 13, '1) Convert 1 to 5 Decimal values to Hex'
     db 10, 13, '2) Quit Program', 10, 13, '$'

MenuInputError db 10, 13, 'Choice must be a 1, 2, or 3!'
               db 10, 13, 'Try again!', 10, 13, '$'

Decimal db 10, 13, 'Enter a number with 1 to 5 digits: ', 10, 13, '$'

.code
    Main proc
    mov ax,@data
    mov ds,ax
    
    DisplayMenu:
    mov dx,OFFSET Menu
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    
    CMP al,'1'
    JL DisplayError
    
    CMP al, '3'
    JG DisplayError
    
    CMP al,'1'
    JE Dec2Hex
    
    CMP al,'2'
    JE Quit
    
    DisplayError:
    mov dx, OFFSET MenuInputError
    mov ah,9
    int 21h
    JMP DisplayMenu
    
    Dec2Hex:
    CALL DEC2HEXA
    JMP DisplayMenu
    
    Quit:
    mov ah,4CH
    int 21h
    
    Main endp
    
DEC2HEXA proc
    mov dx,OFFSET Decimal
    mov ah,09h
    int 21h
    mov ax,0
    PUSH ax
    
    Again:
    mov ah,1
    int 21h
    
    CMP al,13 ; If Return is entered, start division.
    JE StartDivision
    
    CMP al,'0'
    JL Again
    
    CMP al,'9'
    JG Again
    
    mov ah,0
    SUB al,30h  ;30h = 48
    mov cx,ax
    POP ax
    
    mov bx,10
    MUL bx
    
    ADD ax,cx
    PUSH ax
    JMP Again
    
    StartDivision:
    mov cx,0
    mov bx,16
    POP ax
    
    Div1:
    div bx 
    PUSH dx 
    ADD cx,1 
    mov dx,0 
    CMP ax,0 
    JNE Div1
    
    HEXA:
    mov dx,0
    POP dx
    ADD dl,30h
    
    CMP dl,39h
    JG MoreHexa
    
    DisplayHexa:
    mov ah,2
    int 21h
    LOOP Hexa
    JMP Skip
    
    MoreHexa:
    ADD dl, 7h
    JMP DisplayHexa
    
    Skip:
    ret
    
    DEC2HEXA endp

End Main

input:
When I input:

Screen after Input:
After Input, How it shows result

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606

1 Answers1

2
mov ah,1
int 21h
CMP al,13 ; If Return is entered, start division.
JE StartDivision

The Enter that finishes the input loop, brings the cursor to the start of the current line, where the inputted decimal number starts. Next your code immediately converts and displays the hexadecimal characters. This will overwrite the inputted decimal number. The first three characters in "2414" are overwritten by the three characters in "96E", leaving the fourth character "4" as it was.

Just print an additional linefeed as soon as the input loop stops:

StartDivision:
  mov dl, 10   ; Linefeed
  mov ah, 02h  ; DOS.PrintCharacter
  int 21h
  ...
Sep Roland
  • 20,265
  • 3
  • 36
  • 58
  • 1
    Is it normal that the user pressing "enter" doesn't go to the next line? Does echo of input not happen until you read the character, and this program stops reading after the CR, without waiting to see an LF? – Peter Cordes Jan 16 '21 at 16:09
  • 2
    @PeterCordes A linefeed code (10) will never arrive, (unless we press CTRL-ENTER). Pressing ENTER, only generates the code 13 that is echoed, but that is not enough for a full newline (13 and 10). – Sep Roland Jan 16 '21 at 16:15
  • Weird. So the DOS equivalent of `cat > foo.txt` would end up with the user's typed characters all overwriting the same line, I guess, and not put valid newlines into the file. (`type > foo.txt` or something?) That sucks more than I would have guessed. (Unless the program reading its standard input manually fixes line endings). Such a mess, glad I never had much to do with DOS. – Peter Cordes Jan 16 '21 at 16:20
  • @PeterCordes I think we should give DOS some credit here. DOS is smarter than its own functions. Output redirection from the command prompt will correctly send both 13 and 10 to the file. What function 01h does is staying very close to the ASCII code of the key that was pressed, not adding too much additional meaning or interpretation. – Sep Roland Jan 16 '21 at 16:26
  • Your solution help me alot I added the lines you mention above but it need one more line that clears dl ``` StartDivision: mov dl,10 mov ah,2 int 21h mov dl,0 ``` This the solution that was needed Thank you @SepRoland – Safin Mahesania Jan 16 '21 at 16:31
  • You mean the DOS `type` command does that correction? I should have said a naively-written `cat` that just copies input to output one character at a time, not the actual `type` command. It still seems weird that text you type into standard input of something will be different from what that program would read from a file. Somewhat goes against the purpose of having an AH=1 read-stdin system call. Anyway, I guess if DOS had chosen something else (like one keypress -> 2 characters), that would be something else to complain about. It all stems from CR-LF line endings being clunky for text. – Peter Cordes Jan 16 '21 at 16:35
  • @SafinMahesania I understand you mean clearing `DX` before the division, and that before you were relying on the fact that `DX` was already clear because of the multiplication in the forelying code. Nice work! – Sep Roland Jan 16 '21 at 16:37
  • @SafinMahesania: You already have a `mov dx,0` in your source; you should just put it *before* `div` instead of after. (Or use `xor dx,dx` to make it more efficient). The only limitation is that your current code could handle DX:AX being slightly greater than 16-bit from the last mul, without overflowing the divide. – Peter Cordes Jan 16 '21 at 16:37
  • @SafinMahesania: but actually you don't need `div` at all: 16 is a power of 2, so it's much more efficient to just right-shift and AND. (Or rotate the top 4 bits to the bottom). [How to convert a binary integer number to a hex string?](https://stackoverflow.com/q/53823756) or [Printing hex values in x86 assembly](https://stackoverflow.com/q/18879672) (DOS). Never use `div` for a constant power of 2 divisor. – Peter Cordes Jan 16 '21 at 16:40