GNU/Linux xterm-256color bash 145 views

/*
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