Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Constantes y Valores Inmediatos en ASM

–El Problema de los Números Mágicos–

algunas constantes

Antes de exponer el problema de las constantes a la hora de programar en ASM hay que dejar claro que es una constante. El simple sentido común nos dice que una constante es algo que no cambia, que siempre permanece igual como el lugar donde se encuentra el mar o el comportamiento de la gente en internet. Para los matemáticos una constante es una cantidad que no cambia, aunque ellos las separan en constantes absolutas y relativas. Las constantes absolutas mantienen su valor en todas partes en las que aparecen como es el caso de PI = 3.1415927… o e = 2.71828 o el valor de la velocidad de la luz a traves del vacío. Las constantes relativas toman un valor para ese cálculo en particular pero no cambian a traves de este como es el caso del coeficiente constante en una función polinomial para los de arte digital que no me entendieron un coeficiente constante es el número grande que está a la izquierda de la letra equis, el número chiquito que está a la derecha arriba se llama exponente y si está abajo es un subíndice.

Ahora vamos a la programación. En computación una constante es también una cantidad que no cambia. Sin embargo hay dos clases diferentes de constantes que normalmente pueden encontrarse en programas computacionales de cualquier lenguaje: Las Constantes Congeladas y los Valores Inmediatos.

Constantes Congeladas

No es realmente el nombre técnico pero así es como les llamo. Como ya han de saber a estas alturas, y si no lean el blog desde el principio, la computadora almacena valores en celdas de 8 bits llamadas bytes que pueden almacenar cantidades entre 0 y 255. Para valores mayores se combinan estas celdas o se usan registros de CPU de mayor ancho. Estas celdas pueden cambiar el valor que almacenan si se los ordenamos con las instrucciones de transferencia y manipulación de datos como por ejemplo MOV. Algunos compiladores tienen la directiva CONST que impide que las celdas que han sido declaradas constantes cambien su contenido luego de haber sido inicializadas mandando un mensaje de error. Hasta ahora solo he visto esta clase de directivas en compiladores de C y no en ASM. No se exactamente el porqué un programador querría declarar como de solo lectura una localidad de memoria pudiendo recurrir a los valores inmediatos.

Valores Inmediatos

Este término es muy de ensamblador, pero es visto ampliamente en todos los lenguajes. Normalmente un CPU toma los valores que procesa de las celdas de memoria, puertos de entrada y salida o de otros de sus propios registros de procesador en una especie de intercambio similar al que las manos de un artesano llevan a cabo con los materiales y herramientas regadas por su mesa de trabajo. Sin embargo, a veces esos datos pueden ser parte de las instrucciones. Por ejemplo, en la instruccón MOV EAX, 1 movemos el valor de uno al acumulador. Y ese uno es parte del propio opcode (se encuentra en los ultimos 4 bytes del opcode). El uso de los valores inmediatos tiene sus ventajas y desventajas pero una cosa es segura con ellos: LOS VALORES INMEDIATOS NO CAMBIAN NUNCA.

Por razones que sería una tontería explicar, un valor inmediato puede ser el operando origen en una operación de ensamblador pero nunca el operando destino. Por ejemplo, tiene sentido mover el número uno al acumulador pero no tiene sentido mover el contenido del acumulador al número uno. Por lo mismo, un valor inmediato no se guarda en las celdas de memoria que contienen los datos, sino en las que contienen el código y modificar valores en esta sección aunque es posible (se llama Código Auto-Modificable) no solo es dificil y peligroso sino que está prohibido por la seguridad de los sistemas operativos mas modernos.

Otro pariente cercano del código automodificable es la Ejecución de Datos que es escribir código ejecutable en una sección del programa reservada para los datos y luego dirigir el flujo del programa hacia ese segmento. Pero como pueden ver en esta captura de pantalla, ya existe la Data Execution Protection o DEP que por seguridad no nos va a permitir hacer este tipo de cosas.

De acuerdo, tanto las constantes congeladas como los valores inmediatos se consideran valores constantes. Ahora pasemos a los Números Mágicos

