// ****************************************************************************
// * Lenguajes de Interfaz en TECNM Campus ITT
// * Nombre del archivo: practica.s
// * Descripción: Programa que genera un numero aleatorio entre 0 y 5
// * Autor: [America Fernanda Nevarez de la Cruz]
// * Fecha: [2025-04-08]
// * Plataforma: Raspberry Pi OS (64 bits)
// * Demostración: [https://asciinema.org/a/lPw0O3u2U8LG3VM0Hn9DH98LP]
// ****************************************************************************
// ****************************************************************************
// * Codigo equivalente en RUBY
// * msg = "Numero aleatorio (0-5): "
// * len_msg = msg.length
// * nl = "\n"
// * len_nl = nl.length
// * timespec = [0, 0] # struct timespec: tv_sec (8) + tv_nsec (8)
// * def _start
// * Llamada a clock_gettime(CLOCK_REALTIME, ×pec)
// * clock_realtime = 0 # CLOCK_REALTIME
// * timespec = [0, 0]
// * En Ruby, no hay syscalls directas como en ensamblador.
// * La siguiente línea es una aproximación, ya que no existe clock_gettime en Ruby Standard library.
// * nsec = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
// * Leer nanosegundos desde timespec
// * x1 = nsec # x1 = tv_nsec
// * x2 = 6 # divisor para rango 0-5
// * x3 = x1 / x2 # x3 = x1 / 6
// * x4 = x1 % x2 # x4 = x1 - (x3 * x2) = x1 % 6
// * Mostrar mensaje
// * print_msg("Numero aleatorio (0-5): ")
// * Mostrar número en x4
// * print_int(x4)
// * Mostrar nueva línea
// * print_msg("\n")
// * Salir
// * exit 0
// * end
// * def print_msg(message) # x0: ptr, x1: len
// * print message
// * print message
// * end
// * def print_int(number) # x0: número
// * si el número es 0, imprimir '0'
// * if number == 0
// * print '0'
// * print '0'
// * else
// * digits = []
// * temp_num = number
// * while temp_num != 0
// * digit = temp_num % 10
// * convertir a ASCII
// * digits.unshift(digit.chr)
// * temp_num /= 10
// * end
// * print digits.join('')
// * print digits.join('')
// * end
// * end
// * _start
// ****************************************************************************
.section .data
msg: .ascii "Numero aleatorio (0-5): "
len_msg = . - msg
nl: .ascii "\n"
len_nl = . - nl
.section .bss
timespec: .skip 16 // struct timespec: tv_sec (8) + tv_nsec (8)
.section .text
.global _start
_start:
// Llamada a clock_gettime(CLOCK_REALTIME, ×pec)
mov x0, #0 // CLOCK_REALTIME
ldr x1, =timespec
mov x8, #113 // syscall clock_gettime
svc #0
// Leer nanosegundos desde timespec
ldr x1, [x1, #8] // x1 = tv_nsec
mov x2, #6 // divisor para rango 0-5
udiv x3, x1, x2 // x3 = x1 / 6
msub x4, x3, x2, x1 // x4 = x1 - (x3 * x2) = x1 % 6
// Mostrar mensaje
ldr x0, =msg
mov x1, #len_msg
bl print_msg
// Mostrar número en x4
mov x0, x4
bl print_int
// Mostrar nueva línea
ldr x0, =nl
mov x1, #len_nl
bl print_msg
// Salir
mov x8, #93
mov x0, #0
svc #0
// -----------------------------
print_msg: // x0: ptr, x1: len
mov x2, x1
mov x1, x0
mov x0, #1
mov x8, #64
svc #0
ret
// -----------------------------
print_int: // x0: número
sub sp, sp, #16 // reservar espacio
mov x1, x0 // x1 = número
mov x2, sp // puntero al buffer (de atrás hacia adelante)
// si el número es 0, imprimir '0'
cmp x1, #0
b.ne int_convert
mov w3, #'0'
strb w3, [x2]
mov x2, #1
b int_print
int_convert:
mov x3, #10
mov x4, x2 // x4 = ptr final
int_loop:
udiv x5, x1, x3 // x5 = x1 / 10
msub x6, x5, x3, x1 // x6 = x1 - (x5 * 10) => dígito
add x6, x6, #'0' // convertir a ASCII
sub x4, x4, #1
strb w6, [x4]
mov x1, x5
cmp x1, #0
b.ne int_loop
// Calcular longitud y mostrar
sub x2, x2, x4 // x2 = número de bytes
mov x1, x4 // x1 = puntero a inicio del número
int_print:
mov x0, #1
mov x8, #64
svc #0
add sp, sp, #16
ret