Skip to content

Instantly share code, notes, and snippets.

@pepinisillo
Last active April 11, 2025 05:21
Show Gist options
  • Save pepinisillo/040960716d8cb4da83d51bca0969ee81 to your computer and use it in GitHub Desktop.
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
/*
______ ____ ____ __ __
/\ _ \/\ _`\ /'\_/`\ /'___\/\ \\ \
\ \ \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