Una calculadora en ASM x86 sin usar instrucciones “rarasâ€. Solo lo básico:
.model huge ; Imprime una cadena prints macro _str_ mov dx, offset _str_ mov ah, 09h int 21h endm ; Lee una cadena de caracteres gets macro _buff_ mov dx, offset _buff_ mov ah, 0Ah int 21h mov dx, offset _buff_ endm ; Limpia la pantalla limpia macro x, y mov ah, x int 10h mov ah, y int 10h endm .code inicio: ; Direccion del segmento de datos en ds, es mov ax, @data mov ds, ax menu: limpia 0fh, 0 prints m0 prints m2 prints m1 call getche sub al, 30h cmp al, 1 je caso1 cmp al, 2 je caso2 cmp al, 3 je caso3 cmp al, 4 je caso4 cmp al, 5 je caso5 loop menu caso1: call leer call suma call resultado prints m3 prints res call getche jmp menu caso2: call leer call resta cmp bh, 1 jne sinsigno call resultado prints m3 mov ah, 02h mov dl, '-' int 21h prints res call getche jmp menu sinsigno: call resultado prints m3 prints res call getche jmp menu caso3: call leer call multiplicacion call resultado prints m3 prints res call getche jmp menu caso4: call leer cmp cl, 0 je divzero call division call resultado prints m3 prints res call getche jmp menu divzero: prints diz call getche jmp menu caso5: call quit ; ========= Procedimientos =========== ; ax = ch + cl suma proc near mov al, ch mov bl, cl add ax, bx ; Por si la suma excede el byte ;mov ch, 1h ret suma endp ; ax = ch - cl resta proc near mov al, ch mov bl, cl cmp bl, al ja consigno sub al, bl mov ah, 0 ; No importa el signo ret consigno: sub bl, al mov al, bl mov ah, 0 ; No importa el signo mov bh, 1 ; El signo ret resta endp ; ax = ch * cl multiplicacion proc near mov al, ch mul cl ret multiplicacion endp ; ax = ch / cl division proc near mov al, ch div cl mov ah, 0 ; No importa el residuo ret division endp ; Convierte el valor de ax, (el resultado de la operacion) a una cadena resultado proc near mov ch, 2h ; Algo tiene que ver mov dx, 0h mov si, 8 mov bx, 0 ciclo: div divs[si] add al, 30h mov res[bx], al mov ax, dx mov dx, 0h cmp si, 0h je salto dec si dec si inc bx loop ciclo salto: ret resultado endp ; Lee 2 valores del teclado y almacena los numeros en ch y cl leer proc near prints p1 gets n1 mov cl, 0h mov bl, n1[1] mov di, bx mov si, 0h conv: mov al, n1[di+1] sub al, 30h mul mult[si] add cl, al dec di inc si cmp di, 0h jne conv mov ch, cl prints p2 gets n2 mov cl, 0h mov bl, n2[1] mov di, bx mov si, 0h conv1: mov al, n2[di+1] sub al, 30h mul mult[si] add cl, al dec di inc si cmp di, 0h jne conv1 ret leer endp ; Termina el programa quit proc near mov ah,4ch int 21h ret quit endp ; Lee un caracter getche proc near mov ah, 01h int 21h ret getche endp .data diz db 13,10, "Division por zero.", "$" m0 db "CALCULADORA BASICA", 13, 10, "$" m1 db "Selecciona la operacion a realizar:", 13, 10, "$" m2 db " 1. Suma", 13, 10, " 2. Resta", 13, 10, " 3. Multiplicacion", 13, 10, " 4. Division", 13, 10, " 5. Salir", 13, 10, "$" m3 db 10,13,"El resultado de la operacion es: ", "$" p1 db 10,13,"Introduce el primer numero: ", "$" p2 db 10,13,"Introduce el segundo numero: ", "$" n1 DB 4,?,4 DUP('$'),'$' n2 DB 4,?,4 DUP('$'),'$' res DB 10 DUP('$'), '$' mult db 1, 10, 100, 0 divs dw 1, 10, 100, 1000, 10000 .stack end inicio
