;Lourdes Marisol Castillo Caamal
;Carolina Maribel Fernández Uicab
;Angel Iram Torres Salazar
section .data
;Mensaje de ingresar el primer número
num1 db "Ingresa el primer número: ",10
num1_len equ $ - num1
;Mensaje de ingresar segundo número
num2 db "Ingresa un segundo número (debe ser menor que el primer número capturado): ",10
num2_len equ $ - num2
;Mensaje de selección de opción sume o resta
opcion db "Ingresar 1 si desea sumar los dos números ingresados o 2 si los desea restar: ",10
opcion_lem equ $ - opcion
;Leer el valor 1
valor1 times 64 db 0 ;reservamos 64 bytes
valor1_lem equ $ - valor1
;Leer el valor 2
valor2 times 64 db 0 ;reservamos 64 bytes
valor2_lem equ $ - valor2
;Leer la selección
selc times 2 db 0 ;solo leemos el valor y el Enter
;Mensaje de resultado de la suma
msgs db "El resultado de la suma es: ",10
msgs_lem equ $ - msgs
;Mensaje de resultado de la resta
msgr db "El resultado de la resta es: ",10
msgr_lem equ $ - msgr
;Reserva del resultado delimitada a 64 bytes pero podemos ponerlo en equ $ - resultado
resultado times 64 db 0
resultado_lem equ 64
;Mensaje de error por opción inválida
msge db "Error: opción inválida. Solo se permite 1 o 2.",10
msge_lem equ $ - msge
section .text
global _start
_start:
;mensaje de solicitud del primer número
mov rax, 1 ;imprimir
mov rdi, 1 ;en pantalla
mov rsi, num1
mov rdx, num1_len
syscall
;leemos el primer número, un carácter a la vez hasta el Enter
mov rsi, valor1 ;es el inicio del buffer en el valor que se ha leído
leer1: ;se coloca un ciclo para leer cada número uno por uno
mov rax, 0 ;llamado a leer
mov rdi, 0 ;teclado estándar
mov rdx, 1 ;un solo carácter
syscall
mov al, [rsi] ;CONTENIDO EN CORCHETES NO LA DIRECCIÓN
cmp al, 10 ;10 es el Enter es decir cuando acaba el ciclo
je fin_leer1 ;si es Enter sale del ciclo
inc rsi ;si no avanza la siguiente posición
jmp leer1 ;y repite hasta tener el Enter
fin_leer1:
;solicitud del segundo número
mov rax, 1 ;imprimir
mov rdi, 1 ;en pantalla
mov rsi, num2
mov rdx, num2_len
syscall
;leemos el segundo número, un carácter a la vez hasta el Enter
mov rsi, valor2
leer2:
mov rax, 0 ;llamado a leer
mov rdi, 0 ;teclado estándar
mov rdx, 1 ;un solo carácter
syscall
mov al, [rsi] ;CONTENIDO EN CORCHETES NO LA DIRECCIÓN
cmp al, 10 ;10 es el Enter es decir cuando acaba el ciclo
je fin_leer2 ;si es así sale del ciclo
inc rsi ;si no avanza a la siguiente posición
jmp leer2 ;y se repite hasta obtener el Enter
fin_leer2:
pedir_opcion:
; mostrar selección de opción suma o resta
mov rax, 1 ;imprimir
mov rdi, 1 ;en pantalla
mov rsi, opcion
mov rdx, opcion_lem
syscall
;leemos el dígito de la opción
mov rax, 0 ;sysread
mov rdi, 0 ;teclado estándar
mov rsi, selc
mov rdx, 1
syscall
;convertir el segundo número de ASCII a número (todos sus dígitos) considerar que como vamos a trabajar la suma y resta en rax guardamos primero el segundo número
mov rsi, valor2 ;copia la dirección de memoria donde están almacenados
xor rax, rax ;acumulador en 0
convertir2:
xor rdx, rdx ;limpiamos rdx
mov dl, [rsi] ;tomamos un carácter de la dirección y lo lleva a la parte baja como solo va a ser por el momento un dígito usamos solo una fracción
cmp dl, 10 ;si es el Enter termina
je fin2
sub dl, '0' ;convertimos el dígito a ASCII a dígito
mov rcx, rax ;acumulado * 10 usando solo add
add rax, rax ;x2 acumulador
add rax, rax ;x4 acumulador
add rax, rcx ;x5 acumulador
add rax, rax ;x10 acumulador
add rax, rdx ;+ dígito suma el siguiente dígito para la posición
inc rsi ;siguiente carácter
jmp convertir2 ;se repite hasta el Enter que es 10
fin2:
mov rbx, rax ;guarda el segundo número en rbx
;convertir el primer número de ASCII a número (todos sus dígitos)
mov rsi, valor1 ;copia la dirección de memoria donde están almacenados
xor rax, rax ;acumulador en 0
convertir1:
xor rdx, rdx ;limpiar rdx
mov dl, [rsi] ;tomamos un carácter
cmp dl, 10 ;si es Enter termina y no hace ciclos de acomodar los valores
je fin1
sub dl, '0' ;convertir el dígito a ASCII a dígito
mov rcx, rax ;acumulador * 10 usando solo add
add rax, rax ;x2 acumulador
add rax, rax ;x4 acumulador
add rax, rcx ;x5 acumulador
add rax, rax ;z10 acumulador
add rax, rdx ;+ dígito suma el siguiente dígito para la posición
inc rsi ;siguiente carácter
jmp convertir1 ;se repite hasta el Enter que es 10
fin1: ;el primer número se guarda en rax
;Convertir opción a número
xor rcx, rcx ;limpiamos o sea volver en 0
mov cl, [selc] ;tomamos el contenido y lo pasamos a cl que como solo es 1 dígito con el Enter podemos ponerle en la parte baja
sub cl, '0' ;lo convertimos a ASCII
seleccion:
;Comprobar opción
cmp cl, 1 ;si es 1 lo sumamos
je suma ;lo lleva a suma
cmp cl, 2 ;si es 2 lo resta
je resta ;lo lleva a resta
;si no es 1 ni 2 muestra el mensaje de error
mov rax, 1 ;imprimir
mov rdi, 1 ;en pantalla
mov rsi, msge ;mensaje de error
mov rdx, msge_lem
syscall
;terminar
mov rax, 60
mov rdi, 0
syscall
suma:
add rax, rbx ;sume primero + segundo
mov rbx, rax ;guardamos el resultado en rbx, pues el syscall modifica rax
mov rax, 1 ;imprimir
mov rdi, 1 ;en pantalla
mov rsi, msgs ;mensaje de que es suma
mov rdx, msgs_lem
syscall
mov rax, rbx ;regresamos el valor en rax
jmp imprimir ;y lleva a imprimir para no ir a la resta además que deben contabilizar las unidades decenas y centenas de la respuesta
resta:
sub rax, rbx ;resta del primero - segundo
mov rbx, rax ;guardamos el resultado en rbx, pues el syscall modifica rax
mov rax, 1 ;imprimir
mov rdi, 1 ;en pantalla
mov rsi, msgr ;mensaje de que es resta
mov rdx, msgr_lem
syscall
mov rax, rbx ;regresamos el valor a rax y directamente pasa a imprimir es decir sigue con el programa
imprimir:
mov rbx, 10 ;Divisor
mov rsi, resultado_lem ;Cuánto va a imprimir/tamaño
mov rcx, 0 ;Contador cuántos dígitos almacenamos
;El resultado se convierte de derecha a izquierda
convertir:
xor rdx, rdx ;Limpiar y colocar 0
div rbx ;Dividir
add dl, '0' ;Convertir residuo a carácter ASCII
dec rsi ;Retroceder una posición
mov [resultado + rsi], dl ;Guarda el carácter en resultado sumando el retroceso de posición
inc rcx ;Contador de los dígitos
test rax, rax ;Comprueba que el cociente es cero
jnz convertir ;Si no es cero repite, cuando todo se almacenó y es 0 sale para imprimir
;Impresión del resultado
mov rax, 1
mov rdi, 1
lea rsi, [resultado + rsi] ;Movemos los datos a rsi para su impresión
mov rdx, rcx ;Cantidad real de dígitos
syscall
;TERMINAR PROGRAMA
mov rax, 60
mov rdi,0
syscall
To embed this project on your website, copy the following code and paste it into your website's HTML: