Arnon Ahmed
Arnon Ahmed

Reputation: 11

Convert Octal to Hex in assembly language using emu8086

I am new at assembly. My task was to convert Octal to Hex and vice versa. I was only able to code Octal to Binary and then Binary to Hex in two different asm files. Now I really want to merge them together so that I can have Octal to Hex conversion.
Here are both codes:

Octal to Binary

.MODEL SMALL

.DATA

    INP DB 0
    MSG_1 DB "ENTER AN OCTAL NUMBER: $"
    MSG_2 DB "BINARY VALUE OF THIS NUMBER: $"
.CODE

MAIN PROC

    MOV AX,@DATA
    MOV DS,AX
    
    LEA DX,MSG_1
    MOV AH,9
    INT 21H
    
    MOV SI,0
    MOV AH,1
    MOV CX,0
    INPUT: INT 21H
           MOV INP[SI],AL
           INC CX
           INC SI
           CMP AL,13
           JNE INPUT
           
    CALL NEWLINE
    CALL NEWLINE
            
    LEA DX,MSG_2
    MOV AH,9
    INT 21H 

    MOV DI,0 
    MOV AH,2
    DEC CX   
    
    OUTPUT: MOV BL,INP[DI]
            CALL CONVERTOCT
            INC DI
            LOOP OUTPUT
    
    MOV AH,4CH
    INT 21H

ENDP

NEWLINE PROC

    MOV AH,2
    MOV DL,10
    INT 21H
    MOV DL,13
    INT 21H
    RET

NEWLINE ENDP 

CONVERTOCT PROC 
    
    SUB BL,48
    SHL BL,5 
    
    MOV DH,0
    CONV:
    SHL BL,1
    JC PRINT1
    JMP PRINT0
    
    PRINT0:
    MOV DL,'0'
    INT 21H
    INC DH
    CMP DH,3
    JE EXIT 
    JMP CONV
    
    PRINT1: 
    MOV DL,'1'
    INT 21H
    INC DH
    CMP DH,3
    JE EXIT 
    JMP CONV
    
    EXIT:
    RET
    
     
    
    
CONVERTOCT ENDP

END

Binary to Hex

.MODEL SMALL

.STACK 100H

.DATA 

    MSG_1 DB "ENTER BINARY NUMBER: $"
    MSG_2 DB "HEXADECIMAL OF THE NUMBER: $"
    MSG_3 DB "INVALID!  $"

.CODE

MAIN PROC 

    MOV AX,@DATA
    MOV DS,AX
    
    MOV AH,2
    MOV DL,0DH
    INT 21H
    MOV DL,0AH
    INT 21H
    
    MOV AH,9
    LEA DX,MSG_1
    INT 21H
    
    XOR BH,BH

    
INPUT: 

       MOV AH,1
       INT 21H
    
       MOV CH,AL
       CMP CH,0DH
       JE PRINT
    
       CMP CH,'0'
       JL EXIT 
    
       CMP CH,'1'
       JG EXIT
    
       AND CH,15
       SHL BH,1
       OR BH,CH
    
       JMP INPUT    

PRINT:
    
    MOV AH,2
    MOV DL,0DH
    INT 21H
    MOV DL,0AH
    INT 21H
    
    MOV AH,9
    LEA DX,MSG_2
    INT 21H
    
    MOV AH,2
    CMP BH,9
    JLE NUMBER 
    
    CMP BH,15
    JLE CHARACTER
    
NUMBER:
   
    ADD BH,48
    MOV AH,2
    MOV DL,BH
    INT 21H
    
    MOV AH,4CH
    INT 21H
    

CHARACTER:

    ADD BH,55
    MOV AH,2
    MOV DL,BH
    INT 21H
    
    MOV AH,4CH
    INT 21H
     

EXIT:

    MOV AH,2
    MOV DL,0DH
    INT 21H
    MOV DL,0AH
    INT 21H
    
    MOV AH,9
    LEA DX,MSG_3
    INT 21H
    
    MOV AH,4CH
    INT 21H
    MAIN ENDP

END MAIN

Upvotes: 1

Views: 1240

Answers (1)

Sep Roland
Sep Roland

Reputation: 39436

.DATA
    INP DB 0

You might want to correct this error first. Your INP input buffer only has room for a single byte! The correct way to write this is INP db 6 dup (0), for 5 octal digits and the carriage return.

Conversion from Octal to Hex

First pick an available register to act as an accumulator for the octal digits you will input. Choosing the BP register allows processing up to 5 octal digits.
Then modify the CONVERTOCT proc in the first program to no longer print the binary digits, but rather collect them in this accumulator.

CONVERTOCT PROC
    push cx
    mov  cx, 3      ; 8086 didn't have rotate by immediate, and so should emu8086!
    ror  bl, cl     ; Brings the 3 bits of intrest to the top
  CONV:
    shl  bl, 1      ; Out at the top
    rcl  BP, 1      ; In at the bottom
    loop CONV       ; 3 iterations, LOOP is fine on 8086/8088
    pop  cx
    ret
CONVERTOCT ENDP

Your second program (that says it can print Hex), expects its input in BH. Either modify that code so it can use the value from the BP register, or lower your ambitions to 2 octal digits and convert from BP to BH:

mov  bx, BP
mov  bh, bl

Next is a more complete code. The inputted octal digits are not stored in memory. The input gets validated and the conversion is done as the input progresses:

  ; Input octal digits up to the max value 177777o
  ; You can use as many leading zeroes as you like!
  xor  bx, bx     ; The resulting number
MoreInput:
  mov  ah, 01h
  int  21h        ; -> AL
  cmp  al, 13
  je   GotIt
  sub  al, "0"    ; From ["0","7"] -> [0,7] ?
  cmp  al, 8
  jnb  MoreInput  ; Redo because it was not an octal digit

  shl  bx, 1      ; This first shift simply cannot produce CF=1
  shl  bx, 1
  jc   Overflow   ; TO BE DECIDED WHAT THIS NEEDS TO DO
  shl  bx, 1
  jc   Overflow   ; TO BE DECIDED WHAT THIS NEEDS TO DO
  or   bl, al     ; Put newest octal digit in vacated 3-bit space
  jmp  MoreInput
GotIt:

And the following code now prints the contents of BX in the hexadecimal representation:

  mov  cx, 0404h  ; CH counts hex digits, CL counts rotations
MoreOutput:
  rol  bx, cl     ; 8086 didn't have rotate by immediate!
  mov  dl, bl
  and  dl, 15
  add  dl, "0"
  cmp  dl, "9"
  jbe  Print
  add  dl, 7      ; -> ["A","F"]
Print:
  mov  ah, 02h
  int  21h
  dec  ch
  jnz  MoreOutput

Upvotes: 2

Related Questions