/*
Autor: Victor Manuel Madrid Lugo
Fecha: 08/04/2025
Descripción: Divide dos números enteros ingresados por el usuario en Raspbian OS
Demostración: [https://asciinema.org/a/MbuJsSvJVMGrQL5RTiPRH8Dom]
*/
/*
#include <iostream>
using namespace std;
int main() {
double num1, num2, resultado;
cout << "Ingrese el primer número: ";
cin >> num1;
cout << "Ingrese el segundo número: ";
cin >> num2;
if (num2 == 0) {
cout << "Error: No se puede dividir entre cero." << endl;
} else {
resultado = num1 / num2;
cout << "El resultado de la división es: " << resultado << endl;
}
return 0;
}
*/
.section .data
msg1: .asciz "Ingrese el primer número (dividendo): "
msg2: .asciz "Ingrese el segundo número (divisor): "
msg3: .asciz "El resultado de la división es: "
msg_error: .asciz "Error: No se puede dividir por cero\n"
newline: .asciz "\n"
buffer: .skip 10 // Espacio para almacenar entrada del usuario
.section .text
.global _start
_start:
// Mostrar mensaje 1
mov x0, 1 // STDOUT
ldr x1, =msg1 // Dirección del mensaje
mov x2, 40 // Longitud del mensaje
mov x8, 64 // syscall write
svc 0 // Llamada al sistema
// Leer primer número (dividendo)
mov x0, 0 // STDIN
ldr x1, =buffer // Dirección del buffer
mov x2, 10 // Longitud máxima de entrada
mov x8, 63 // syscall read
svc 0 // Llamada al sistema
// Convertir a entero
ldr x0, =buffer
bl atoi // Llama a la función atoi
mov x20, x0 // Guarda el dividendo en x20
// Mostrar mensaje 2
mov x0, 1
ldr x1, =msg2
mov x2, 39 // Longitud del mensaje
mov x8, 64
svc 0
// Leer segundo número (divisor)
mov x0, 0
ldr x1, =buffer
mov x2, 10
mov x8, 63
svc 0
// Convertir a entero
ldr x0, =buffer
bl atoi
mov x21, x0 // Guarda el divisor en x21
// Verificar división por cero
cmp x21, #0
beq division_por_cero
// Dividir los números
udiv x22, x20, x21 // x22 = x20 / x21
// Mostrar resultado
mov x0, 1
ldr x1, =msg3
mov x2, 32 // Longitud del mensaje
mov x8, 64
svc 0
// Imprimir resultado como número
mov x0, x22
bl print_int
// Imprimir salto de línea
mov x0, 1
ldr x1, =newline
mov x2, 1 // Longitud de "\n"
mov x8, 64
svc 0
// Salir
mov x8, 93
mov x0, 0
svc 0
division_por_cero:
// Mostrar mensaje de error
mov x0, 1
ldr x1, =msg_error
mov x2, 34 // Longitud del mensaje de error
mov x8, 64
svc 0
// Salir con código de error
mov x8, 93
mov x0, 1 // Código de error
svc 0
// Función atoi: Convierte string en número
atoi:
mov x1, #0 // Inicializa resultado en 0
atoi_loop:
ldrb w2, [x0], #1 // Carga un byte y avanza al siguiente
cmp w2, #48 // Compara con '0' (ASCII)
blt atoi_done // Si es menor, termina
cmp w2, #57 // Compara con '9' (ASCII)
bgt atoi_done // Si es mayor, termina
sub w2, w2, #48 // Convierte ASCII a número (0-9)
mov x3, #10 // Carga el valor 10 en un registro
mul x1, x1, x3 // Multiplica el resultado por 10
add x1, x1, x2 // Suma el nuevo dígito
b atoi_loop
atoi_done:
mov x0, x1
ret
// Función print_int: Imprime un número en pantalla
print_int:
sub sp, sp, #16 // Reserva espacio en la pila
mov x1, sp // Usa la pila como buffer temporal
mov x2, #10 // Contador de caracteres
print_int_loop:
mov x3, #10 // Carga el valor 10 en un registro
udiv x4, x0, x3 // Divide por 10
msub x5, x4, x3, x0 // Resto: x5 = x0 - (x4 * x3)
add x5, x5, #48 // Convierte a ASCII
sub x2, x2, #1
strb w5, [x1, x2] // Guarda el carácter en el buffer
mov x0, x4 // Actualiza x0 con el cociente
cbnz x0, print_int_loop // Si no es cero, repite
// Imprimir número
mov x0, 1 // STDOUT
add x1, x1, x2 // Apunta al primer carácter válido
mov x3, #10 // Longitud original del buffer
sub x2, x3, x2 // Calcula longitud real (10 - posición)
mov x8, 64 // syscall write
svc 0
add sp, sp, #16 // Limpia la pila
ret