Saturday, June 30, 2012

Very simple calculator with 8086

Hello, this is a project I made for learning. It should have many programming flaws, I didn't check and the comments are not enough. But it is working pretty well and it may be useful to somebody.

Here is a screenshot of it working;
                                        

The input format should be <integer><operator><integer>. Where <integer> is a value between 0 and 65535, and <operator> is a member of the set { + , - , * , /}.


And here is the code



CALL readdata
MOV BX, input
CALL printstr
CALL convertdata


MOV DI,input
MOV BX, SI
SUB BL,input
DEC BL 

begin:

CMP BL, 0
JNE morethanone
MOV CL,B[DI]
MOV CH,0h
ADD number1 W, CX
JMP finishconversion
morethanone:
MOV CL, BL
CALL expt
MOV CL, B[DI]
MOV CH, 0
MUL CX
ADD number1 W, AX
INC DI
DEC BL
JMP begin

finishconversion:



MOV DI, SI
INC DI
MOV BL, number2length B
DEC BL 

begin2:

CMP BL, 0
JNE morethanone2
MOV CL,B[DI]
MOV CH,0h
ADD number2 W, CX
JMP finishconversion2
morethanone2:
MOV CL, BL
CALL expt
MOV CL, B[DI]
MOV CH, 0
MUL CX
ADD number2 W, AX
INC DI
DEC BL
JMP begin2

finishconversion2:



MOV AX, number1 W
MOV BX, number2 W

CALL calculate

MOV result W, AX


CALL hextodecimal


MOV AH, 02h
MOV DL, '='
INT 21h

MOV DL, DH
CMP result W, 9999
JNG skip1
INT 21h
skip1:

MOV DL, CH
CMP result W, 999
JNG skip2
INT 21h
skip2:

MOV DL, CL
CMP result W, 99
JNG skip3
INT 21h
skip3:

MOV DL, BH
CMP result W, 9
JNG skip4
INT 21h
skip4:

MOV DL, BL
INT 21h

INT 20h


hextodecimal PROC

MOV     BX,0
MOV     CX,0
MOV     DH,0

convertloop2:

INC     BL               
CMP     BL,0Ah           
JNE     noripple         
MOV     BL,0             
INC     BH               
CMP     BH,0Ah           
JNE     noripple        
MOV     BH,0
INC     CL               
CMP     CL,0Ah
JNE     noripple
MOV     CL,0
INC     CH              
CMP     CH,0Ah
JNE     noripple
MOV     CH,0
INC     DH               


noripple:
DEC AX
CMP AX, 0h
JNE convertloop2

ADD DH, '0'
ADD CH, '0'
ADD CL, '0'
ADD BH, '0'
ADD BL, '0'

RET

hextodecimal ENDP


calculate PROC
ADD B[SI], '0' ; because we decreased it by 0's ascii value along with the other numbers..

CMP B[SI], '+'
JNE notAdd
ADD AX,BX
notAdd:
CMP B[SI], '-'
JNE notSub
SUB AX,BX
notSub:
CMP B[SI], '/'
JNE notDiv
MOV DX, 0h
DIV BX
notDiv:
CMP B[SI], '*'
JNE notMul
MUL BX
notMul:
RET
calculate ENDP





readdata PROC
MOV BX, input
MOV AH, 01h

readloop:
INT 21h
CMP AL, 13d
JE finishread

CMP AL, '0'
JNL jmpover
MOV SI, BX        ; we have the operators index in SI now
jmpover:

MOV B[BX], AL
INC BX

JMP readloop

finishread:
MOV B[BX], 0

sub BX, SI
DEC BX
MOV number2length B, BL

RET
readdata ENDP

convertdata PROC

MOV BX, input

convertloop:
CMP B[BX], 0
JE finishconvert

SUB B[BX], '0'
INC BX
JMP convertloop

finishconvert:

RET
convertdata ENDP


printstr PROC
myloop:
MOV AH, 02h ; we are setting it to print mode
MOV DL,[BX] ; we are moving the data located at the memory address BX to DL
CMP DL, 0h    ; we are checking if that data is 0
JE finish            ; if 0 we jump to finish and return
INT 21h           ; if not we output that data
INC BX           ; we are incrementing the memory location.
JMP myloop
finish:
RET
printstr ENDP

expt PROC
MOV AX, 10d

exptloop:
CMP CL, 1
JE exptfinish
MUL ten W
DEC CL
JMP exptloop

exptfinish:
RET
expt ENDP

ten:
dw 0Ah

number2length:
db 0

number1:
dw 0
number2:
dw 0


result:
dw 0

input:
db ?

No comments:

Post a Comment