GNU/Linux xterm bash 186 views

📌 Demostración: Verificar si un número es par o impar en ARM64 Assembly

💻 Lenguajes de Interfaz en TECNM Campus ITT
👨‍💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/09

🎯 Descripción

Este programa verifica si un número es par o impar.
La implementación se realiza en:

Assembly ARM64 para RaspbianOS en Raspberry Pi

🔧 Compilación en Raspberry Pi (ARM64)

as impar_par.s -o impar_par.o  
ld impar_par.o -o impar_par

▶️ Ejecución

./impar_par

👀 Código fuente

🔗 Código fuente en Gist: Programa 23 Verificar si un número es par o impar 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/09                                                    | 
| • Descripción: Programa que verifica si un número es par               | 
|   o impar en Rust y Assembly ARM64 para RaspbianOS.                    | 
| • Demostración:                                                        |
|   https://asciinema.org/a/713447                                       |
| • Compilación (Raspberry Pi ARM64):                                    |  
|     as impar_par.s -o impar_par.o                                      |  
|     ld impar_par.o -o impar_par                                        |  
| • Ejecución: ./impar_par                                               |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                        

⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Rust •°•═══════

use std::process;

fn main() {
    let numero = 42;

    println!("Comprobando si el número es par o impar");
    println!("El número es: {}", numero);

    if numero % 2 == 0 {
        println!("El número es PAR");
    } else {
        println!("El número es IMPAR");
    }

    process::exit(0);
}

════════════════════•°• ☆ •°•══════════════════════════════
/*

/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */

.data
numero:     .quad   42              // El número a comprobar

msg_intro:  .ascii  "Comprobando si el número es par o impar\n"
msg_len_intro = . - msg_intro

num_msg:    .ascii  "El número es: "
num_len = . - num_msg

par_msg:    .ascii  "El número es PAR\n"
par_len = . - par_msg

impar_msg:  .ascii  "El número es IMPAR\n"
impar_len = . - impar_msg

newline:    .ascii  "\n"
nl_len = . - newline

buffer:     .space  20              // Buffer para convertir enteros a ASCII

.text
.global _start

_start:
    // Mostrar mensaje introductorio
    mov x0, #1                      // file descriptor: 1 es stdout
    ldr x1, =msg_intro              // puntero al mensaje
    ldr x2, =msg_len_intro          // longitud del mensaje
    mov x8, #64                     // syscall: write = 64
    svc #0                          // llamada al sistema

    // Mostrar "El número es: "
    mov x0, #1
    ldr x1, =num_msg
    ldr x2, =num_len
    mov x8, #64
    svc #0

    // Convertir y mostrar el número
    ldr x0, =numero
    ldr x0, [x0]
    bl int_to_ascii
    mov x0, #1
    ldr x1, =buffer
    mov x2, x9                      // x9 contiene la longitud del string
    mov x8, #64
    svc #0

    // Mostrar nueva línea
    mov x0, #1
    ldr x1, =newline
    ldr x2, =nl_len
    mov x8, #64
    svc #0

    // Comprobar si el número es par o impar
    ldr x0, =numero
    ldr x0, [x0]
    and x1, x0, #1                  // x1 = x0 & 1 (bit menos significativo)
    
    // Si x1 = 0, el número es par; si x1 = 1, el número es impar
    cbnz x1, es_impar

es_par:
    // Mostrar mensaje "El número es PAR"
    mov x0, #1
    ldr x1, =par_msg
    ldr x2, =par_len
    mov x8, #64
    svc #0
    b fin

es_impar:
    // Mostrar mensaje "El número es IMPAR"
    mov x0, #1
    ldr x1, =impar_msg
    ldr x2, =impar_len
    mov x8, #64
    svc #0

fin:
    // Salir del programa
    mov x0, #0                      // estado de salida: 0
    mov x8, #93                     // syscall: exit = 93
    svc #0

// Función para convertir un entero en x0 a ASCII en buffer
// Retorna en x9 la longitud del string
int_to_ascii:
    mov x10, #0         // contador de dígitos
    ldr x3, =buffer
    add x3, x3, #19     // apuntar al final del buffer
    mov x2, #10         // divisor = 10
    
    // Caso especial para 0
    cmp x0, #0
    bne convert_loop
    mov x4, #'0'        // ASCII de '0'
    strb w4, [x3]       // almacenar en buffer
    mov x9, #1          // longitud = 1
    b int_to_ascii_end

convert_loop:
    cbz x0, convert_end   // si x0 = 0, terminar
    udiv x1, x0, x2       // x1 = x0 / 10
    msub x4, x1, x2, x0   // x4 = x0 - (x1 * 10) = x0 % 10
    add x4, x4, #'0'      // convertir a ASCII
    strb w4, [x3], #-1    // guardar y mover el puntero
    add x10, x10, #1      // incrementar contador
    mov x0, x1            // x0 = x0 / 10
    b convert_loop

convert_end:
    add x3, x3, #1        // ajustar el puntero al primer dígito
    ldr x5, =buffer
    add x5, x5, #20
    sub x5, x5, x10       // x5 = dirección final en buffer
    
    // Copiar al principio del buffer
    ldr x6, =buffer
    mov x7, #0            // contador

copy_loop:
    cmp x7, x10
    beq copy_end
    ldrb w4, [x5, x7]     // cargar byte
    strb w4, [x6, x7]     // almacenar byte
    add x7, x7, #1        // incrementar contador
    b copy_loop

copy_end:
    mov x9, x10           // retornar longitud
    
int_to_ascii_end:
    ret