GNU/Linux
•
xterm-256color
•
bash
133 views
/*
Autor: Victor Manuel Madrid Lugo
Fecha: 07/04/2025
Descripción: Ordena 3 números ingresados por el usuario de mayor a menor
Demostración: [https://asciinema.org/a/YDn9TXoKzFgoPNE16dTiXcQX0]
*/
/*
# Ordenamiento de 3 números en Python (mayor a menor)
# Solicitar números al usuario
num1 = int(input("Ingrese el primer número: "))
num2 = int(input("Ingrese el segundo número: "))
num3 = int(input("Ingrese el tercer número: "))
# Ordenamiento (usando comparaciones simples)
if num1 < num2:
num1, num2 = num2, num1 # Intercambiar si están en orden incorrecto
if num1 < num3:
num1, num3 = num3, num1
if num2 < num3:
num2, num3 = num3, num2
# Mostrar resultado
print(f"Números ordenados: {num1}, {num2}, {num3}")
*/
.section .data
msg_prompt1: .asciz "Ingrese el primer número: "
msg_prompt2: .asciz "Ingrese el segundo número: "
msg_prompt3: .asciz "Ingrese el tercer número: "
msg_result: .asciz "Números ordenados: "
comma_space: .asciz ", "
newline: .asciz "\n"
buffer: .skip 21 // Buffer para entrada
num_buffer: .skip 21 // Buffer para conversión numérica
.section .text
.global _start
_start:
// =============================================
// Leer los tres números del usuario
// =============================================
// Primer número
mov x0, #1 // stdout
ldr x1, =msg_prompt1 // mensaje
mov x2, #27 // longitud
mov x8, #64 // syscall write
svc #0
mov x0, #0 // stdin
ldr x1, =buffer // buffer de entrada
mov x2, #21 // tamaño máximo
mov x8, #63 // syscall read
svc #0
ldr x0, =buffer // convertir a número
bl atoi
mov x19, x0 // guardar en x19
// Segundo número
mov x0, #1
ldr x1, =msg_prompt2
mov x2, #27
mov x8, #64
svc #0
mov x0, #0
ldr x1, =buffer
mov x2, #21
mov x8, #63
svc #0
ldr x0, =buffer
bl atoi
mov x20, x0 // guardar en x20
// Tercer número
mov x0, #1
ldr x1, =msg_prompt3
mov x2, #27
mov x8, #64
svc #0
mov x0, #0
ldr x1, =buffer
mov x2, #21
mov x8, #63
svc #0
ldr x0, =buffer
bl atoi
mov x21, x0 // guardar en x21
// =============================================
// Ordenar los números (x19, x20, x21)
// =============================================
// Comparar x19 y x20
cmp x19, x20
b.ge comp1_ok
// Intercambiar si x19 < x20
mov x22, x19
mov x19, x20
mov x20, x22
comp1_ok:
// Comparar x19 y x21
cmp x19, x21
b.ge comp2_ok
// Intercambiar si x19 < x21
mov x22, x19
mov x19, x21
mov x21, x22
comp2_ok:
// Comparar x20 y x21
cmp x20, x21
b.ge comp3_ok
// Intercambiar si x20 < x21
mov x22, x20
mov x20, x21
mov x21, x22
comp3_ok:
// =============================================
// Mostrar resultados
// =============================================
// Imprimir "Números ordenados: "
mov x0, #1
ldr x1, =msg_result
mov x2, #20 // longitud del mensaje
mov x8, #64
svc #0
// Imprimir primer número (x19)
ldr x0, =num_buffer
mov x1, x19
bl int_to_str // convertir a string
mov x2, x0 // longitud del número
mov x0, #1 // stdout
ldr x1, =num_buffer // buffer con el número
mov x8, #64 // write
svc #0
// Imprimir ", "
mov x0, #1
ldr x1, =comma_space
mov x2, #2
mov x8, #64
svc #0
// Imprimir segundo número (x20)
ldr x0, =num_buffer
mov x1, x20
bl int_to_str
mov x2, x0
mov x0, #1
ldr x1, =num_buffer
mov x8, #64
svc #0
// Imprimir ", "
mov x0, #1
ldr x1, =comma_space
mov x2, #2
mov x8, #64
svc #0
// Imprimir tercer número (x21)
ldr x0, =num_buffer
mov x1, x21
bl int_to_str
mov x2, x0
mov x0, #1
ldr x1, =num_buffer
mov x8, #64
svc #0
// Imprimir newline
mov x0, #1
ldr x1, =newline
mov x2, #1
mov x8, #64
svc #0
// =============================================
// Terminar programa
// =============================================
mov x0, #0 // código de salida
mov x8, #93 // syscall exit
svc #0
// =============================================
// Función atoi: Convierte string a entero
// Entrada: x0 = dirección del string
// Salida: x0 = número convertido
// =============================================
atoi:
mov x1, #0 // resultado
mov x3, #10 // base 10
mov x4, #0 // indicador negativo
// Verificar signo negativo
ldrb w2, [x0], #1
cmp w2, #'-'
b.ne atoi_loop
mov x4, #1
ldrb w2, [x0], #1
atoi_loop:
// Verificar fin de string
cmp w2, #10 // '\n'
b.eq atoi_done
cbz w2, atoi_done // '\0'
// Verificar que es dígito
cmp w2, #'0'
b.lt atoi_error
cmp w2, #'9'
b.gt atoi_error
// Convertir y acumular
sub w2, w2, #'0'
mul x1, x1, x3
add x1, x1, x2
// Siguiente carácter
ldrb w2, [x0], #1
b atoi_loop
atoi_done:
// Aplicar signo si es negativo
cbz x4, atoi_positive
neg x1, x1
atoi_positive:
mov x0, x1
ret
atoi_error:
mov x0, #0
ret
// =============================================
// Función int_to_str: Convierte entero a string
// Entrada: x0 = buffer, x1 = número
// Salida: x0 = longitud del string
// =============================================
int_to_str:
mov x2, #10 // base 10
mov x3, #0 // contador de dígitos
mov x4, x0 // guardar dirección inicial
// Manejar caso especial de 0
cbz x1, zero_case
// Manejar negativos
cmp x1, #0
b.gt positive
neg x1, x1
mov w5, #'-'
strb w5, [x4], #1
add x3, x3, #1
positive:
// Convertir dígitos (en orden inverso)
convert_loop:
udiv x5, x1, x2 // x5 = x1 / 10
msub x6, x5, x2, x1 // x6 = x1 % 10
add x6, x6, #'0' // convertir a ASCII
strb w6, [x4], #1 // almacenar dígito
add x3, x3, #1 // incrementar contador
mov x1, x5 // x1 = cociente
cbnz x1, convert_loop // repetir si no es cero
// Invertir los dígitos en el buffer
sub x4, x4, #1 // x4 apunta al último dígito
mov x5, x0 // x5 apunta al inicio
add x6, x0, x3 // x6 apunta después del último dígito
sub x6, x6, #1 // x6 apunta al último dígito
// Si es negativo, saltar el signo -
cbz x4, no_negative // x4 = 0 si no hay dígitos (no debería pasar)
ldrb w7, [x5]
cmp w7, #'-'
b.ne reverse_loop
add x5, x5, #1 // saltar el signo -
reverse_loop:
cmp x5, x6
b.ge reverse_done
ldrb w7, [x5] // intercambiar caracteres
ldrb w8, [x6]
strb w8, [x5], #1
strb w7, [x6], #-1
b reverse_loop
zero_case:
mov w5, #'0'
strb w5, [x4]
mov x0, #1
ret
no_negative:
// Caso de error, no debería ocurrir
mov x0, #0
ret
reverse_done:
mov x0, x3 // devolver longitud
ret