GNU/Linux xterm-256color bash 145 views

// ****************************************************************************
// * 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, &timespec)
// *  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, &timespec)
    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