Reputation: 11
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:
.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
.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
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.
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