Beruflich Dokumente
Kultur Dokumente
Ensamblador 8086
El 8086 es un procesador de 16 bits. Esto significa que trabaja con registros internos de este tamao y que la amplitud del bus de datos es tambin de 16 bits. Sin embargo, todas las funcionalidades que describiremos aqu seguirn siendo vlidas cuando queramos adaptarnos a generaciones posteriores de procesadores, como el Pentium, ya que la compatibilidad es una premisa bsica en el diseo de las arquitecturas x86.
Perifricos e Interfaces
Ensamblador 8086
1.2 Registros
En primer lugar se nos ofrecen cuatro registros de 16 bits de propsito general, aunque cada uno tuvo asignada inicialmente una labor ms especializada.
AX: Acumulador BX: Base CX: Contador DX: Dato
Si se trabaja con datos de ocho bits, estos registros pueden ser vistos por las instrucciones como ocho registros de un byte cada uno
AH BH CH DH AL BL CL DL
Existen cuatro registros de ndice que, aunque se pueden utilizar como de propsito general, tienen una funcionalidad ms definida, relacionada con los accesos a memoria.
SP SI BP DI
SP y BP se utilizan en accesos al segmento de pila (paso de parmetros), mientras que SI y DI se utilizan en los accesos a segmentos de datos (cadenas de caracteres). Para mantener la referencia a los segmentos con los que trabaja un proceso durante su ejecucin existen otros cuatro registros. Estos cuatro registros contienen la referencia al segmento correspondiente.
CS: segmento de cdigo DS: segmento de datos ES: segmento de datos extra SS: segmento de pila (stack)
El registro IP contiene la direccin de la siguiente instruccin a ejecutar y el usuario no tiene ningn acceso a este registro, sin embargo lo est modificando implcitamente con las instrucciones de salto.
Perifricos e Interfaces
Ensamblador 8086
Finalmente, existe un registro de flags que contiene una serie de seales que nos indican el estado del procesador en cualquier momento. Estas seales o banderas nos sirven para dirigir el control del proceso a partir de sucesos previos. Los flags que se nos ofrecen son los siguientes:
De estado CF: de acarreo OF: de overflow ZF: de resultado cero SF: de resultado negativo PF: paridad del resultado AF: auxiliar (correccin en lgica decimal BCD) De control DF: de direccin (en instrucciones mltiples) IF: de interrupciones TF: paso a paso
A la izquierda del smbolo : figura el segmento (base) y a la derecha el desplazamiento. Dado que el segmento est expresado con 16 bits no podemos considerarlo exactamente la direccin base, que ha de tener 20 bits, por lo que hay que desplazarlo 4 bits a la izquierda (recurdese que trabajamos en notacin hexadecimal).
1050 + 0=1000+50=100+F50=10+1040=0+1050
Hay 7 modos de direccionamiento. A continuacin se muestra un ejemplo de cada uno utilizando el registro AX igual que podra haberse utilizado cualquier otro de los registros de propsito general. De registro a registro
MOV AX,BX
Inmediato
MOV AX, 500
Perifricos e Interfaces
Ensamblador 8086
Uso de variable
MOV AX, TABLA
TABLA es un smbolo que para el compilador tendr el mismo sentido que una direccin de memoria especificada directamente. Indirecto mediante registro
MOV AX, [BX] MOV AX, [BP] MOV AX, [DI] MOV AX, [SI]
Los registros encerrados entre corchetes contienen un desplazamiento dentro del segmento con el que se trabaja. El uso de determinados registros asume implcitamente un registro de segmento: BX, DI y SI asumen el registro de segmento DS, mientras que BP asume el registro de segmento SS. Relativo a base
MOV AX, [BX]+4 MOV AX, [BP]+4
Indexado a base
MOV AX,TABLA[BX][SI] MOV AX,TABLA[BX][DI] MOV AX,TABLA[BP][SI] MOV AX,TABLA[BP][DI]
1.4 Interrupciones
Para un programador, el sistema de interrupciones del 8086 consiste en una estructura formada por un conjunto de posiciones de memoria que comienza en la direccin absoluta de memoria 0. Esta estructura es un vector de interrupciones que contiene, cada dos palabras, una direccin de salto a una rutina de atencin a una interrupcin (la direccin 0 corresponde a la interrupcin 0, la direccin 2 a la interrupcin 1, etc). Las interrupciones pueden tener una causa fsica, invocadas por un dispositivo, o lgica, causadas por algn error de ejecucin o por una invocacin directa por parte de un programa. En cualquier caso, cuando se invoca una interrupcin, el mecanismo de atencin utiliza el nmero de la interrupcin para acceder al vector de interrupciones y toma de l la direccin correspondiente a la rutina de atencin.
4
Perifricos e Interfaces
Ensamblador 8086
Para crear una rutina de atencin a determinada interrupcin, el programador tiene que crear el programa y almacenarlo en memoria. Luego debe almacenar la direccin de comienzo del mismo en la posicin correspondiente del vector de interrupciones. Naturalmente, escribir una rutina de interrupcin obliga a respetar ciertos protocolos.
1.6 Instrucciones
Un programa en ensamblador es una especificacin de instrucciones, colocadas en el orden en que deseamos que se ejecuten, adems de una especificacin de los datos de partida sobre los que se ejecutar el programa. En un programa hay que especificar los segmentos. Como mnimo hay que especificar el segmento de cdigo, que es el que almacena el programa, aunque generalmente se especifica tambin un segmento de datos que contendr los datos iniciales. Opcionalmente, tambin puede especificarse un segmento de pila y un segmento extra, que quedar para apoyo de la codificacin. Sin embargo cada situacin requiere sus propias decisiones. Todas las instrucciones pueden trabajar con operandos tanto de 8 como de 16 bits. Ambos operandos deben ser del mismo tamao para poder realizar una operacin entre ellos. En los accesos a memoria, dependiendo de los registros utilizados, l cdigo de la instruccin indicar el tamao usado. Si la instruccin no utiliza registros, el tamao debe definirse mediante una directiva. Existen 92 tipos de instrucciones. Por tipo de instruccin entendemos una instruccin genrica, como por ejemplo mover. Cada tipo de instruccin puede tener muchas versiones posibles segn donde residan los operandos y el modo de direccionamiento que se utilice para acceder a un dato en memoria. El conjunto de instrucciones se puede clasificar en uno de los siguientes grupos: Transferencia de datos Aritmticas Aritmtica a nivel de bit Transferencia de control Operaciones con cadenas (de bytes) Interrupciones Control del microprocesador
Perifricos e Interfaces
Ensamblador 8086
Para facilitar la escritura de los programas existen las instrucciones ensamblador y, adems, otras herramientas que nos proporcionan un cierto nivel de abstraccin, como por ejemplo las pseudo-instrucciones y las directivas. Las pseudos-instrucciones son instrucciones en ensamblador que podran no corresponderse directamente con una instruccin en cdigo mquina. Es una abstraccin que se crea para facilitar la tarea al programador. Las directivas son una serie de comandos que nos permiten controlar las acciones del compilador, tanto las relacionadas con la propia codificacin de instrucciones como con la generacin de informacin residual del proceso.
Perifricos e Interfaces
JNE - Saltar si no es igual - Saltar si no es mayor
Ensamblador 8086
INSTRUCCIONES 8086
Transferencia de datos
IN LAHF LDS LEA LES MOV OUT POP POPF PUSh PUSHF SAHF XCHG XLAT - entrada de bytes o palabra - Cargar AH con las banderas - Cargar puntero usando DS - Cargar direccin efectiva - Cargar puntero usando ES - Mover - Salida de byte o palabra - Recuperar palabra de la pila - Recuperar banderas de la pila - Depositar palabra en la pila - Depositar banderas en la pila - Almacenar Ah en banderas - Intercambiar dos operandos - Traducir
JNG JNGE JNL JNLE JNO JNP JNS JNZ JMP JO JP JPE JPO JS JZ LOOP LOOPE
- Saltar si no es mayor o igual - Saltar si no es menor - Saltar si no es menor o igual - Saltar si no se produce desbordamiento - Saltar si no hay paridad - Saltar si no es negativo - Saltar si no es cero - Salto incondicional - Saltar si se produce desbordamiento - Saltar si hay paridad - Saltar si hay paridad par - Saltar si hay paridad impar - Saltar si el signo es negativo - Saltar si el resultado es cero - Bucle hasta que acabe contador - Bucle mientras igual
LOOPNE - Bucle mientras no igual LOOPNZ - Bucle mientras resultado no cero LOOPZ RET - Bucle mientras resultado cero - Retornar de un procedimiento
Instrucciones aritmticas
AAA AAD AAM AAS ADC ADD CBW CMP CWD DAA DAS DEC DIV IDIV IMUL INC MUL NEG SBB SUB - Ajuste ASCII en suma - Ajuste ASCII en divisin - Ajuste ASCII en multiplicacin - Ajuste ASCII en resta - Sumar con acarreo - Sumar (sin acarreo) - Convertir byte en palabra - Comparar operandos - Convertir palabra a doble palabra - Ajuste decimal en suma - Ajuste decimal en resta - Decrementar en uno - Dividir sin signo - Dividir con signo - Multiplicar con signo - Incrementar en uno - Multiplicar sin signo - Negar/formar complemento a 2 - Restar con acarreo - Restar (sin acarreo)
Instrucciones de interrupcin.
INT INTO IRET - Invocar a la interrupcin - Retorno de interrupcin
- Interrupcin si desbordamiento
(conservando el signo)
coprocesador)
Perifricos e Interfaces
Directivas de listado
Ensamblador 8086
Listado de macros
.LALL .SALL .XALL - Listar macros y expansiones - Suprimir listado macros y expansiones - Listar slo macros que generan cdigo objeto
Definicin de datos
DB DW DD DQ DT - Definir byte - Definir palabra - Definir doble palabra - Definir cudruple palabra - Definir diez bytes
Referencias externas
PUBLIC - Definir smbolo pblico EXTRN - Definir smbolo externo INCLUDE - Incluir fichero fuente
Comentarios
COMMENT - Comentario
Mensajes
%OUT - Emitir un mensaje durante el ensamblaje
Directivas de macro
Definicin de macros MACRO - Comienza macro ENDM LOCAL EXITM PURGE REPT veces IRP vez IRPC cada vez - Repetir bloque de sentencias con un carcter - Repetir bloque de sentencias con un valor cada - Fin macro - Define etiquetas dentro de macro - Terminar expansin de la macro - Borrar macros de la memoria - Repetir bloque de sentencias un nmero de
Definicin de bloques
GROUP NAME LABEL STRUC - Agrupar segmentos - Nombrar un mdulo - Asignar un atributo a un nombre - Definir estructura
Directivas condicionales
IF ELSE ENDIF - Evaluar condicin y decidir - Si condicin es falsa - Fin de estructura condicional
Operadores de macro
para concatenar smbolos o texto para comentarios que no aparecern para interpretar caracteres en sentido para convertir una expresin en un
Perifricos e Interfaces
Ensamblador 8086
La asignatura Perifricos e Interfaces introduce al alumno en el manejo de las herramientas de desarrollo de programas en ensamblador para procesadores de la familia x86. En concreto se utilizarn tres herramientas proporcionadas por el Turbo Debugger de Borland y que funcionan bajo MSDOS: el ensamblador TASM, el enlazador TLINK y el depurador TD. Un programa en ensamblador debe ser generado con un editor de textos como el Block de Notas o el WordPad. En cualquier caso, ha de trabajarse en texto plano, es decir, sin aadir ningn tipo de carcter de control de edicin. Para evitar confusiones, es recomendable que el fichero editado tenga la extensin .asm. El TASM es un ensamblador, es decir, un programa que transforma el cdigo simblico con el que trabaja el programador en cdigo mquina. De entre las opciones que admite el TASM, la que ms nos interesa es /zi, que ensambla el cdigo introduciendo elementos aadidos para permitir posteriormente su depuracin mediante el TD. Una vez que tengamos depurado el programa, esta opcin nos perjudica porque genera un cdigo menos eficiente. Otra opcin de inters en el TASM es /l, que nos devuelve un archivo con extensin .lst, el cual contiene un listado del cdigo ya ensamblado. En l podemos observar el cdigo mquina que est asociado a cada instruccin, o la direccin relativa de cada instruccin con respecto al comienzo de segmento. En general, el ensamblado de un programa lo realizaremos de la siguiente manera:
tasm /zi ejemplo.asm
El TASM generar como resultado un archivo objeto con extensin .obj que deber ser enlazado utilizando el enlazador TLINK. Este enlazador convertir el cdigo mquina generado por el TASM en un fichero ejecutable en el sistema operativo base de la mquina. Para permitir la depuracin del programa usando el TD, tambin ser necesario utilizar el parmetro /v.
tlink /v ejemplo.obj
El resultado del proceso de enlazado ser un fichero ejecutable con extensin .exe. Podemos ejecutar este fichero invocando su nombre directamente desde MSDOS como un comando.
ejemplo.exe
Sin embargo, si el programa no funciona como se espera no obtendremos demasiadas pistas de cual puede ser la causa. Por este motivo, resulta interesante utilizar el TD, una herramienta de depuracin de errores del cdigo. Esta herramienta nos permite simular la ejecucin del cdigo ejecutable y detectar los posibles fallos que se revelarn en tiempo de ejecucin.
td ejemplo.exe
Perifricos e Interfaces
Ensamblador 8086
La herramienta nos permitir ver el programa fuente as como el cdigo generado por el ensamblador en sus posiciones de memoria definitivas para la actual ejecucin. Tambin podemos observar (y modificar) los registros del procesador y los datos que hayamos situado en memoria (segmento de datos). Adems, nos permitir realizar una ejecucin segura del programa, entendiendo por esto que si el programa alberga errores tenemos la certeza de que estos no van a perjudicar al sistema, lo que no podemos asegurar si directamente lo ejecutamos desde MSDOS. Sin embargo, la opcin ms prctica de todas es la posibilidad de ejecutar el programa instruccin a instruccin, indicndose con una flecha en el cdigo fuente cul es la ltima instruccin que se ha ejecutado. De esta forma podremos comprobar que cada instruccin modifica exactamente aquellos recursos que esperamos que modifique y que lo hace de la manera en que desebamos que lo hiciera cuando escribimos el programa. El men RUN contiene las opciones de ejecucin: paso a paso, paso a paso saltndose las llamadas a rutina (las ejecuta como un todo), ejecutar hasta donde est el cursor, etc. Si el programa muestra datos por pantalla, para ver la pantalla de ejecucin hay que pulsar ALT+F5, mientras que para retornar al depurador basta con pulsar cualquier tecla. Adems, es importante destacar que hay que realizar un program reset para iniciar cada nueva ejecucin del programa. Otra interesante posibilidad del depurador es observar los cambios que ocurren en los registros y la memoria durante la ejecucin del programa. La opcin CPU del men VIEW abre varias ventanas. Arriba a la izquierda aparece una ventana con el cdigo mquina ya localizado en memoria y una flecha apuntando a la primera instruccin a ejecutar. Arriba a la derecha aparecer otra ventana con el contenido de los registros, mientras que debajo del cdigo aparecer una ventana con el contenido de la memoria. Cuando se ejecute el programa paso a paso podremos ver como avanza la flecha de instruccin a instruccin y como van cambiando los registros y la memoria. Cada ventana tiene su propio men local: los registros pueden verse como 32 bits o 16 bits y pueden modificarse a voluntad, la ventana de la memoria puede localizarse en cualquier direccin y modificarse a voluntad, etc. Otras opciones de inters dentro del men VIEW son VARIABLES, donde podemos ver los contenidos de las variables de nuestro programa (una variable es una etiqueta definida en un segmento de datos), DUMP, que nos muestra otra ventana de memoria, REGISTERS, otra ventana de registros, MODULE, que muestra el cdigo fuente, etc. Finalmente, hay otros mens que nos permiten introducir BREAKPOINTS, modificar el contenido de la memoria a travs de las variables y otras muchas funcionalidades de las que tpicamente estn disponibles en los depuradores de programas.
10
Perifricos e Interfaces
Ensamblador 8086
DATOS SEGMENT TEXTO1 DB "PERIFERICOS E INTERFACES. FI.",13,10,"TITULACION DE INGENIERO EN INFORMATICA",13,10,'$' TEXTO2 DB "AMIGOS Y AMIGAS, BIENVENIDOS A LAS PRACTICAS DE PERIFERICOS E INTERFACES",13,10,'$' DATOS ENDS
CODIGO
borra_pantalla PROC PUSH ES PUSH AX PUSH CX PUSH DI PUSHF MOV AX, com_pantalla MOV ES,AX MOV CX, (tam_pantalla/2)+1 MOV DI, tam_pantalla MOV AL, '-' MOV AH, 07h STD REP STOSW POPF POP DI POP CX POP AX POP ES RET ENDP
empezar: MOV AX, DATOS MOV DS, AX MOV AX, PILA MOV SS, AX MOV SP, OFFSET apuntador MOV AH, 09h MOV DX, OFFSET TEXTO1 INT 21h Call borra_pantalla MOV AH, 09h MOV DX, OFFSET TEXTO2 INT 21h MOV AH, 4Ch INT 21h
retorno:
fin:
CODIGO END
ENDS empezar
11
Perifricos e Interfaces
Ensamblador 8086
En primer lugar tenemos una directiva de ensamblador EQU por medio de la cual identificamos un smbolo con un valor. En cualquier lugar del programa en que hayamos utilizado el smbolo, ste ser sustituido por su valor durante el ensamblado. A continuacin definimos un segmento, indicado por la directiva SEGMENT. Le llamamos DATOS, porque es el que vamos a utilizar como segmento de datos. El fin de un segmento viene especificado por la directiva ENDS. Dentro del segmento de datos podemos observar el uso una directiva de reserva de memoria: DB. Esta directiva reserva bytes, existiendo mltiples maneras de indicar el nmero. Lo que figura a la izquierda de la directiva es la ETIQUETA, que vamos a utilizar dentro del programa para acceder a la primera posicin de memoria que vamos a reservar. Observemos la lnea que comienza con la etiqueta TEXTO. Primero se reservan tantos bytes como caracteres hay en la cadena. Se excluyen las comillas, que son los delimitadores de la cadena. La coma es un separador, no implica reserva de bytes. A continuacin viene un nmero, con ello solicitamos que reserve un byte con el valor 13h. Los siguientes elementos son semejantes a los descritos excepto el ltimo: $, con el que indicamos que queremos reservar un byte con el carcter ascii encerrado entre comillas simples. Las comillas simples son un delimitador de carcter. Debajo definimos otro segmento que va a ser el de pila. No es realmente necesario si no hacemos un uso abusivo de la pila porque el propio ensamblador se encarga de generar un pequeo segmento de pila e inicializar los registros pertinentes. No obstante lo hemos definido, en cuyo caso nosotros debemos inicializar los registros en el programa. Aqu usamos la directiva DB, pero para reservar espacio utilizamos 127 DUP(p), con esto estamos diciendo que reserve 127 bytes y que los inicialice al carcter p. (esto tiene ninguna relevancia en lo que respecta al manejo de la pila, es una cuestin esttica). APUNTADOR es la etiqueta que vamos a utilizar para inicializar el puntero de pila. Viene a continuacin la definicin de otro segmento. A este le llamamos cdigo porque va a contener el programa ensamblador. La directiva ASSUME es un indicador para el ensamblador donde le explicamos para qu vamos a utilizar cada uno de los segmentos definidos. Aqu le estamos indicando que el segmento DATOS va a ser el segmento de datos del programa y que utilice por defecto el registro de segmento DS cada vez que aludamos a una etiqueta de las definidas dentro de este segmento. Lo mismo hacemos para el segmento de cdigo y el segmento de pila. Ojo: esta directiva no inicializa los registros, salvo el CS, as que habr que hacerlo en el programa. La etiqueta EMPEZAR marca el comienzo del programa y, por lo tanto, es en este punto donde empieza a ejecutarse el programa. Para indicrselo al ensamblador hay que poner al final del archivo una directiva END con el nombre de la etiqueta. Esta accin es estrictamente necesaria para que el procesador empiece a ejecutar el cdigo en este punto precisamente y no desde el comienzo de segmento como lo hara de forma natural.
12
Perifricos e Interfaces
Ensamblador 8086
Las primeras instrucciones que se ejecutan son las que inicializan los registros de segmento. Primero inicializamos el registro DS, despus el SS y despus el SP. Obsrvese que lo hacemos mediante el registro AX, ya que no es posible mover datos inmediatos directamente a un registro de segmento. Si estudiamos el cdigo podemos ver algunos ejemplos de uso de la interrupcin 21h con la funcin AH=9h para imprimir una cadena de caracteres en pantalla. Obsrvese que lo ltimo que se ejecuta es una interrupcin 21h con la funcin AH=4Ch. Esta llamada es la que permite a procesador volver al sistema operativo. Es estrictamente necesario incluir como instruccin final un retorno al sistema operativo, esta es una de las forma, pero hay otras. Tambin podemos ver en el programa la definicin de rutina. sta viene encerrada entre dos directivas PROC y ENDP. Naturalmente junto a PROC est la etiqueta que nos servir para invocar a la rutina. Lo primero que hace la rutina es guardar en la pila los valores de los registros para luego realizar su funcin y, finalmente, recuperar los valores originales de los registros. La funcin de la rutina es, en este caso, borrar la pantalla rellenndola con el carcter -.
13