Created
April 8, 2025 04:43
-
-
Save Alex-JAML/1f7738fdb73059c865d031eaa68f3658 to your computer and use it in GitHub Desktop.
Codigo Assembly ARM64 Hola Mundo para RaspbianOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* --------------------------------------------------------------------------------- | |
* Lenguajes de Interfaz en TECNM Campus ITT | |
* Autor: [Jorge Alejandro Martinez Lopez] | |
* Fecha: [2025-04-07] | |
* Descripción: Este programa imprime la tabla de multiplicar del 12 (del 12 x 1 al 12 x 12), | |
* mostrando cada línea en el formato "12 x b = c". | |
* Demostración: [ASCIINEMA.ORG/.....] | |
* --------------------------------------------------------------------------------- | |
*/ | |
/* | |
* ---------------------------------------------- | |
* C# "Tabla del 12" para Desarrolladores Embebidos (Referencia) | |
* ---------------------------------------------- | |
* using System; | |
* | |
* class Program { | |
* static void Main() { | |
* Console.WriteLine("Tabla del 12:"); | |
* for (int i = 1; i <= 12; i++) { | |
* Console.WriteLine("12 x {0} = {1}", i, 12 * i); | |
* } | |
* } | |
* } | |
*/ | |
.global _start | |
/* -------------------------------------------------------------------- | |
* Sección de datos: Constantes y mensajes fijos | |
* -------------------------------------------------------------------- | |
*/ | |
.section .data | |
prefix: .ascii "12x" // Prefijo fijo | |
prefix_len = . - prefix // Longitud de "12x" | |
infix: .ascii " = " // Texto intermedio | |
infix_len = . - infix // Longitud de " = " | |
newline: .ascii "\n" // Salto de línea | |
newline_len = . - newline // Longitud de "\n" | |
/* -------------------------------------------------------------------- | |
* Sección BSS: Buffer para formar la línea de salida. | |
* Se reserva 64 bytes. | |
* -------------------------------------------------------------------- | |
*/ | |
.section .bss | |
.lcomm outBuffer, 64 | |
/* -------------------------------------------------------------------- | |
* Sección de texto: Código principal y subrutinas | |
* -------------------------------------------------------------------- | |
*/ | |
.section .text | |
_start: | |
// x19 = multiplicador (i) comienza en 1 | |
mov x19, #1 | |
print_loop: | |
// Si se han impreso 12 líneas, salir | |
cmp x19, #13 | |
beq exit_program | |
// Calcular el producto: x20 = 12 * (valor en x19) | |
mov x0, x19 // x0 = multiplicador | |
mov x1, #12 | |
mul x20, x0, x1 // x20 = producto | |
// Se arma la línea en outBuffer: | |
// outBuffer = "12x" + [multiplicador] + " = " + [producto] + "\n" | |
ldr x9, =outBuffer // x9 apunta al buffer (se reinicia cada iteración) | |
// 1. Copiar el prefijo "12x" (la subrutina ya incrementa x9) | |
ldr x1, =prefix // x1 apunta a "12x" | |
mov x2, prefix_len // longitud = 3 | |
bl memcpy_copy | |
// 2. Convertir el multiplicador (1 o 2 dígitos) a cadena | |
// Se pasa el número en x0 y el destino en x1 (x1 se conserva como x9 actual) | |
mov x0, x19 // multiplicador en x0 | |
mov x1, x9 // x1 = posición actual en el buffer | |
bl convert_mult // devuelve en x2 la cantidad de dígitos escritos | |
add x9, x9, x2 // Se avanza x9 según cantidad de dígitos escritos | |
// 3. Copiar el intermedio " = " | |
ldr x1, =infix | |
mov x2, infix_len | |
bl memcpy_copy | |
// 4. Convertir el producto (hasta 3 dígitos) a cadena | |
mov x0, x20 // Producto en x0 | |
mov x1, x9 // x1 = posición actual en el buffer | |
bl convert_product // Convierte y devuelve la cantidad de dígitos en x2 | |
add x9, x9, x2 // Avanza el buffer | |
// 5. Copiar el salto de línea "\n" | |
ldr x1, =newline | |
mov x2, newline_len | |
bl memcpy_copy | |
// Calcular la longitud total de la línea: (x9 - outBuffer) | |
ldr x3, =outBuffer | |
sub x3, x9, x3 | |
// Realizar la llamada al sistema para escribir en stdout (fd 1) | |
mov x0, #1 // stdout | |
ldr x1, =outBuffer // puntero al buffer | |
mov x2, x3 // longitud de la línea | |
mov x8, #64 // syscall: write | |
svc #0 | |
// Incrementar el multiplicador e iterar | |
add x19, x19, #1 | |
b print_loop | |
exit_program: | |
// Salir con código 0 | |
mov x0, #0 | |
mov x8, #93 // syscall: exit | |
svc #0 | |
/* -------------------------------------------------------------------- | |
* Subrutina: memcpy_copy | |
* Copia x2 bytes desde la dirección en x1 al destino apuntado por x9. | |
* Nota: Esta subrutina avanza el puntero x9 internamente. | |
* -------------------------------------------------------------------- | |
* Entradas: | |
* x1 = puntero a la fuente | |
* x2 = número de bytes a copiar | |
* x9 = puntero al destino (se actualiza internamente) | |
* Salida: | |
* x9 apunta al final del bloque copiado. | |
* -------------------------------------------------------------------- | |
*/ | |
memcpy_copy: | |
cmp x2, #0 | |
beq memcpy_done | |
copy_loop: | |
ldrb w3, [x1], #1 // Cargar byte y post-incrementar x1 | |
strb w3, [x9], #1 // Almacenar byte y post-incrementar x9 | |
subs x2, x2, #1 | |
bne copy_loop | |
memcpy_done: | |
ret | |
/* -------------------------------------------------------------------- | |
* Subrutina: convert_mult | |
* Convierte el número en x0 (multiplicador, de 1 a 12) a una cadena ASCII. | |
* Se asume que el número tiene 1 o 2 dígitos. | |
* Entrada: | |
* x0 = número a convertir (multiplicador) | |
* x1 = puntero al buffer destino donde se escribirá la cadena | |
* Salida: | |
* x2 = cantidad de dígitos escritos (1 o 2) | |
* -------------------------------------------------------------------- | |
*/ | |
convert_mult: | |
cmp x0, #10 | |
blt cm_one_digit | |
// Caso de dos dígitos: | |
mov x3, #10 | |
udiv x4, x0, x3 // x4 = dígito de las decenas | |
msub x5, x4, x3, x0 // x5 = dígito de las unidades (x0 - x4*10) | |
// Convertir dígito de las decenas a ASCII usando x10 como temporal | |
mov w10, w4 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
add x1, x1, #1 | |
// Convertir dígito de las unidades a ASCII | |
mov w10, w5 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
mov x2, #2 | |
ret | |
cm_one_digit: | |
add w0, w0, #'0' | |
strb w0, [x1] | |
mov x2, #1 | |
ret | |
/* -------------------------------------------------------------------- | |
* Subrutina: convert_product | |
* Convierte el número en x0 (producto, máximo 144) a su representación ASCII. | |
* Maneja casos de 1, 2 o 3 dígitos. | |
* Entrada: | |
* x0 = número a convertir (producto) | |
* x1 = puntero al buffer destino donde se escribirá la cadena | |
* Salida: | |
* x2 = cantidad de dígitos escritos | |
* -------------------------------------------------------------------- | |
*/ | |
convert_product: | |
cmp x0, #10 | |
blt cp_one_digit | |
cmp x0, #100 | |
blt cp_two_digit | |
// Caso de tres dígitos: | |
mov x3, #100 | |
udiv x4, x0, x3 // x4 = dígito de las centenas | |
msub x5, x4, x3, x0 // x5 = residuo (parte de decenas y unidades) | |
mov x6, #10 | |
udiv x7, x5, x6 // x7 = dígito de las decenas | |
msub x8, x7, x6, x5 // x8 = dígito de las unidades | |
// Escribir dígito de las centenas | |
mov w10, w4 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
add x1, x1, #1 | |
// Escribir dígito de las decenas | |
mov w10, w7 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
add x1, x1, #1 | |
// Escribir dígito de las unidades | |
mov w10, w8 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
mov x2, #3 | |
ret | |
cp_two_digit: | |
// Caso de dos dígitos: | |
mov x3, #10 | |
udiv x4, x0, x3 // x4 = dígito de las decenas | |
msub x5, x4, x3, x0 // x5 = dígito de las unidades | |
// Escribir dígito de las decenas | |
mov w10, w4 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
add x1, x1, #1 | |
// Escribir dígito de las unidades | |
mov w10, w5 | |
add w10, w10, #'0' | |
strb w10, [x1] | |
mov x2, #2 | |
ret | |
cp_one_digit: | |
// Caso de un dígito: | |
add w0, w0, #'0' | |
strb w0, [x1] | |
mov x2, #1 | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fue agradable su estilo de bloque para documentar el codigo yo le sumaria arriba el "Asciinema" y poner un poco mas de cometnarios