Números Mágicos

En esta imagen tenemos dos rutinas en ASM que hacen exactamente lo mismo, de hecho si las ensamblamos incluso generan el mismo código máquina.

MOV      EAX, [EBX + 14H]
CMP      EAX, 4
SETNS    EDX
MOV      [EBX + 10H], EDX

MOV      EAX, [EBX + PUNTOS_DE_VIDA]
CMP      EAX, VALOR_DE_ATAQUE
SETS     EDX
MOV      [EBX + PERSONAJE_MUERE]

En ambos códigos primero leemos un valor de una estructura que contiene los datos de un personaje y extraemos el valor de sus puntos de vida, luego los comparamos con el valor de ataque recibido que es en este caso 4 y si el resultado de restarle ese 4 al total de puntos de vida la bandera que indica si el personaje se muere o no se muere. En este caso si el personaje tiene menos de 4 puntos de vida va a perder. Como puede verse no solo la rutina de abajo es mucho mas entendible ¡Y ni siquiera tiene comentarios! Sino que es mas mantenible a largo plazo. Por ejemplo si mas adelante queremos cambiar el valor de ataque o el orden de los datos dentro de la estructura solo es necesario ir al punto donde se define el valor de la constante y todas las referencias a esta serán automáticamente actualizadas. Que si nos ponemos a buscar todos los cuatros a lo largo del código nos tomará bastante mas tiempo.

Supongo que ya se han de imaginar porqué se les llama números mágicos a los números que aparecen como parte de las instrucciones y los operandos. Porque como todo lo que es mágico su funcionamiento se nos oculta y como programadores debemos escribir código que sea entendible ya no para otros sino para nosotros mismos, pues cuando un programa pasa de las 10,000 lineas se vuelve verderamente dificil de mantener si no hemos organizado el código de manera adecuada.

Trabajando con constantes inmediatas

Bueno, ya se habló de las maravillas del uso de constantes y como estas pueden mejorar la manejabilidad del código sin afectar la eficiencia del programa en los mas mínimo. Ahora veamos como hacemos nuestras propias constantes.

Declarar una constante en FASM es tan sencillo como escribir el nombre de la constante y el valor numérico separados por un signo de igual. Por ejemplo si queremos que la constante MALA_SUERTE tenga el valor de trece, solo tenemos que hacer esto:

MALA_SUERTE = 13

A partir de esa linea, cada que el compilador encuentre MALA_SUERTE va a sustituirla con el número 13. Por cierto, aunque no es obligatorio existe la convención de escribir los nombres de las constantes en MAYUSCULAS separando las palabras con el signo de subrayado _ (underscore bar _ ) no solo para que sean facilmente identificables sino para que no se confundan con el código normal que bien pueden llamarse igual. Por lo menos el FASM hace distinción entre letras mayúsculas y minúsculas. Por cierto, el sistema de definición de constantes no solo sirve para declarar constantes numéricas, usado con precaución puede usarse para modificar las instrucciones y estructura del propio compilador pues puede sustituir palabras o frases enteras.

Ahora bien, las constantes tienen un pequeñisimo problema sobre todo para los principiantes que aprenden leyendo código escrito por otros programadores. Y es que si el valor de una constante no ha sido definida por el programador el compilador no va a saber como manejarla y va a marcar un error de sintaxis. La mayor parte del tiempo cuando intenten programar para una nueva API en ensamblador se las van a ver con este problema. Por lo que deben de aprender a localizar, organizar y reutilizar dichas constantes en sus propios programas. Este proceso, al que yo llamo “Cacería de Constantes” es bastante entretenido y hace reflexionar sobre el verdadero significado de la palabra “hacking”. Pero de este asunto hablaremos en otra nota con mayor profundidad.

Anuncios

junio 10, 2010 - Posted by | Uncategorized | , , ,

1 comentario »

  1. Muy buen articulo. thx

    Saludos.

    Comentario por StrongCod3r | junio 10, 2010 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: