Last active
April 11, 2025 05:21
-
-
Save pepinisillo/040960716d8cb4da83d51bca0969ee81 to your computer and use it in GitHub Desktop.
Programa 36 Potencia de un número, ingresando la base y la potencia por el usuario, mostrando resultado en terminal Código Assembly ARM64 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
/* | |
______ ____ ____ __ __ | |
/\ _ \/\ _`\ /'\_/`\ /'___\/\ \\ \ | |
\ \ \L\ \ \ \L\ \/\ \/\ \__/\ \ \\ \ | |
\ \ __ \ \ , /\ \ \__\ \ \ _``\ \ \\ \_ | |
\ \ \/\ \ \ \\ \\ \ \_/\ \ \ \L\ \ \__ ,__\ | |
\ \_\ \_\ \_\ \_\ \_\\ \_\ \____/\/_/\_\_/ | |
\/_/\/_/\/_/\/ /\/_/ \/_/\/___/ \/_/ | |
♡ ∩_∩ | |
(„• ֊ •„)♡ | |
| ̄U U ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄| | |
| • Lenguajes de Interfaz en TECNM Campus ITT | | |
| • Autor: Alejandro Suarez Sandoval | | |
| • Fecha: 2025/04/10 | | |
| • Descripción: Programa que calcula una potencia dada de una base dada | | |
| por el usuario en C y Assembly ARM64 para RaspbianOS. | | |
| • Demostración: | | |
| https://asciinema.org/a/714611 | | |
| • Compilación (Raspberry Pi ARM64): | | |
| as potencia.s -o potencia.o | | |
| ld potencia.o -o potencia | | |
| • Ejecución: ./potencia | | |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ | |
⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆ | |
═════════•°• Demostración Código en lenguaje C •°•═══════ | |
#include <stdio.h> | |
#include <math.h> | |
int main() { | |
double base, exponente; | |
printf("Ingrese la base: "); | |
scanf("%lf", &base); | |
printf("Ingrese el exponente: "); | |
scanf("%lf", &exponente); | |
double resultado = pow(base, exponente); | |
printf("Resultado: %.0f\n", resultado); | |
return 0; | |
} | |
════════════════════•°• ☆ •°•══════════════════════════════ | |
/* | |
/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆ | |
═════════════•°• Código en ARM64 Assembly •°•═════════════ */ | |
// Calculadora de Potencias en ARM64 Assembly para Linux | |
// Este programa calcula base^exponente, con ambos valores ingresados por el usuario | |
.global _start | |
// Garantizar alineamiento para los datos | |
.align 4 | |
.section .rodata | |
prompt_base: .ascii "Ingrese la base: " | |
.equ prompt_base_len, . - prompt_base | |
prompt_exp: .ascii "Ingrese el exponente: " | |
.equ prompt_exp_len, . - prompt_exp | |
result_msg: .ascii "Resultado: " | |
.equ result_msg_len, . - result_msg | |
newline: .ascii "\n" | |
.align 4 | |
.section .bss | |
.align 4 | |
buffer: .space 20 // Buffer para entrada de usuario | |
.align 3 | |
base: .quad 0 // Almacena la base | |
.align 3 | |
exponent: .quad 0 // Almacena el exponente | |
.align 3 | |
result: .quad 0 // Almacena el resultado | |
.align 4 | |
result_buffer: .space 20 // Buffer para convertir resultado a ASCII | |
.align 4 | |
.section .text | |
_start: | |
// Mostrar prompt para la base | |
mov x0, #1 // fd = STDOUT | |
ldr x1, =prompt_base // buffer = prompt_base | |
mov x2, prompt_base_len // length | |
mov x8, #64 // syscall = sys_write | |
svc #0 | |
// Leer la base del usuario | |
mov x0, #0 // fd = STDIN | |
ldr x1, =buffer // buffer donde almacenar la entrada | |
mov x2, #20 // count = tamaño máximo del buffer | |
mov x8, #63 // syscall = sys_read | |
svc #0 | |
// Convertir el string de la base a número | |
ldr x1, =buffer | |
bl string_to_int // Convertir entrada a entero | |
// Guardar la base | |
ldr x1, =base | |
str x0, [x1] | |
// Mostrar prompt para el exponente | |
mov x0, #1 // fd = STDOUT | |
ldr x1, =prompt_exp // buffer = prompt_exp | |
mov x2, prompt_exp_len // length | |
mov x8, #64 // syscall = sys_write | |
svc #0 | |
// Leer el exponente del usuario | |
mov x0, #0 // fd = STDIN | |
ldr x1, =buffer // buffer donde almacenar la entrada | |
mov x2, #20 // count = tamaño máximo del buffer | |
mov x8, #63 // syscall = sys_read | |
svc #0 | |
// Convertir el string del exponente a número | |
ldr x1, =buffer | |
bl string_to_int // Convertir entrada a entero | |
// Guardar el exponente | |
ldr x1, =exponent | |
str x0, [x1] | |
// Calcular la potencia | |
ldr x0, =base | |
ldr x0, [x0] // x0 = base | |
ldr x1, =exponent | |
ldr x1, [x1] // x1 = exponente | |
bl calculate_power // Calcula base^exponente | |
// Guardar el resultado | |
ldr x1, =result | |
str x0, [x1] | |
// Mostrar mensaje de resultado | |
mov x0, #1 // fd = STDOUT | |
ldr x1, =result_msg // buffer = result_msg | |
mov x2, result_msg_len // length | |
mov x8, #64 // syscall = sys_write | |
svc #0 | |
// Convertir resultado a string | |
ldr x0, =result | |
ldr x0, [x0] // x0 = resultado | |
ldr x1, =result_buffer // buffer para string | |
bl int_to_string // Convertir resultado a string | |
mov x2, x0 // x2 = longitud del string | |
// Mostrar el resultado | |
mov x0, #1 // fd = STDOUT | |
ldr x1, =result_buffer // buffer = result_buffer | |
mov x8, #64 // syscall = sys_write | |
svc #0 | |
// Mostrar salto de línea | |
mov x0, #1 // fd = STDOUT | |
ldr x1, =newline // buffer = newline | |
mov x2, #1 // length = 1 | |
mov x8, #64 // syscall = sys_write | |
svc #0 | |
// Salir del programa | |
mov x0, #0 // código de salida = 0 | |
mov x8, #93 // syscall = sys_exit | |
svc #0 | |
// Función para calcular base^exponente | |
// x0 = base, x1 = exponente | |
// Retorna: x0 = resultado | |
calculate_power: | |
// Guardar registros en la pila | |
stp x29, x30, [sp, #-16]! | |
stp x19, x20, [sp, #-16]! | |
// Guardar parámetros en registros no volátiles | |
mov x19, x0 // x19 = base | |
mov x20, x1 // x20 = exponente | |
// Casos especiales | |
cmp x20, #0 // Si exponente = 0 | |
b.ne not_zero_exp | |
mov x0, #1 // Retornar 1 | |
b power_done | |
not_zero_exp: | |
mov x0, #1 // Inicializar resultado = 1 | |
power_loop: | |
cmp x20, #0 // Mientras exponente > 0 | |
b.le power_done | |
mul x0, x0, x19 // resultado = resultado * base | |
sub x20, x20, #1 // exponente-- | |
b power_loop | |
power_done: | |
// Restaurar registros | |
ldp x19, x20, [sp], #16 | |
ldp x29, x30, [sp], #16 | |
ret | |
// Función para convertir string a entero | |
// x1 = puntero al buffer con el string | |
// Retorna: x0 = valor entero | |
string_to_int: | |
// Guardar registros | |
stp x29, x30, [sp, #-16]! | |
mov x0, #0 // Inicializar resultado = 0 | |
mov x2, #0 // Índice = 0 | |
str_to_int_loop: | |
ldrb w3, [x1, x2] // Cargar byte: w3 = buffer[i] | |
// Verificar fin de línea o entrada | |
cmp w3, #10 // Si es '\n' | |
b.eq str_to_int_done | |
cmp w3, #0 // Si es '\0' | |
b.eq str_to_int_done | |
// Verificar que sea un dígito | |
cmp w3, #'0' | |
b.lt str_to_int_next // Si < '0', ignorar | |
cmp w3, #'9' | |
b.gt str_to_int_next // Si > '9', ignorar | |
// Convertir ASCII a dígito | |
sub w3, w3, #'0' // w3 = valor numérico | |
// result = result * 10 + digit | |
mov x4, #10 | |
mul x0, x0, x4 // result *= 10 | |
add x0, x0, x3 // result += digit | |
str_to_int_next: | |
add x2, x2, #1 // i++ | |
b str_to_int_loop | |
str_to_int_done: | |
// Restaurar registros | |
ldp x29, x30, [sp], #16 | |
ret | |
// Función para convertir entero a string | |
// x0 = valor entero a convertir | |
// x1 = puntero al buffer donde almacenar el string | |
// Retorna: x0 = longitud del string | |
int_to_string: | |
// Guardar registros | |
stp x29, x30, [sp, #-16]! | |
stp x19, x20, [sp, #-16]! | |
mov x19, x0 // Guardar valor original | |
mov x20, x1 // Guardar puntero al buffer | |
// Caso especial: valor = 0 | |
cmp x19, #0 | |
b.ne not_zero | |
mov w2, #'0' // Carácter '0' | |
strb w2, [x20] // buffer[0] = '0' | |
mov w2, #0 // Fin de string | |
strb w2, [x20, #1] // buffer[1] = '\0' | |
mov x0, #1 // Longitud = 1 | |
b int_to_string_done | |
not_zero: | |
mov x2, #0 // Contador de dígitos | |
mov x3, x20 // Puntero temporal al buffer | |
// Convertir dígitos (en orden inverso) | |
int_to_string_loop: | |
cmp x19, #0 | |
b.eq int_to_string_reverse | |
mov x4, #10 | |
udiv x5, x19, x4 // x5 = valor / 10 | |
msub x6, x5, x4, x19 // x6 = valor % 10 (remainder) | |
add w6, w6, #'0' // Convertir a ASCII | |
strb w6, [x3], #1 // Almacenar en buffer y avanzar | |
mov x19, x5 // valor = valor / 10 | |
add x2, x2, #1 // contador++ | |
b int_to_string_loop | |
// Invertir el string (ya que los dígitos están al revés) | |
int_to_string_reverse: | |
mov x0, x2 // Guardar longitud en x0 | |
mov w4, #0 | |
strb w4, [x3] // Terminar string con '\0' | |
// Si longitud <= 1, no necesitamos invertir | |
cmp x2, #1 | |
b.le int_to_string_done | |
// Preparar para invertir: i=0, j=len-1 | |
mov x3, #0 // i = 0 | |
sub x4, x2, #1 // j = len - 1 | |
reverse_loop: | |
cmp x3, x4 // mientras i < j | |
b.ge int_to_string_done | |
// Intercambiar buffer[i] y buffer[j] | |
ldrb w5, [x20, x3] // w5 = buffer[i] | |
ldrb w6, [x20, x4] // w6 = buffer[j] | |
strb w6, [x20, x3] // buffer[i] = w6 | |
strb w5, [x20, x4] // buffer[j] = w5 | |
add x3, x3, #1 // i++ | |
sub x4, x4, #1 // j-- | |
b reverse_loop | |
int_to_string_done: | |
// Restaurar registros | |
ldp x19, x20, [sp], #16 | |
ldp x29, x30, [sp], #16 | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment