GNU/Linux xterm bash 143 views

📌 Demostración: Verificar si un número es negativo o positivo e imprimir resultado en la terminal en ARM64 Assembly

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

🎯 Descripción

Este programa muestra en la terminal si un número dado es negativo o positivo.
La implementación se realiza en:

Assembly ARM64 para RaspbianOS en Raspberry Pi

🔧 Compilación en Raspberry Pi (ARM64)

as negativo_positivo.s -o negativo_positivo.o  
ld negativo_positivo.o -o negativo_positivo 

▶️ Ejecución

./negativo_positivo

👀 Código fuente

🔗 Código fuente en Gist: Programa 12 Verifica si un numero es positivo o negativo y muestra 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/08                                              | 
| • Descripción: Programa que verifica si un numero es             | 
|   positivo o negativo en C y Assembly ARM64 para RaspbianOS.     | 
| • Demostración:                                                  |
|   https://asciinema.org/a/713328                                 |
| • Compilación (Raspberry Pi ARM64):                              |  
|     as negativo_positivo.s -o negativo_positivo.o                |  
|     ld negativo_positivo.o -o negativo_positivo                  |  
| • Ejecución: ./negativo_positivo                                 |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                        

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

#include <stdio.h>

int main() {
    int numero = -7; 
    
    printf("El número %d %s\n", 
           numero, 
           (numero >= 0) ? "es positivo" : "es negativo");
    
    return 0;
} 
════════════════════•°• ☆ •°•══════════════════════════════
/*

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

.data
// Mensajes
msg_resultado:  .asciz "El número "
msg_positivo:   .asciz " es positivo\n"
msg_negativo:   .asciz " es negativo\n"
numero:         .word -7          // Número a evaluar

// Buffer para convertir número a cadena
buffer:         .fill 12, 1, 0    // 12 bytes para almacenar el número como cadena

.text
.global _start

_start:
    // Cargar el número a verificar
    ldr x0, =numero
    ldr w1, [x0]
    
    // Convertir el número a cadena ASCII
    ldr x0, =buffer
    bl int_to_string
    
    // Imprimir "El número "
    mov x0, #1                  // stdout
    ldr x1, =msg_resultado
    mov x2, #10                 // longitud del mensaje
    mov x8, #64                 // syscall write
    svc #0
    
    // Imprimir el número
    mov x0, #1                  // stdout
    ldr x1, =buffer
    bl strlen                   // calcular longitud de la cadena
    mov x2, x0                  // longitud en x2
    mov x8, #64                 // syscall write
    svc #0
    
    // Cargar el número original para comparar
    ldr x0, =numero
    ldr w1, [x0]
    cmp w1, #0
    
    // Seleccionar el mensaje apropiado
    b.ge imprimir_positivo
    
imprimir_negativo:
    mov x0, #1                  // stdout
    ldr x1, =msg_negativo
    mov x2, #13                 // longitud del mensaje
    b imprimir
    
imprimir_positivo:
    mov x0, #1                  // stdout
    ldr x1, =msg_positivo
    mov x2, #12                 // longitud del mensaje
    
imprimir:
    mov x8, #64                 // syscall write
    svc #0
    
    // Salir del programa
    mov x0, #0                  // código de retorno
    mov x8, #93                 // syscall exit
    svc #0

// Función para convertir entero a cadena (versión corregida)
// x0: dirección del buffer
// w1: número a convertir
int_to_string:
    mov x2, x0                  // dirección del buffer
    mov w3, #10                 // divisor
    mov w4, #0                  // contador de dígitos
    
    // Manejar el caso especial de 0
    cmp w1, #0
    b.eq handle_zero
    
    // Manejar números negativos (CORRECCIÓN PRINCIPAL)
    cmp w1, #0
    b.gt positive_number
    mov w5, #'-'                // almacenar signo negativo
    strb w5, [x2], #1           // guardar en buffer y avanzar puntero
    neg w1, w1                  // convertir a positivo
    add w4, w4, #1              // incrementar contador
    
positive_number:
    // Convertir cada dígito
convert_loop:
    udiv w5, w1, w3             // dividir por 10
    msub w6, w5, w3, w1         // obtener residuo (dígito)
    add w6, w6, #'0'            // convertir a ASCII
    strb w6, [x2], #1           // guardar en buffer
    add w4, w4, #1              // incrementar contador
    mov w1, w5                  // actualizar número
    cmp w1, #0                  // verificar si terminamos
    b.ne convert_loop
    
    // Invertir los dígitos en el buffer (excepto el signo negativo si existe)
    sub x2, x2, #1              // apuntar al último carácter
    ldr x5, =buffer
    ldrb w6, [x5]               // verificar primer carácter
    cmp w6, #'-'
    b.eq signed_number
    // Para números positivos
    add x5, x5, x4
    sub x5, x5, #1
    b reverse_loop
    
signed_number:
    // Para números negativos, no invertir el signo -
    add x0, x0, #1              // saltar el signo -
    sub x4, x4, #1              // ajustar contador
    add x5, x5, x4
    add x5, x5, #1              // ajustar posición final
    
reverse_loop:
    cmp x0, x2
    b.ge end_reverse
    ldrb w6, [x0]               // intercambiar caracteres
    ldrb w7, [x2]
    strb w7, [x0], #1
    strb w6, [x2], #-1
    b reverse_loop
    
handle_zero:
    mov w5, #'0'
    strb w5, [x2]
    mov w4, #1
    ret
    
end_reverse:
    ret

// Función para calcular longitud de cadena
// x1: dirección de la cadena
// retorna longitud en x0
strlen:
    mov x0, #0
strlen_loop:
    ldrb w2, [x1, x0]
    cbz w2, strlen_end
    add x0, x0, #1
    b strlen_loop
strlen_end:
    ret