BCD to HEX in assembly

Discussion in 'Programmer's Corner' started by Jefecito20, May 4, 2010.

  1. Jefecito20

    Thread Starter New Member

    Apr 26, 2010
    6
    0
    I'm not sure this is the correct forum for this, but since I'm not a member of any other technical forums I thought I'd give it a shot anyway.

    I'm writing a program to convert 2-digit BCD number to HEX number is assembly (using Turbo Assembler/TASM). So far this is the code I've written, but it's giving wrong outputs. Can anyone find what is wrong with it?

    Code ( (Unknown Language)):
    1. .model small
    2. .stack 100
    3.  
    4. .data
    5. msg1 db 10,13,"Enter the 2 digit BCD number: $"
    6. msg2 db 10,13,"The equivalent HEX number is: $"
    7. no db ?
    8.  
    9. .code
    10.         main proc
    11.         mov ax,@data
    12.         mov ds,ax
    13.  
    14.         lea dx,msg1
    15.         mov ah,9
    16.         int 21h
    17.  
    18.         mov ah,1
    19.         int 21h
    20.         sub al,30h
    21.         sub dl,10
    22.         mul dl
    23.         mov no,al
    24.         mov ah,1
    25.         int 21h
    26.         cmp al,0dh
    27.         je exit
    28.  
    29.         sub al,30h
    30.         add no,al
    31.  
    32.         lea dx,msg2
    33.         mov al,9
    34.         int 21h
    35.  
    36.         mov al,no
    37.         and al,0f0h
    38.         mov cl,4
    39.         shr al,cl
    40.         mov dl,al
    41.         cmp dl,9
    42.         jg alpha1
    43.         add dl,30h
    44.         jmp next
    45.  
    46. alpha1: add dl,37h
    47.  
    48. next:   mov ah,2
    49.         int 21h
    50.  
    51.         mov al,no
    52.         and al,0fh
    53.         mov dl,al
    54.         cmp dl,9
    55.         jg alpha2
    56.         add dl,30h
    57.         jmp next2
    58.  
    59. alpha2: add dl,37h
    60.  
    61. next2:  mov ah,2
    62.         int 21h
    63.         jmp exit1
    64.  
    65. exit:   lea dx,msg2
    66.         mov ah,9
    67.         int 21h
    68.  
    69.         mov al,no
    70.         mov cl,10
    71.         mov ah,0
    72.         div cl
    73.         mov dl,al
    74.         add dl,30h
    75.         mov ah,2
    76.         int 21h
    77.  
    78. exit1:  mov ah,4ch
    79.         int 21h
    80.         main endp
    81.         end main
     
  2. 311499

    New Member

    Apr 29, 2010
    5
    0
    The only bugs I could find were:
    "sub dl,10" (should be MOV DL, 10)
    "mov al,9" (should be MOV AH, 9)
    Code ( (Unknown Language)):
    1. .model small
    2. .stack 100    ;did you mean 100h?
    3.  
    4. .data
    5. msg1 db 10,13,"Enter the 2 digit BCD number: $"
    6. msg2 db 10,13,"The equivalent HEX number is: $"
    7. no db ?
    8.  
    9. .code
    10.         main proc
    11.         mov ax,@data
    12.         mov ds,ax
    13.  
    14.         lea dx,msg1
    15.         mov ah,9
    16.         int 21h
    17.  
    18.         mov ah,1
    19.         int 21h
    20.         sub al,30h    ;you can also use "AND AL, 0FH"
    21.         MOV DL, 10    ;not "sub dl,10"
    22.         mul dl
    23.         mov no,al
    24.         mov ah,1
    25.         int 21h
    26.         cmp al,0dh
    27.         je exit
    28.  
    29.         sub al,30h    ;you can also use "AND AL, 0FH"
    30.         add no,al
    31.  
    32.         lea dx,msg2
    33.         MOV AH, 9    ;not "mov al,9"
    34.         int 21h
    35.  
    36.         mov al,no    ;you can move the variable directly into DL also
    37. ;        and al,0f0h    ;not required as the SHR below deletes bits 3..0
    38.         mov cl,4
    39.         shr al,cl
    40.         mov dl,al
    41.         cmp dl,9
    42.         jg alpha1    ;instead of "jg" you can use JA (preferred for unsigned numbers)
    43.         add dl,30h    ;you can also use "OR DL, 30H" (I don't know if it's any faster
    44.     ;though)
    45.         jmp next
    46.  
    47. alpha1: add dl,37h
    48.  
    49. next:   mov ah,2
    50.         int 21h
    51.  
    52.         mov al,no    ;you can move the variable directly into DL also
    53.         and al,0fh
    54.         mov dl,al
    55.         cmp dl,9
    56.         jg alpha2    ;JA preferred for unsigned numbers (by me at least)
    57.         add dl,30h
    58.         jmp next2
    59.  
    60. alpha2: add dl,37h
    61.  
    62. next2:  mov ah,2
    63.         int 21h
    64.         jmp exit1
    65.  
    66. exit:   lea dx,msg2
    67.         mov ah,9
    68.         int 21h
    69.  
    70.         mov al,no
    71.         mov cl,10
    72.         mov ah,0    ;"XOR AH, AH" is also possible and useful with words/dwords as it
    73.     ;makes the instruction shorter, e.g., "XOR BX, BX" instead of "MOV BX, 0".
    74.     ;Additionally, you can use CBW here (a one-byte instruction) as bit 7 is clear in AL
    75.     ;(CBW stands for "convert byte to word". It reads AL and sets AH to either 0 or 0FFH,
    76.     ;depending on the setting of bit 7 in AL. CBW is for signed numbers primarily but it
    77.     ;can replace an "XOR AH, AH" or a "MOV AH, 0FFH", provided you know how bit 7 is set
    78.     ;in AL).
    79.         div cl
    80.         mov dl,al    ;you can use "XCHG DX, AX" to make the ins one byte shorter
    81.         add dl,30h    ;"OR DL, 30H" can also be used (somehow I think it's faster)
    82.         mov ah,2
    83.         int 21h
    84.  
    85. exit1:  mov ah,4ch
    86.         int 21h
    87.         main endp
    88.         end main
    89. ;"JMP SHORT" can be used in many cases to replace a "jmp" (one byte shorter)
    This is my tested rewrite of the program:
    Code ( (Unknown Language)):
    1. .MODEL SMALL
    2. .STACK 00100H
    3.  
    4. .DATA
    5.  
    6. MSG1 DB 00DH, 00AH, "Enter the 2 digit BCD number: $"
    7. MSG2 DB 00DH, 00AH, "The equivalent HEX number is: $"
    8.  
    9. NR DB 10
    10.  
    11. .CODE
    12.  
    13.     MAIN PROC
    14. MOV AX, @DATA
    15. MOV DS, AX
    16. LEA DX, [MSG1]
    17. MOV AH, 009H
    18. INT 021H
    19. MOV AH, 001H
    20. INT 021H
    21. AND AL, 00FH
    22. MUL BYTE PTR [NR]
    23. MOV [NR], AL
    24. MOV AH, 001H
    25. INT 021H
    26. CMP AL, 00DH
    27. JE EXIT
    28. AND AL, 00FH
    29. ADD [NR], AL
    30. LEA DX, [MSG2]
    31. MOV AH, 009H
    32. INT 021H
    33. MOV DL, [NR]
    34. PUSH DX
    35. MOV CL, 004H
    36. SHR DL, CL
    37. OR DL, 030H
    38. MOV AH, 002H
    39. INT 021H
    40. POP DX
    41. AND DL, 00FH
    42. OR DL, 030H
    43. CMP DL, 03AH
    44. JB NEXT
    45. ADD DL, 007H
    46.     NEXT:
    47. MOV AH, 002H
    48. INT 021H
    49. JMP SHORT EXIT1
    50.     EXIT:
    51. LEA DX, [MSG2]
    52. MOV AH, 009H
    53. INT 021H
    54. MOV AL, [NR]
    55. CBW
    56. MOV CL, 10
    57. DIV CL
    58. XCHG DX, AX
    59. OR DL, 030H
    60. MOV AH, 002H
    61. INT 021H
    62.     EXIT1:
    63. MOV AH, 04CH
    64. INT 021H
    65. MAIN ENDP
    66.  
    67. END MAIN
    68.  
    A useful way for printing hex digits is one that uses the XLAT instruction:
    Code ( (Unknown Language)):
    1.  
    2.     WRHEX24:    ;WRITE 24 BIT NUMBER IN DL:AX
    3. PUSH AX
    4. MOV AL, DL
    5. CALL WRHEXB
    6. POP AX
    7.     WRHEXW:    ;WRITE 16 BIT NUMBER IN AX
    8. PUSH AX
    9. MOV AL, AH
    10. CALL WRHEXB
    11. POP AX
    12.     WRHEXB:    ;WRITE 8 BIT NUMBER IN AL
    13. PUSH AX
    14. SHR AL, 004H
    15. CALL WRHEXN
    16. POP AX
    17.     WRHEXN:    ;WRITE 4 BIT NUMBER IN LOW BITS OF AL
    18. PUSH AX
    19. PUSH BX
    20. MOV BX, OFFSET HEXCH
    21. AND AL, 00FH
    22. SEGCS XLAT
    23. CALL PRINTCH
    24. POP BX
    25. POP AX
    26. RET
    27.  
    28.     PRINTCH:    ;PRINT CHARACTER IN AL
    29. PUSH AX
    30. PUSH DX
    31. MOV DL, AL
    32. MOV AH, 002H
    33. INT 021H
    34. POP DX
    35. POP AX
    36. RET
    37.  
    38. HEXCH DB "0123456789ABCDEF"
    The above is a fragment of a protected mode program I wrote, with
    the procedure PRINTCH adapted for DOS (using INT 21H).

    Have fun!
     
Loading...