8. Recommendations and Conclusion
8.3 Recommendations for Improvement of Current Practice
8.3.1 Recommendation on Procedural Issues
¿Qué conocimientos previos debo tener? Antes de leer este libro, debe haber completado un curso universitario de nivel básico sobre programación de computadoras. De esta forma, comprenderá mejor las instrucciones de programación de alto nivel tales como IF, ciclos y arreglos, al implementarlos en lenguaje ensamblador.
¿Qué son los ensambladores y los enlazadores? Un ensamblador es un programa utilitario que con- vierte el código fuente de los programas escritos en lenguajes ensamblador a lenguaje máquina. Un enlaza-
dor es un programa utilitario que combina los archivos individuales creados por un ensamblador, en un solo
programa ejecutable. Hay una herramienta relacionada, llamada depurador, la cual le permite avanzar paso a paso a través de un programa mientras se ejecuta, para poder examinar los registros y la memoria.
¿Qué hardware y software necesito? Necesita una computadora con un procesador Intel386, Intel486, Pentium o compatible. Por ejemplo, los procesadores AMD funcionan muy bien con este libro. MASM (el ensamblador) es compatible con todas las versiones de 32 bits de Microsoft Windows, empezando con Windows 95. Algunos de los programas avanzados, relacionados con el acceso directo al hardware y la pro- gramación de los sectores de disco deben ejecutarse en MS-DOS, Windows 95/98/Me, debido a las estrictas restricciones de seguridad impuestas por Windows NT/2000/XP.
Además, necesitará lo siguiente:
• Editor: use un editor de texto o un editor para programadores, para crear los archivos de código fuente en lenguaje ensamblador.
• Depurador de 32 bits: en sentido estricto, no necesita un depurador, pero es muy conveniente tener uno. El depurador que se incluye con Visual C++ 2005 Express es excelente.
1.1 Bienvenido al lenguaje ensamblador 3
¿Qué tipos de programas podré crear? Este libro muestra cómo crear dos clases generales de programas: • Modo de direccionamiento real de 16 bits: los programas en modo de direccionamiento real de 16 bits se ejecutan en MS-DOS y en la ventana de consola en MS-Windows. También se les conoce como programas en modo real, ya que utilizan un modelo segmentado de memoria, requerido en programas escritos para los procesadores Intel 8086 y 8088. Hay notas a lo largo del libro con tips acerca de cómo programar en modo de direccionamiento real, y se dedican dos capítulos exclusivamente a la programa- ción de colores y gráfi cos en modo real.
• Modo protegido de 32 bits: los programas en modo protegido de 32 bits se ejecutan en todas las versio- nes de 32 bits de Microsoft Windows. Por lo general son más fáciles de escribir y de comprender que los programas en modo real.
¿Qué obtengo con este libro? Además de una buena cantidad de papel impreso podrá descargar Micro- soft Assembler del sitio Web de Microsoft. En el sitio Web www.asmirvine.com podrá consultar los detalles acerca de cómo obtener el ensamblador.
En el sitio Web del libro encontrará lo siguiente:
• Archivo de ayuda en línea, en donde se detallan los procedimientos de la biblioteca del libro y las estruc- turas esenciales de la API de Windows, por Gerald Cahill.
• Libro de trabajo de lenguaje ensamblador, una colección de tutoriales escritos por el autor.
• Bibliotecas de vínculos Irvine32 e Irvine16, para la programación en modo de direccionamiento real y modo protegido, con código fuente completo.
• Programas de ejemplo, con todo el código fuente del libro.
• Correcciones al libro y a los programas de ejemplo. ¡Esperamos que no sean demasiadas! • Tutoriales acerca de cómo instalar el ensamblador.
• Artículos sobre temas avanzados que no se incluyeron en el libro impreso por falta de espacio. • Grupo de discusión, que cuenta con más de 500 miembros.
¿Qué voy a aprender? Este libro le ofrece mucha información sobre la arquitectura computacional, la programación y las ciencias computacionales. He aquí lo que verá:
• Los principios básicos de la arquitectura computacional, aplicados en la familia de procesadores IA-32 de Intel.
• La lógica booleana básica y su aplicación en relación con la programación y el hardware de computadora. • La manera en que los procesadores IA-32 administran la memoria, usando modo real, modo protegido y
modo virtual.
• La manera en que los compiladores de lenguajes de alto nivel (tales como C++) traducen las instrucciones de su lenguaje a lenguaje ensamblador y código de máquina nativo.
• La manera en que los lenguajes de alto nivel implementan expresiones aritméticas, ciclos y estructuras lógicas a nivel de máquina.
• La representación de los datos, incluyendo enteros con y sin signo, números reales y datos tipo carácter. • A depurar programas a nivel de máquina. La necesidad de esta habilidad es imprescindible cuando se trabaja
en lenguajes tales como C y C++, los cuales proporcionan acceso a los datos y el hardware de bajo nivel. • La manera en que los programas de aplicación se comunican con el sistema operativo de la computadora,
a través de manejadores de interrupciones, llamadas al sistema y áreas comunes de memoria. • A interconectar el código en lenguaje ensamblador con programas en C++.
• A crear programas de aplicación en lenguaje ensamblador.
¿Cómo se relaciona el lenguaje ensamblador con el lenguaje máquina? El lenguaje máquina es un lenguaje numérico que un procesador de computadora (la CPU) entiende de manera específi ca. Los proce- sadores compatibles con IA-32 entienden un lenguaje máquina común. El lenguaje ensamblador consiste en instrucciones escritas con nemónicos cortos, tales como ADD, MOV, SUB y CALL. El lenguaje ensamblador
tiene una relación de uno a uno con el lenguaje máquina: cada una de las instrucciones en lenguaje ensam- blador corresponden a una sola instrucción en lenguaje máquina.
¿Cómo se relacionan C++ y Java con el lenguaje ensamblador? Los lenguajes de alto nivel, tales como C++ y Java, tienen una relación de uno a varios con el lenguaje ensamblador y el lenguaje máquina. Una sola instrucción en C++ se expande en varias instrucciones en lenguaje ensamblador o lenguaje má- quina. Podemos mostrar cómo las instrucciones en C++ se expanden en código máquina. La mayoría de las personas no puede leer código de máquina puro, por lo que utilizaremos su pariente más cercano, el lenguaje ensamblador. La siguiente instrucción en C++ lleva a cabo dos operaciones aritméticas y asigna el resultado a una variable. Suponga que X y Y son enteros:
int Y;
int X = (Y + 4) * 3;
A continuación se muestra la traducción de esta instrucción a lenguaje ensamblador. La traducción requiere varias instrucciones, ya que el lenguaje ensamblador funciona a un nivel detallado:
mov eax,Y ; mueve Y al registro EAX
add eax,4 ; suma 4 al registro EAX
mov ebx,3 ; mueve el 3 al registro EBX
imul ebx ; multiplica EAX por EBX
mov X,eax ; mueve EAX a X
(Los registros son ubicaciones de almacenamiento con nombre en la CPU, que almacenan los resultados intermedios de las operaciones).
El punto en este ejemplo no es afi rmar que C++ es superior al lenguaje ensamblador o viceversa, sino mostrar su relación.
¿Nosotros? ¿Quiénes somos? A lo largo de este libro verá referencias constantes a nosotros. A menudo, los au-
tores de libros de texto y artículos académicos utilizan nosotros como una referencia formal a ellos mismos. Esto se debe a que parece tan informal decir, “Ahora le mostraré cómo” hacer tal y tal cosa. Si le es de ayuda, piense en
nosotros como una referencia al autor, sus revisores (quienes en realidad lo ayudaron de manera considerable),
su editor (Prentice Hall), y sus estudiantes (miles de ellos).
¿Es portable el lenguaje ensamblador? Una importante distinción entre los lenguajes de alto nivel y el lenguaje ensamblador está relacionada con la portabilidad. Se dice que un lenguaje cuyos programas de código fuente pueden compilarse y ejecutarse en una amplia variedad de sistemas computacionales es
portable. Por ejemplo, un programa en C++ puede compilarse y ejecutarse en casi cualquier computadora,
a menos que haga referencias específi cas a funciones de biblioteca que existan en un solo sistema operativo. Una importante característica del lenguaje Java es que los programas compilados se ejecutan en casi cualquier sistema computacional.
El lenguaje ensamblador no es portable, ya que está diseñado para una familia de procesadores específi ca. Hay una gran variedad de lenguajes ensambladores en uso actualmente, cada uno de los cuales está basado en una familia de procesadores. Algunas familias de procesadores reconocidas son: Motorola 68x00, Intel IA-32, SUN Sparc, Vax e IBM-370. Las instrucciones en lenguaje ensamblador pueden coincidir directa- mente con la arquitectura de la computadora, o pueden traducirse durante la ejecución mediante un programa dentro del procesador, al cual se le conoce como intérprete de microcódigo.
¿Por qué aprender lenguaje ensamblador? ¿Por qué no sólo leer un buen libro acerca del hardware y la arquitectura de las computadoras, y evitar aprender a programar en lenguaje ensamblador?
• Si estudia ingeniería computacional, es muy probable que le pidan que escriba programas embebidos. Éstos son programas cortos que se almacenan en una pequeña cantidad de memoria, en dispositivos de un solo propósito tales como los teléfonos, los sistemas del combustible y la ignición del automóvil, los sistemas de control de aire acondicionado, los sistemas de seguridad, los instrumentos para la adquisición de datos,
1.1 Bienvenido al lenguaje ensamblador 5
las tarjetas de video, las tarjetas de sonido, los discos duros, los módems y las impresoras. El lenguaje ensamblador es ideal para escribir programas embebidos, debido a que utilizan muy poca memoria. • Las aplicaciones en tiempo real, tales como las simulaciones y el monitoreo de hardware, requieren preci-
sión en la sincronización y en las respuestas. Los lenguajes de alto nivel no proporcionan a los programa- dores un control exacto sobre el código máquina generado por los compiladores. El lenguaje ensamblador nos permite especifi car con precisión el código ejecutable de un programa.
• Las consolas de videojuegos requieren que su software esté altamente optimizado para que su tamaño de código sea pequeño y se ejecute con la mayor rapidez posible. Los programadores de videojuegos son expertos en la escritura de código que aproveche al máximo las características de hardware del sistema destino. Utilizan el lenguaje ensamblador como su herramienta preferida, ya que les permite un acceso directo al hardware de la computadora, y el código puede optimizarse en forma manual para obtener la máxima velocidad.
• El lenguaje ensamblador nos ayuda a obtener una comprensión general en cuanto a la interacción entre el hardware de computadora, los sistemas operativos y los programas de aplicación. Mediante el uso de lenguaje ensamblador, usted puede aplicar y probar la información teórica que recibe en los cursos de arqui- tectura computacional y sistemas operativos.
• En ocasiones, los programadores de aplicaciones encuentran que las limitaciones en los lenguajes de alto ni- vel les impiden realizar tareas de bajo nivel con efi ciencia, como la manipulación a nivel de bits y el cifrado de datos. A menudo hacen llamadas a subrutinas escritas en lenguaje ensamblador para lograr su objetivo. • Los fabricantes de hardware crean controladores de dispositivos para el equipo que venden. Los controla-
dores de dispositivos son programas que traducen los comandos generales del sistema operativo en refe-
rencias específi cas a los detalles relacionados con el hardware. Por ejemplo, los fabricantes de impresoras crean un controlador de dispositivo de MS-Windows distinto para cada modelo que venden. Lo mismo se aplica para los sistemas operativos Mac OS, Linux y otros.
¿Hay reglas en el lenguaje ensamblador? La mayoría de las reglas en el lenguaje ensamblador se basan en las limitaciones físicas del procesador de destino y su lenguaje máquina. Por ejemplo, la CPU requiere que los dos operandos de una instrucción sean del mismo tamaño. El lenguaje ensamblador tiene menos reglas que C++ o Java, ya que estos dos lenguajes de alto nivel utilizan reglas de sintaxis para redu- cir los errores de lógica involuntarios, a expensas del acceso a los datos de bajo nivel. Los programadores de lenguaje ensamblador pueden evadir con facilidad las restricciones características de los lenguajes de alto nivel. Por ejemplo, Java no permite el acceso a direcciones de memoria específi cas. Para evadir esta restricción podemos hacer una llamada a una subrutina en C que utilice clases de la JNI (Interfaz nativa de Java), pero puede ser complicado mantener el programa resultante. Por otro lado, el lenguaje ensamblador puede acceder a cualquier dirección de memoria. El precio por dicha libertad es alto: ¡los programadores de lenguaje ensamblador invierten mucho tiempo en el proceso de la depuración!