Ok, luego de ver varios ejemplos consegui una calculadora y le modifique para que solo sumara y restara, pero veo que se ve como muy complicada para alguien que solo llevo una clase de esta vara... Deberia simplificarla mas??
name "Proyecto2"
PUTC MACRO char
PUSH AX
MOV AL, char
MOV AH, 0Eh
INT 10h
POP AX
ENDM
org 100h
jmp start
; variables
msg1 db 0Dh,0Ah, 'Digite el primer numero: $'
msg2 db "Digite el simbolo correspondiente a la operacion deseada: + - : $"
msg3 db "Digite el segundo numero: $"
msg4 db 0dh,0ah , 'El resultado es : $'
msg5 db 0dh,0ah ,'Presione la tecla "s" para salir : ', 0Dh,0Ah, '$'
err1 db "Simbolo de operacion incorrecto!", 0Dh,0Ah , '$'
opr db '?'
num1 dw ?
num2 dw ?
start:
;mov dx, offset msg0
lea dx, msg1
mov ah, 09h
int 21h
call scan_num
; guarda el primer numero digitado
mov num1, cx
;nueva linea creada
putc 0Dh
putc 0Ah
lea dx, msg2
mov ah, 09h
int 21h
;aqui se obtiene el operador
mov ah, 1 ; entra un char al AL.
int 21h
mov opr, al
;nueva linea creada
putc 0Dh
putc 0Ah
cmp opr, 's'; s para salida del programa
je exit
lea dx, msg3
mov ah, 09h
int 21h
call scan_num
; se guarda el segundo numero digitado
mov num2, cx
lea dx, msg4
mov ah, 09h
int 21h
; calculate:
cmp opr, '+'
je do_plus
cmp opr, '-'
je do_minus
wrong_opr:
lea dx, err1
mov ah, 09h
int 21h
exit:
lea dx, msg5
mov ah, 09h
int 21h
;esperar a que una tecla sea presionada
mov ah, 0
int 16h
ret;retornar al OS
do_plus:
mov ax, num1
add ax, num2
call print_num ; imprime el valor de ax.
jmp exit
do_minus:
mov ax, num1
sub ax, num2
call print_num ; imprime el valor de ax.
jmp exit
SCAN_NUM PROC NEAR
PUSH DX
PUSH AX
PUSH SI
MOV CX, 0
; bandera en reset
MOV CS:make_minus, 0
next_digit:
; obtiene un char del teclado
; into AL:
MOV AH, 00h
INT 16h
; y lo imprime:
MOV AH, 0Eh
INT 10h
; checkea el MINUS:
CMP AL, '-'
JE set_minus
; checkea el ENTER:
CMP AL, 0Dh ; carriage return?
JNE not_cr
JMP stop_input
not_cr:
CMP AL, 8 ; pregunta si el 'BACKSPACE' fue presionado?
JNE backspace_checked
MOV DX, 0 ; removueva el ultimo digito
MOV AX, CX ; division:
; DIV CS:ten
; MOV CX, AX
PUTC ' ' ; clear position.
PUTC 8 ; backspace de nuevo.
JMP next_digit
backspace_checked:
; allow only digits:
CMP AL, '0'
JAE ok_AE_0
JMP remove_not_digit
ok_AE_0:
CMP AL, '9'
JBE ok_digit
remove_not_digit:
PUTC 8 ; backspace.
PUTC ' '
PUTC 8 ; backspace again.
JMP next_digit; espera por la siguiente entrada.
ok_digit:
; multiplica CX por 10 (la primera vez el resultado es zero)
PUSH AX
MOV AX, CX
MUL CS:ten ; DX:AX = AX*10
MOV CX, AX
POP AX
; checkea si el numero es muy grande
CMP DX, 0
JNE too_big
; convertir del codigo ASCII:
SUB AL, 30h
; add AL to CX:
MOV AH, 0
MOV DX, CX
ADD CX, AX
JC too_big2
JMP next_digit
set_minus:
MOV CS:make_minus, 1
JMP next_digit
too_big2:
MOV CX, DX
MOV DX, 0
too_big:
MOV AX, CX
DIV CS:ten ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
MOV CX, AX
PUTC 8 ; backspace.
PUTC ' '
PUTC 8 ; backspace again.
JMP next_digit; esperar a que Enter/Backspace sean presionados.
stop_input:
; checkear la bandera:
CMP CS:make_minus, 0
JE not_minus
NEG CX
not_minus:
POP SI
POP AX
POP DX
RET
make_minus DB ? ;usado como bandera.
SCAN_NUM ENDP
;imprime el numero en AX
; usa PRINT_NUM_UNS para imprimir los numeros:
PRINT_NUM PROC NEAR
PUSH DX
PUSH AX
CMP AX, 0
JNZ not_zero
PUTC '0'
JMP printed
not_zero:
; revisa el signo de AX
; make absolute if it's negative:
CMP AX, 0
JNS positive
NEG AX
PUTC '-'
positive:
CALL PRINT_NUM_UNS
printed:
POP AX
POP DX
RET
PRINT_NUM ENDP
; allowed values are from 0 to 65535 (FFFF)
PRINT_NUM_UNS PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
; la bandera para prevenir imprimir zeros antes del número:
MOV CX, 1
; (el resultado de "/ 10000" siempre es menor o igual que 9).
MOV BX, 10000 ; 2710h - divider.
; AX is zero?
CMP AX, 0
JZ print_zero
begin_print:
CMP BX,0
JZ end_print
; la bandera para prevenir imprimir zeros antes del número:
CMP CX, 0
JE calc
; if AX<BX then result of DIV will be zero:
CMP AX, BX
JB skip
calc:
MOV CX, 0 ; set flag.
MOV DX, 0
DIV BX ; AX = DX:AX / BX (DX=remainder).
; print last digit
; AH is always ZERO, so it's ignored
ADD AL, 30h ; convert to ASCII code.
PUTC AL
MOV AX, DX ; get remainder from last div.
skip:
; calculate BX=BX/10
PUSH AX
MOV DX, 0
MOV AX, BX
DIV CS:ten ; AX = DX:AX / 10 (DX=remainder).
MOV BX, AX
POP AX
JMP begin_print
print_zero:
PUTC '0'
end_print:
POP DX
POP CX
POP BX
POP AX
RET
PRINT_NUM_UNS ENDP
ten DW 10 ; used as multiplier/divider by SCAN_NUM & PRINT_NUM_UNS.
GET_STRING PROC NEAR
PUSH AX
PUSH CX
PUSH DI
PUSH DX
MOV CX, 0 ; char counter.
CMP DX, 1 ; buffer too small?
JBE empty_buffer ;
DEC DX ; reserve space for last zero.
;============================
; loop infinito para obtener
; y procesar la tecla presionada:
wait_for_key:
MOV AH, 0 ; obtener tecla presionada.
INT 16h
CMP AL, 0Dh ; 'RETURN'
JZ exit_GET_STRING
CMP AL, 8 ; 'BACKSPACE'
JNE add_to_buffer
JCXZ wait_for_key ; nothing to remove!
DEC CX
DEC DI
PUTC 8 ; backspace.
PUTC ' ' ;limpiar posicion.
PUTC 8 ; backspace.
JMP wait_for_key
add_to_buffer:
CMP CX, DX ; buffer esta lleno?
JAE wait_for_key ; if so wait for 'BACKSPACE' or 'RETURN'...
MOV [DI], AL
INC DI
INC CX
; imprimir simbolo:
MOV AH, 0Eh
INT 10h
JMP wait_for_key
;============================
exit_GET_STRING:
; terminate by null:
MOV [DI], 0
empty_buffer:
POP DX
POP DI
POP CX
POP AX
RET
GET_STRING ENDP