; Integrantes del equipo:
; - Nombre Apellido 1
; - Nombre Apellido 2
; - Nombre Apellido 3
;
; Programa: Menú para sumar o restar dos números de varios dígitos
section .data
menu db "===== MENÚ =====", 10, "1. Sumar dos números", 10, "2. Restar dos números", 10, "Elige una opción: "
menu_len equ $-menu
prompt_n1 db "Teclea el primer número (máximo 6 dígitos): "
prompt_n1_len equ $-prompt_n1
prompt_n2 db "Teclea el segundo número (máximo 6 dígitos): "
prompt_n2_len equ $-prompt_n2
mensaje_res db "El resultado es: "
mensaje_res_len equ $-mensaje_res
msg_error db "Opción inválida, solo puedes elegir 1 o 2.", 10
msg_error_len equ $-msg_error
msg_negativo db "Error: no se permiten números negativos.", 10
msg_negativo_len equ $-msg_negativo
msg_no_numero db "Error: solo puedes teclear números del 0 al 9.", 10
msg_no_numero_len equ $-msg_no_numero
msg_resta db "Error: en la resta el primer número no puede ser menor que el segundo.", 10
msg_resta_len equ $-msg_resta
opcion times 2 db 0
salto times 2 db 0
num1 times 8 db 0
num2 times 8 db 0
resultado db "0000000000", 10
section .text
global _start
_start:
; Mostramos el menú
mov rax, 1
mov rdi, 1
mov rsi, menu
mov rdx, menu_len
syscall
; Leemos la opción y después el salto de línea
mov rax, 0
mov rdi, 0
mov rsi, opcion
mov rdx, 1
syscall
mov rax, 0
mov rdi, 0
mov rsi, salto
mov rdx, 1
syscall
; Solo se debe haber tecleado un carácter
mov bl, [salto]
cmp bl, 10
je revisar_opcion
cmp bl, 0
je revisar_opcion
jmp opcion_invalida
revisar_opcion:
mov al, [opcion]
cmp al, "1"
je pedir_numeros
cmp al, "2"
je pedir_numeros
jmp opcion_invalida
pedir_numeros:
; rbx guarda en qué variable se lee el número (num1 o num2)
mov rbx, num1
mov rsi, prompt_n1
mov rdx, prompt_n1_len
pedir_numero:
mov rax, 1
mov rdi, 1
syscall
mov rsi, rbx
leer_numero:
; Leemos un carácter a la vez hasta el salto de línea
mov rax, 0
mov rdi, 0
mov rdx, 1
syscall
cmp rax, 0 ; ya no hay más que leer
je fin_lectura
xor rax, rax
mov al, [rsi]
cmp al, 10
je fin_lectura
cmp al, "-"
je numero_negativo
; Revisamos que sea un dígito del "0" al "9"
mov rdx, "0"
revisar_digito:
cmp rax, rdx
je digito_valido
cmp rdx, "9"
je no_es_numero
add rdx, 1
jmp revisar_digito
digito_valido:
add rsi, 1
; Máximo 7 caracteres por número
mov rdx, rbx
add rdx, 7
cmp rsi, rdx
je fin_lectura
jmp leer_numero
fin_lectura:
; Si no tecleó ningún dígito, no es válido
cmp rsi, rbx
je no_es_numero
; Si ya leímos el segundo número, pasamos a convertir
mov rdx, num2
cmp rbx, rdx
je convertir
mov rbx, num2
mov rsi, prompt_n2
mov rdx, prompt_n2_len
jmp pedir_numero
convertir:
; Convertimos el primer número de ASCII a número
mov rsi, num1
xor rax, rax
convertir_num1:
xor rbx, rbx
mov bl, [rsi]
cmp bl, 10
je fin_num1
cmp bl, 0
je fin_num1
; Multiplicamos por 10 usando sumas
mov rdx, rax
add rax, rax ; x2
add rax, rax ; x4
add rax, rdx ; x5
add rax, rax ; x10
sub bl, "0"
add rax, rbx
add rsi, 1
jmp convertir_num1
fin_num1:
; Guardamos el primer número en rdi
mov rdi, rax
; Convertimos el segundo número de ASCII a número
mov rsi, num2
xor rax, rax
convertir_num2:
xor rbx, rbx
mov bl, [rsi]
cmp bl, 10
je fin_num2
cmp bl, 0
je fin_num2
mov rdx, rax
add rax, rax
add rax, rax
add rax, rdx
add rax, rax
sub bl, "0"
add rax, rbx
add rsi, 1
jmp convertir_num2
fin_num2:
; Revisamos qué opción eligió el usuario
mov bl, [opcion]
cmp bl, "1"
je suma
cmp bl, "2"
je resta
suma:
; rdi tiene el primer número y rax el segundo
mov rbx, rdi
add rbx, rax
jmp mostrar_resultado
resta:
mov rbx, rdi
; Restamos 1 a ambos hasta que alguno llegue a 0
; para saber cuál es mayor
mov rdx, rbx
mov rsi, rax
comparar:
cmp rdx, rsi
je resta_positiva
cmp rsi, 0
je resta_positiva
cmp rdx, 0
je resta_invalida
sub rdx, 1
sub rsi, 1
jmp comparar
resta_positiva:
sub rbx, rax
mostrar_resultado:
; El resultado queda en rbx, que no cambia con syscall
mov rax, 1
mov rdi, 1
mov rsi, mensaje_res
mov rdx, mensaje_res_len
syscall
convertir_ascii:
; Sumamos 1 al último dígito tantas veces como vale rbx
cmp rbx, 0
je imprimir_resultado
mov rsi, resultado
add rsi, 9
sumar_uno:
mov al, [rsi]
add al, 1
mov [rsi], al
cmp al, 58 ; 58 es el carácter que sigue después del "9"
je acarreo
sub rbx, 1
jmp convertir_ascii
acarreo:
; Si pasó de 9, vuelve a 0 y se suma 1 al dígito de la izquierda
mov al, "0"
mov [rsi], al
sub rsi, 1
jmp sumar_uno
imprimir_resultado:
; Nos saltamos los ceros de la izquierda
mov rsi, resultado
mov rdx, resultado
add rdx, 9
quitar_ceros:
mov al, [rsi]
cmp al, "0"
je revisar_ultimo
jmp imprimir
revisar_ultimo:
; El último dígito se imprime aunque sea 0
cmp rsi, rdx
je imprimir
add rsi, 1
jmp quitar_ceros
imprimir:
; Cantidad de caracteres: dígitos restantes + salto de línea
mov rdx, resultado
add rdx, 11
sub rdx, rsi
jmp escribir
opcion_invalida:
mov rsi, msg_error
mov rdx, msg_error_len
jmp escribir
numero_negativo:
mov rsi, msg_negativo
mov rdx, msg_negativo_len
jmp escribir
no_es_numero:
mov rsi, msg_no_numero
mov rdx, msg_no_numero_len
jmp escribir
resta_invalida:
mov rsi, msg_resta
mov rdx, msg_resta_len
escribir:
mov rax, 1
mov rdi, 1
syscall
; Salimos correctamente
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: