GNU/Linux
•
xterm-256color
•
bash
145 views
/*
Autor: Victor Manuel Madrid Lugo
Fecha: 08/04/2025
Descripción: Imprime la fecha actual del sistema
Demostración: [https://asciinema.org/a/9fllKL8vwWmKhAgTISz9lV5aW]
*/
/*
Equivalente en Python:
import time
from datetime import datetime
def main():
try:
# Obtener el tiempo actual
current_time = time.time()
# Convertir a formato legible
date_string = datetime.fromtimestamp(current_time).strftime('%d/%m/%Y %H:%M:%S')
# Imprimir el resultado
print(f"Fecha actual: {date_string}")
except Exception as e:
print(f"Error al obtener la fecha: {e}")
if __name__ == "__main__":
main()
*/
.global _start
.data
msg_fecha: .asciz "Fecha actual: "
msg_fecha_len = . - msg_fecha
buffer: .space 128
formato: .asciz "%d/%m/%Y %H:%M:%S"
formato_len = . - formato
error_msg: .asciz "Error al obtener la fecha\n"
error_msg_len = . - error_msg
newline: .asciz "\n"
.text
_start:
// Reservar espacio para la estructura timespec (tiempo actual)
sub sp, sp, #32
mov x0, sp // x0 = puntero a timespec
// Llamar a clock_gettime(CLOCK_REALTIME, timespec)
mov x8, #113 // syscall clock_gettime
mov x1, x0 // x1 = puntero a timespec
mov x0, #0 // CLOCK_REALTIME
svc 0
// Verificar error
cmp x0, #0
bne error
// Cargar el tiempo (time_t) desde la estructura timespec
ldr x0, [sp] // x0 = time_t (segundos desde epoch)
// Reservar espacio para la estructura tm
sub sp, sp, #64
// Llamar a localtime_r(time_t, struct tm *)
// Necesitamos usar la syscall mmap para conseguir memoria para la función
mov x8, #222 // syscall mmap
mov x0, #0 // NULL (dejar que el kernel decida la dirección)
mov x1, #4096 // tamaño de página
mov x2, #3 // PROT_READ | PROT_WRITE
mov x3, #0x22 // MAP_PRIVATE | MAP_ANONYMOUS
mov x4, #-1 // fd = -1
mov x5, #0 // offset = 0
svc 0
// Verificar error en mmap
cmp x0, #0
ble error
// Guardar la dirección de memoria asignada
mov x19, x0
// Preparar parámetros para syscall nanosleep (para simular localtime)
// En sistemas reales se usaría la biblioteca libc para localtime
ldr x0, [sp, #64] // Cargar time_t
// Imprime el mensaje "Fecha actual: "
mov x0, #1 // stdout
ldr x1, =msg_fecha
mov x2, msg_fecha_len
mov x8, #64 // syscall write
svc 0
// Como no podemos llamar a funciones de biblioteca, simulemos la fecha
// con el valor bruto de epoch
// Convertir segundos desde epoch a tiempo legible
// Nota: Normalmente usaríamos strftime, pero en puro assembly
// implementaremos algo básico
ldr x0, [sp, #64] // Cargar time_t
// Imprimir los segundos desde epoch como texto
bl print_int
// Imprimir nueva línea
mov x0, #1
ldr x1, =newline
mov x2, #1
mov x8, #64
svc 0
// Liberar memoria asignada con mmap
mov x8, #215 // syscall munmap
mov x0, x19 // dirección a liberar
mov x1, #4096 // tamaño
svc 0
// Limpieza y salida
add sp, sp, #96 // restaurar pila
mov x0, #0 // código de salida exitoso
mov x8, #93 // syscall exit
svc 0
error:
// Imprimir mensaje de error
mov x0, #2 // stderr
ldr x1, =error_msg
mov x2, error_msg_len
mov x8, #64 // syscall write
svc 0
// Salir con código de error
mov x0, #1 // código de error
mov x8, #93 // syscall exit
svc 0
// Función para imprimir un entero (simplificada)
print_int:
// Guardar registros
sub sp, sp, #48
str x19, [sp, #0]
str x20, [sp, #8]
str x21, [sp, #16]
str x22, [sp, #24]
str x30, [sp, #32] // Link register
mov x19, x0 // Guardar el valor a imprimir
// Asignar buffer en la pila
sub sp, sp, #32 // 32 bytes para el buffer
mov x21, sp // x21 = buffer
// Manejar caso especial de 0
cmp x19, #0
bne convert_loop
mov w22, #'0'
strb w22, [x21]
mov x20, #1 // Longitud = 1
b print_digits
convert_loop:
mov x20, #0 // x20 = contador de dígitos
mov x22, x19 // x22 = valor a convertir
// Obtener dígitos en orden inverso
loop:
cmp x22, #0
beq reverse_digits
mov x0, x22
mov x1, #10
udiv x2, x0, x1 // x2 = x0 / 10
msub x3, x2, x1, x0 // x3 = x0 - (x2 * 10) = x0 % 10
add w3, w3, #'0' // Convertir a ASCII
strb w3, [x21, x20] // Guardar en buffer
add x20, x20, #1 // Incrementar contador
mov x22, x2 // Continuar con el cociente
b loop
reverse_digits:
// Invertir los dígitos (si hay más de 1)
cmp x20, #1
ble print_digits
mov x0, #0 // índice inicio
sub x1, x20, #1 // índice fin
reverse_loop:
cmp x0, x1
bge print_digits
ldrb w2, [x21, x0] // cargar byte de inicio
ldrb w3, [x21, x1] // cargar byte de fin
strb w3, [x21, x0] // intercambiar
strb w2, [x21, x1]
add x0, x0, #1
sub x1, x1, #1
b reverse_loop
print_digits:
// Agregar terminador nulo por seguridad
mov w22, #0
strb w22, [x21, x20]
// Imprimir los dígitos
mov x0, #1 // stdout
mov x1, x21 // buffer
mov x2, x20 // longitud
mov x8, #64 // syscall write
svc 0
// Limpiar y restaurar
add sp, sp, #32 // liberar buffer
ldr x19, [sp, #0]
ldr x20, [sp, #8]
ldr x21, [sp, #16]
ldr x22, [sp, #24]
ldr x30, [sp, #32] // Link register
add sp, sp, #48
ret