You are on page 1of 20

name "calcu"

PUTC MACRO char push ax, mov al, char mov ah, 0EH int 10h pop ax

endm

org 100h jmp start

msg0 db "note: calculator works with integer values only.",0Dh,0Ah db "",0Dh,0Ah,'$' msg1 db 0Dh,0Ah, 0Dh,0Ah, 'enter first number: $' msg2 db "enter the operator: + - * / msg3 db "enter second number: $" : $"

msg4 db 0dh,0ah , 'the approximate result of my calculations is : $' err1 db "wrong operator!", 0Dh,0Ah , '$' smth db " and something.... $"

opr db '?'

num1 dw ? num2 dw ?

start: mov dx, offset msg0 mov ah, 9 int 21h

lea dx, msg1 mov ah, 09h int 21h

call scan_num

mov num1, cx

putc 0Dh putc 0Ah

lea dx, msg2 mov ah, 09h int 21h

mov ah, 1 int 21h mov opr, al

putc 0Dh putc 0Ah

cmp opr, 'q' je exit

cmp opr, '*' jb wrong_opr cmp opr, '/' ja wrong_opr

lea dx, msg3 mov ah, 09h int 21h

call scan_num

mov num2, cx

lea dx, msg4 mov ah, 09h int 21h

cmp opr, '+' je do_plus

cmp opr, '-' je do_minus

cmp opr, '*' je do_mult

cmp opr, '/' je do_div

wrong_opr: lea dx, err1 mov ah, 09h

int 21h

exit:

lea dx, msg5 mov ah, 09h int 21h

mov ah, 0 int 16h

ret

do_plus:

mov ax, num1 add ax, num2 call print_num

jmp exit

do_minus:

mov ax, num1 sub ax, num2 call print_num

jmp exit

do_mult:

mov ax, num1 imul num2 call print_num

jmp exit

do_div:

mov dx, 0 mov ax, num1 idiv num2 cmp dx, 0 jnz approx call print_num jmp exit approx: call print_num lea dx, smth mov ah, 09h int 21h jmp exit

scan_num

PROC NEAR

PUSH DX PUSH AX PUSH SI

MOV

CX, 0

MOV

CS:make_minus, 0

next_digit:

MOV INT

AH, 00h 16h

MOV INT

AH, 0Eh 10h

CMP JE

AL, '-' set_minus

CMP JNE JMP not_cr:

AL, 0Dh not_cr stop_input

CMP JNE MOV MOV DIV MOV

AL, 8 backspace_checked DX, 0 AX, CX CS:ten CX, AX

PUTC ' ' PUTC 8 JMP next_digit

backspace_checked:

CMP JAE JMP ok_AE_0: CMP JBE

AL, '0' ok_AE_0 remove_not_digit

AL, '9' ok_digit

remove_not_digit: putc 8 putc ' ' putc 8 JMP ok_digit: next_digit

push ax mov mul mov pop ax, cx cs:ten cx, ax ax

cmp jne

dx, 0 too_big

sub

al, 30h

mov mov add JC

ah, 0 dx, cx CX, AX too_big2

jmp

next_digit

set_minus: mov jmp CS:make_minus, 1 next_digit

too_big2: mov mov too_big: mov div mov AX, CX CS:ten CX, AX CX, DX DX, 0

putc 8 putc ' ' putc 8 jmp next_digit

stop_input:

cmp JE NEG not_minus:

CS:make_minus, 0 not_minus CX

POP POP POP RET

SI AX DX

make_minus SCAN_NUM

DB ENDP

PRINT_NUM PUSH DX PUSH AX

PROC NEAR

CMP JNZ

AX, 0 not_zero

PUTC '0' JMP printed

not_zero:

CMP JNS NEG

AX, 0 positive AX

PUTC '-'

positive: CALL PRINT_NUM_UNS printed: POP POP RET PRINT_NUM ENDP AX DX

PRINT_NUM_UNS PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX

MOV

CX, 1

MOV

BX, 10000

CMP JZ

AX, 0 print_zero

begin_print:

CMP JZ

BX,0 end_print

CMP JE

CX, 0 calc

CMP JB calc: MOV

AX, BX skip

CX, 0

MOV DIV

DX, 0 BX

ADD

AL, 30h

PUTC AL

MOV

AX, DX

skip:

PUSH AX MOV MOV DX, 0 AX, BX

DIV MOV POP

CS:ten BX, AX AX

JMP

begin_print

print_zero: PUTC '0'

end_print:

POP POP POP POP RET

DX CX BX AX

PRINT_NUM_UNS ENDP

ten

DW

10

GET_STRING PUSH AX PUSH CX PUSH DI PUSH DX

PROC NEAR

MOV

CX, 0

CMP JBE

DX, 1 empty_buffer

DEC

DX

wait_for_key:

MOV INT

AH, 0 16h

CMP

AL, 0Dh

JZ

exit_GET_STRING

CMP JNE

AL, 8 add_to_buffer

JCXZ wait_for_key DEC DEC CX DI

PUTC 8 PUTC ' ' PUTC 8 JMP wait_for_key

add_to_buffer:

CMP JAE

CX, DX wait_for_key

MOV INC INC

[DI], AL DI CX

MOV INT

AH, 0Eh 10h

JMP

wait_for_key

;============================

exit_GET_STRING:

MOV

[DI], 0

empty_buffer:

POP POP POP POP RET

DX DI CX AX

GET_STRING

ENDP

You might also like