Hola,
Mi nombre es Nicolás y me acabo de registrar en el foro. Estoy haciendo en una calculadora la cual primero le pide al usuario que ingrese dos números y después le pide que indique que operación desea realizar con estos dos números. Mi calculadora suma, resta y multiplica correctamente pero no es capaz de dividir. Al intentar realizar una división recibo el error "Excepción de coma flotante".
A continuación les dejo mi código:
section .data
; Mensajes
msg1 db 10,'-Calculadora-',10,0
lmsg1 equ $ - msg1
msg2 db 10,'Numero 1: ',0
lmsg2 equ $ - msg2
msg3 db 'Numero 2: ',0
lmsg3 equ $ - msg3
msg4 db 10,'1. Sumar',10,0
lmsg4 equ $ - msg4
msg5 db '2. Restar',10,0
lmsg5 equ $ - msg5
msg6 db '3. Multiplicar',10,0
lmsg6 equ $ - msg6
msg7 db '4. Dividir',10,0
lmsg7 equ $ - msg7
msg8 db 'Operacion: ',0
lmsg8 equ $ - msg8
msg9 db 10,'Resultado: ',0
lmsg9 equ $ - msg9
msg10 db 10,'Opcion Incorrecta',10,0
lmsg10 equ $ - msg10
nlinea db 10,10,0
lnlinea equ $ - nlinea
section .bss
; Espacios reservados para almacenar los valores proporcionados
; por el usuario.
opc resb 2
num1 resw 2
num2 resw 2
result resw 2
section .text
global _start
_start:
; Imprimimos en pantalla el mensaje 1
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, lmsg1
int 80h
; Imprimimos en pantalla el mensaje 2
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, lmsg2
int 80h
; Obtenemos el valor de numero1
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2
int 80h
; Imprimimos en pantalla el mensaje 3
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, lmsg3
int 80h
; Obtenemos el valor de numero2
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2
int 80h
; Imprimimos en pantalla el mensaje 4
mov eax, 4
mov ebx, 1
mov ecx, msg4
mov edx, lmsg4
int 80h
; Imprimimos en pantalla el mensaje 5
mov eax, 4
mov ebx, 1
mov ecx, msg5
mov edx, lmsg5
int 80h
; Imprimimos en pantalla el mensaje 6
mov eax, 4
mov ebx, 1
mov ecx, msg6
mov edx, lmsg6
int 80h
; Imprimimos en pantalla el mensaje 7
mov eax, 4
mov ebx, 1
mov ecx, msg7
mov edx, lmsg7
int 80h
; Imprimimos en pantalla el mensaje 8
mov eax, 4
mov ebx, 1
mov ecx, msg8
mov edx, lmsg8
int 80h
; Obtenemos la opcion deseada por el usuario
mov ebx,0
mov ecx,opc
mov edx,2
mov eax,3
int 80h
mov ah, [opc] ; Movemos la opcion seleccionada al registro ah
sub ah, '0' ; Convertimos de ascii a decimal
; Comparamos el valor ingresado por el usuario para saber que
; operacion desea realizar.
cmp ah, 1
je sumar
cmp ah, 2
je restar
cmp ah, 3
je multiplicar
cmp ah, 4
je dividir
; Si el valor ingresado por el usuario no cumple ninguna de las
; condiciones anteriores entonces mostramos un mensaje de error y
; finalizamos el programa.
mov eax, 4
mov ebx, 1
mov ecx, msg10
mov edx, lmsg10
int 80h
jmp salir
sumar:
; Guardamos los numeros en los registros eax y ebx
mov eax, [num1]
mov ebx, [num2]
; Conversion de ascii a decimal
sub eax, '0'
sub ebx, '0'
; Suma
add eax, ebx
; Conversion de decimal a ascii
add eax, '0'
; Movemos el resultado
mov [result], eax
; Imprimimos el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos el resultado
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
restar:
; Guardamos los numeros en los registros eax y ebx
mov eax, [num1]
mov ebx, [num2]
; Conversion de ascii a decimal
sub eax, '0'
sub ebx, '0'
; Resta
sub eax, ebx
; Conversion de decimal a ascii
add eax, '0'
; Movemos el resultado
mov [result], eax
; Imprimimos el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos el resultado
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
multiplicar:
; Guardamos los numeros en los registros ax y bx
mov ax, [num1]
mov bx, [num2]
; Conversion de ascii a decimal
sub ax, '0'
sub bx, '0'
; Multiplicacion. AL = AX x BX
mul bx
; Conversion decimal a ascii
add al, '0'
; Movemos el resultado
mov [result], al
; Imprimimos el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos el resultado
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
dividir:
; Guardamos los numeros en los registros ax y bl
mov ax, [num1]
mov bl, [num2]
; Conversion de ascii a decimal
sub ax, '0'
sub bl, '0'
; Division. AL = AX / BL
div bl
; Conversion decimal a ascii
add al, '0'
; Movemos el resultado
mov [result], al
; Imprimimos el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos el resultado
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
salir:
; Imprimimos dos nuevas lineas
mov eax, 4
mov ebx, 1
mov ecx, nlinea
mov edx, lnlinea
int 80h
; Finalizamos el programa
mov eax, 1
mov ebx, 0
int 80h
El problema se encuentra dentro de la etiqueta dividir. Es la unica operacion que devuelve un error.
Espero que algun usuario me pueda ayudar a resolver este error.
Muchas Gracias
podrias poner la linea del error, no tengo nasm talvez con logica se resuelve :P
El error se encuentra en esta parte:
dividir:
; Guardamos los numeros en los registros ax y bl
mov ax, [num1]
mov bl, [num2]
; Conversion de ascii a decimal
sub ax, '0'
sub bl, '0'
; Division. AL = AX / BL
div bl
; Conversion decimal a ascii
add al, '0'
; Movemos el resultado
mov [result], al
; Imprimimos el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos el resultado
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
Para ser mas exacto esta linea genera el error:
div bl
Al ejecutar esta linea se genera una "Excepción de coma flotante".
E probado con MASM y me ah funcionado, bueno nose como trabaja la interrupcion 80 o como obtienes los valores
pero estas lineas si num1 y num2 son punteros a los valores estarian bien sino si son los valores en si, entonces esta incorrecto
porque estarias usando los valores como punteros:
mov ax, [num1]
mov bl, [num2]
sino, lo mejor es que depures el codigo
Seguí investigando por mi cuenta y modifique la etiqueta dividir.
Ahora quedo así:
dividir:
; Guardamos los numeros en los registros ax y bl
mov dx, 0
mov ax, [num1]
mov bx, [num2]
; Conversion de ascii a decimal
sub ax, '0'
sub bx, '0'
; Division. AX = DX:AX / BX
div bx
; Conversion decimal a ascii
add ax, '0'
; Movemos el resultado
mov [result], ax
; Imprimimos el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos el resultado
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
Sigue sin funcionar pero ya no me genera mas la excepción. El problema ahora es que sin importar que división haga siempre me devuelve 1.
Podra alguien ayudarme? Gracias
Hola a todos,
Quería comentarles que logre finalmente arreglar mi calculadora. A continuación les dejo el código. Espero que le sirva a algún principiante.
section .data
; Mensajes
msg1 db 10,'-Calculadora-',10,0
lmsg1 equ $ - msg1
msg2 db 10,'Numero 1: ',0
lmsg2 equ $ - msg2
msg3 db 'Numero 2: ',0
lmsg3 equ $ - msg3
msg4 db 10,'1. Sumar',10,0
lmsg4 equ $ - msg4
msg5 db '2. Restar',10,0
lmsg5 equ $ - msg5
msg6 db '3. Multiplicar',10,0
lmsg6 equ $ - msg6
msg7 db '4. Dividir',10,0
lmsg7 equ $ - msg7
msg8 db 'Operacion: ',0
lmsg8 equ $ - msg8
msg9 db 10,'Resultado: ',0
lmsg9 equ $ - msg9
msg10 db 10,'Opcion Invalida',10,0
lmsg10 equ $ - msg10
nlinea db 10,10,0
lnlinea equ $ - nlinea
section .bss
; Espacios en la memoria reservados para almacenar los valores introducidos por el usuario y el resultado de la operacion.
opcion: resb 2
num1: resb 2
num2: resb 2
resultado: resb 2
section .text
global _start
_start:
; Imprimimos en pantalla el mensaje 1
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, lmsg1
int 80h
; Imprimimos en pantalla el mensaje 2
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, lmsg2
int 80h
; Obtenemos el numero 1
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2
int 80h
; Imprimimos en pantalla el mensaje 3
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, lmsg3
int 80h
; Obtenemos el numero 2
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2
int 80h
; Imprimimos en pantalla el mensaje 4
mov eax, 4
mov ebx, 1
mov ecx, msg4
mov edx, lmsg4
int 80h
; Imprimimos en pantalla el mensaje 5
mov eax, 4
mov ebx, 1
mov ecx, msg5
mov edx, lmsg5
int 80h
; Imprimimos en pantalla el mensaje 6
mov eax, 4
mov ebx, 1
mov ecx, msg6
mov edx, lmsg6
int 80h
; Imprimimos en pantalla el mensaje 7
mov eax, 4
mov ebx, 1
mov ecx, msg7
mov edx, lmsg7
int 80h
; Print on screen the message 8
mov eax, 4
mov ebx, 1
mov ecx, msg8
mov edx, lmsg8
int 80h
; Obtenemos la opcion seleccionada por el usuario
mov ebx, 0
mov ecx, opcion
mov edx, 2
mov eax, 3
int 80h
mov ah, [opcion] ; Movemos la opcion seleccionada a el registro AH
sub ah, '0' ; Convertimos el valor ingresado de ascii a decimal
; Comparamos el valor ingresado por el usuario para saber que operacion realizar.
; JE = Jump if equal = Saltamos si el valor comparado es igual
cmp ah, 1
je sumar
cmp ah, 2
je restar
cmp ah, 3
je multiplicar
cmp ah, 4
je dividir
; Si el valor ingresado no cumple con ninguna de las condiciones anteriores entonces mostramos un mensaje de error y finalizamos
; la ejecucion del programa
mov eax, 4
mov ebx, 1
mov ecx, msg10
mov edx, lmsg10
int 80h
jmp salir
sumar:
; Movemos los numeros ingresados a los registro AL y BL
mov al, [num1]
mov bl, [num2]
; Convertimos los valores ingresados de ascii a decimal
sub al, '0'
sub bl, '0'
; Sumamos el registro AL y BL
add al, bl
; Convertimos el resultado de la suma de decimal a ascii
add al, '0'
; Movemos el resultado a un espacio reservado en la memoria
mov [resultado], al
; Imprimimos en pantalla el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos en pantalla el resultado
mov eax, 4
mov ebx, 1
mov ecx, resultado
mov edx, 2
int 80h
; Finalizamos el programa
jmp salir
restar:
; Movemos los numeros ingresados a los registro AL y BL
mov al, [num1]
mov bl, [num2]
; Convertimos los valores ingresados de ascii a decimal
sub al, '0'
sub bl, '0'
; Restamos el registro AL y BL
sub al, bl
; Convertimos el resultado de la resta de decimal a ascii
add al, '0'
; Movemos el resultado a un espacio reservado en la memoria
mov [resultado], al
; Imprimimos en pantalla el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos en pantalla el resultado
mov eax, 4
mov ebx, 1
mov ecx, resultado
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
multiplicar:
; Movemos los numeros ingresados a los registro AL y BL
mov al, [num1]
mov bl, [num2]
; Convertimos los valores ingresados de ascii a decimal
sub al, '0'
sub bl, '0'
; Multiplicamos. AX = AL X BL
mul bl
; Convertimos el resultado de la resta de decimal a ascii
add ax, '0'
; Movemos el resultado a un espacio reservado en la memoria
mov [resultado], ax
; Imprimimos en pantalla el mensaje 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos en pantalla el resultado
mov eax, 4
mov ebx, 1
mov ecx, resultado
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
dividir:
; Movemos los numeros ingresados a los registro AL y BL
mov al, [num1]
mov bl, [num2]
; Igualamos a cero los registros DX y AH
mov dx, 0
mov ah, 0
; Convertimos los valores ingresados de ascii a decimal
sub al, '0'
sub bl, '0'
; Division. AL = AX / BL. AX = AH:AL
div bl
; Convertimos el resultado de la resta de decimal a ascii
add ax, '0'
; Movemos el resultado a un espacio reservado en la memoria
mov [resultado], ax
; Print on screen the message 9
mov eax, 4
mov ebx, 1
mov ecx, msg9
mov edx, lmsg9
int 80h
; Imprimimos en pantalla el resultado
mov eax, 4
mov ebx, 1
mov ecx, resultado
mov edx, 1
int 80h
; Finalizamos el programa
jmp salir
salir:
; Imprimimos en pantalla dos nuevas lineas
mov eax, 4
mov ebx, 1
mov ecx, nlinea
mov edx, lnlinea
int 80h
; Finalizamos el programa
mov eax, 1
mov ebx, 0
int 80h