Académique Documents
Professionnel Documents
Culture Documents
2.1 Importancia del Lenguaje Ensamblador. 2.2 Manejo de memoria. 2.3 Direccionamiento. 2.4 Formato de un programa. 2.5 Proceso de ensamble y ligado. 2.6 Instrucciones del Lenguaje Ensamblador. 2.7 Macros. 2.8 Interrupciones. Importancia del Lenguaje Ensamblador. La importancia estriba en que se pueden utilizar directamente los recursos del equipo de cmputo, es decir, podemos utilizar los registros del procesador, los puertos de E/S, la memoria principal, esto trae como ventaja que se desarrollen programas que sean rpidos en su ejecucin. Los registros de la familia 80x86. El 8086 fue diseado para ejecutar instrucciones y realizar operacin aritmtica y lgica, al mismo tiempo que reciben instrucciones y pasa datos a y desde memoria. Para hacer esto utiliza registros de 16 bits. Existen 14 registros en el 80x86, cada uno con un uso especial. Cuatro registros de propsito general son usados por los programas para almacenar temporalmente los resultados intermedios y los operandos de las operaciones aritmticas y lgicas. Cuatro registros de segmento guardan la direccin inicial de ciertos segmentos de memoria. Cinco registros apuntadores e ndices mantienen las direcciones de desplazamiento que son utilizadas con los prrafos de segmento para localizar datos en memoria. Finalmente, existe un registro de banderas (flags) que contiene nueve banderas de 1 bit utilizadas para registrar la informacin de estado y controlar las operaciones del 8086. La siguiente figura muestra estos registros. Los registros de propsito general. Los registros de propsito general, de tamao de 16 bits, son conocidos como AX, BX, CX y DX. Cada uno de ellos puede ser opcionalmente referenciado como un par de registros de 8 bits (1 byte). El byte de la parte izquierda (el ms significativo) es referido como el byte alto (high), y el byte de la parte derecha (el menos significativo) es referido como el byte bajo (low). As el registro AX puede ser dividido en los registros AH y AL, el registro
MC Genaro Alberto Gmez Chi. Pgina 1
Cdigo
CF OF ZF SF PF AF
Bandera de acarreo Bandera de desborde Bandera de cero Bandera de signo Bandera de paridad Bandera de acarreo auxiliar
Es puesta a uno cuando una operacin genera un acarreo a o un prstamo de un operando destino. Es puesta a uno si el resultado de una operacin es demasiado grande o pequeo para ajustarse en el operando destino. Es puesta a uno si el resultado de una operacin es cero o el de una comparacin es igual. Igual al bit de mayor orden del resultado de una operacin (0 es positivo, 1 es negativo) Es puesta a uno si los de orden bajo del resultado de una operacin contiene un numero par de bits 1. Es puesta a uno si la operacin genera un acarreo a o un prstamo de los 4 bits de orden bajo de un operando. Indica un ajuste Pgina 4
DF
IF
TF
El concepto de bus. Las computadoras basadas en procesadores de la familia 80x86 enlazan toda su circuitera de control interna en un diseo de circuito conocido como bus. Un bus es simplemente un camino compartido en la tarjeta principal en el que todas las partes controladoras de la computadora estn conectadas. Cuando los datos son pasados de un componente a otro viajan a lo largo de este camino comn para alcanzar su destino. Cada chip de control y cada byte de memoria en el PC estn conectados directa o indirectamente al bus. Cuando un nuevo componente es conectado a una de las ranuras de expansin, se esta conectando directamente al bus, y convirtindolo en un socio en la operacin de la unidad entera. Siempre que una celda de memoria de memoria o puerto es usado como un sitio de almacenamiento, su localizacin es marcada por una direccin que es nica que lo identifica. Cuando un dato esta listo para ser transferido, su direccin destino se transmite primero a lo largo del bus de direcciones, los datos le siguen entonces a lo largo del bus de datos. De esta manera, el bus transporta ms que datos. Acarrea informacin de potencia y control, tal como seales de temporizacin (del reloj del sistema) y seales de interrupcin, como tambin las direcciones de miles de celdas de memoria y los diferentes dispositivos adheridos al bus. Para acomodar estas cuatro diferentes funciones, el bus se divide en cuatro partes: las lneas de potencia, el bus de control, el bus de direcciones y el bus de datos. El Bus de Direcciones El Bus de direcciones en la familia estndar de PC usa 20 lneas de seal para transmitir las direcciones de las celdas de memoria y los dispositivos adheridos al bus. Puesto que hay otros dos valores posibles (0 y 1) que pueden viajar a lo largo de cada una
MC Genaro Alberto Gmez Chi. Pgina 5
12340h
MC Genaro Alberto Gmez Chi.
1234:5678
+ 5678h 179B8h
Pgina 8
Pgina 11
Uso Servicios de despliegue de video Servicios de disco flexible Servicios de comunicaciones Servicios de cinta de cassette Servicios de teclado estndar Servicios de impresora Servicio de lista de equipo Servicio de tamao de memoria
Pgina 14
Las diferentes banderas del registro de banderas (FLAGS) son modificadas por las rutinas del ROM-BIOS. Por lo tanto, no deber esperarse que sean preservadas. En algunos servicios las banderas de acarreo (CF) y de cero (ZF) son usadas para sealar el xito o fracaso general de una operacin requerida. El sistema operativo de disco (DOS). El DOS es un programa de control que administra los recursos del sistema (UCP, memoria, almacenamiento secundario, etc.). Tambin proporciona el lenguaje de comandos con el que puede controlar fcilmente el accionar de la computadora. Microsoft proporciona el ncleo del DOS como un programa propietario basado en los servicios estndares del BIOS. El ncleo del DOS suministra servicios independientes del hardware que pueden ser utilizados por los programas de aplicacin en una gran variedad de sistemas. Los servicios del DOS pueden ser divididos arbitrariamente en las siguientes categoras: E/S de caracteres. Operaciones de directorio. Control de disco. Localizacin dinmica de memoria. Manejo de errores. Operaciones con archivos. Miscelnea de funciones del sistema. Funciones de red. Iniciacin y terminacin de programas. Pueden accederse los servicios del DOS de 2 maneras. Algunos servicios, los ms importantes desde el punto de vista del programador, son accedidos directamente utilizando interrupciones de software; otros, los usados por usuarios finales, son accedidos mediante el procesador de comandos (generalmente caracterizado por el programa COMMAND.COM).
MC Genaro Alberto Gmez Chi. Pgina 15
Pgina 18
Pgina 19
Edicin
Archivo de programa fuente
Ensamble
Modificacin, en caso de error Archivo de programa Objeto
Enlace
Archivo de programa ejecutable
Depuracin
Archivo de programa ejectuable
Para cada programa que se realice, habr eventualmente tres archivos en el disco. El paso inicial es crear un archivo de programa fuente. Para crear este programa es necesario usar un editor ASCII, como el programa EDIT de la versin 5.0 o posterior de MS-DOS. Este archivo contendr todas las instrucciones de lenguaje ensamblador que conforman nuestro programa. Por convencin, los archivos escritos en lenguaje ensamblador tienen asignados la extensin .ASM. Los mdulos de programa fuente que constituyen un programa ejecutable pueden estar organizados en una gran variedad de formas. Por ejemplo, pueden escribirse todos los procedimientos de un programa en un solo mdulo o pueden dividirse estos procedimientos en diferentes mdulos, de acuerdo a la especifidad de la tarea que realizan.
Pgina 20
Pgina 21
Para la operacin del programa se asume que se est utilizando el ensamblador y el ligador, TASM y TLINK respectivamente, de Borland. Adems, no hace uso de las caractersticas avanzadas de estos productos y opera utilizando nicamente las opciones establecidas por omisin. Tambin, en el PATH del DOS debern agregarse los directorios donde se encuentran instalados ambos productos de Borland.
La sintaxis del programa es: ALE filename [x]
Pgina 22
El archivo de procesamiento por lotes realiza el siguiente trabajo: Verifica que el archivo que se desea ensamblar exista. De otra forma salta al final del archivo, sin hacer nada.
Pgina 23
Ejecuta el programa Turbo Link que enlazar los mdulos para producir el programa ejecutable. Si hubiese algn error durante el ligado de los mdulos existentes, la siguiente lnea se encargar de verificarlo al probar la existencia del archivo con extensin .EXE. La lnea
IF NOT "A%1" == "A" GOTO EJECUTAR
Verificar si el programador ha proporcionado un segundo parmetro en la lnea de comando que ejecuta el archivo batch. Si lo anterior es cierto, se ejecutar el programa ejecutable producido por TLINK; si no se proporciona segundo parmetro, se estar indicando que se desea depurar el archivo ejecutable y se invocar al programa Turbo Debugger para seguir la ejecucin lgica del programa ejecutable. El formato de una lnea en lenguaje ensamblador 8086 Las lneas de cdigo fuente de lenguaje ensamblador tienen el siguiente formato:
<etiqueta> <instruccin/directiva> <operandos> <;comentario>
Donde <etiqueta> es un nombre simblico opcional; <instruccin/directiva> es un nemnico para una instruccin o una directiva; <operandos> contiene una combinacin de cero, uno o dos (y algunas pocas veces ms) constantes, referencias de memoria, referencias de registro y cadenas de texto, segn lo requiera la instruccin particular o la directiva; <;comentarios> es un comentario opcional.
Pgina 24
Los dgitos (0 - 9) no pueden ser utilizados como el primer carcter de una etiqueta. El signo de pesos ($) y el signo de interrogacin (?) solos no pueden ser utilizados como un smbolo, puesto que as tienen un significado especial. Cada etiqueta debe ser definida slo una vez1; esto es, deben ser nicas. Las etiquetas pueden ser usadas como operandos cualquier nmero de veces. Una etiqueta puede aparecer sola en una lnea; es decir, sobre una lnea sin una instruccin o directiva. En este caso, el valor de la etiqueta es la direccin de la instruccin o directiva en la siguiente lnea del programa. Las etiquetas que aparecen solas en una lnea o acompaadas de instrucciones o directivas deben finalizar con un smbolo de dos puntos (:). Otras etiquetas generalmente no finalizan con este smbolo. En el programa ejemplo HOLA.ASM se utilizan dos etiquetas: Msg, que es el nombre asignado a la cadena de caracteres Hola a todos,0Ah,0Dh,$, almacenada en el segmento de datos del programa, e Inicio que, aunque aparezca sola en una lnea del programa, representa la direccin donde se almacena en memoria la instruccin
mov ax,@data
En la lnea
mov
dx,OFFSET Msg
1Esta
regla tiene su excepcin en el procesamiento de macros del ensamblador, donde es posible definir ms de una vez un identificador o etiqueta.
Pgina 25
Representa el conjunto de instrucciones que despliega el mensaje en la pantalla. Las directivas, por su parte, generalmente no producen cdigo ejecutable, sino que controlan varios aspectos de como opera el ensamblador, del tipo de cdigo ensamblado, de los segmentos usados, etc. En otras palabras, las directivas instruyen al ensamblador de ciertos aspectos relativos a la traduccin de lenguaje ensamblador a lenguaje de mquina. Las directivas utilizadas en el programa HOLA.ASM estn escritas en maysculas, para distinguirlas de los mnemnicos de instruccin. Sin embargo, las directivas pueden ser escritas en minsculas o en maysculas y minsculas.
El campo de operandos
Los nemnicos de instrucciones y las directivas le dicen al ensamblador qu hacer. Los operandos, por otra parte, le dicen al ensamblador qu registros, parmetros, localizaciones de memoria, etctera, estn asociados a cada instancia de una instruccin o
Pgina 26
(llamadas a
Pgina 28
.DATA, por su parte, marca el inicio del segmento de datos. En este segmento debern colocarse las variables de memoria. Por ejemplo:
ErrorMessage Counter ... .DATA DB 0Dh,0Ah,'*** Error ***',0Dh,0Ah,'$' DW ? ...
A diferencia de las directivas de segmento anteriores, .DATA presenta cierta complejidad: en el cdigo del programa, debe cargarse explcitamente el registro DS con el smbolo @data, antes de que se realicen accesos a localizaciones de memoria existentes en el segmento definido por .DATA. Puesto que un registro de segmento puede ser cargado con el contenido de un registro de propsito general o una localizacin de memoria, pero no con una constante, el registro de segmento es generalmente cargado con una secuencia de dos instrucciones:
... mov ax,@data
Pgina 29
Esta secuencia de instrucciones inicializa DS para que apunte al segmento de datos que inicia con la directiva .DATA. Sin las dos instrucciones que inicializan el registro DS con el segmento definido por .DATA, las variables de memoria que residen en el segmento .DATA no podrn ser accedidas a menos que DS apunte a este segmento. Los registros de segmento CS y SS son inicializados por el DOS cuando un programa inicia, por lo tanto no debern ser cargados explcitamente como se hace con el registro DS. Mientras que CS apunta a las instrucciones y SS apunta a la pila, DS apunta a los datos. Los programas no pueden manipular directamente el cdigo y la pila; pero trabajan constantemente con los datos de manera directa. Adems, los programas pueden tener datos en diferentes segmentos a la vez; recurdese que el 8086 permite acceder cualquier localidad de memoria en un rango de 1 Mb, pero nicamente en bloques de 64 Kb (relativo a un registro de segmento) a la vez. Por lo tanto, al principio el programador querr inicializar el registro DS con un segmento, acceder datos en ese segmento y despus cargar DS con otro segmento para acceder un bloque diferente de datos. Este esquema es utilizado generalmente en los programas ms grandes de lenguaje ensamblador. El registro ES, por su parte, es cargado tal y como se hace con el registro DS. A menudo, puede necesitarse trabajar con los dos segmentos de datos: el segmento de datos normal, apuntado por DS, y el segmento de datos extra, apuntado por ES. La directiva DOSSEG La directiva DOSSEG causa que los segmentos en un programa de ensamblador sean agrupados acorde a las convenciones de ordenamiento de segmentos de Microsoft. Para la mayora de las programas escritos completamente en lenguaje ensamblador el uso de esta directiva asegura que se desempeen correctamente. No es necesario especificar DOSSEG cuando se enlazan mdulos de lenguaje ensamblador con lenguajes de alto nivel, debido a que los lenguajes de alto nivel automticamente seleccionan el ordenamiento de segmentos de Microsoft; sin embargo, es til su utilizacin para recordar que clase de ordenamiento de segmentos est en efecto. Por lo tanto, el enfoque ms simple es usar DOSSEG como la primera lnea en todos los programas (a menos que se tengan razones para no hacerlo).
Pgina 30
Descripcin
El cdigo y los datos del programa deben ajustarse dentro del mismo segmento de 64 Kb. Cdigo y datos son near. El cdigo del programa debe ajustarse dentro de un segmento simple de 64 Kb, y los datos del programa deben estar en otro segmento separado de 64 Kb. Cdigo y datos son near. El cdigo del programa puede ser mayor que 64 Kb, pero los datos del programa deben ajustarse en un slo segmento de 64 Kb. El cdigo es far, mientras que los datos son near. El cdigo del programa debe estar dentro de un segmento de 64 Kb, pero los datos del programa pueden ocupar ms de 64 Kb. El cdigo es near, mientras que los datos son far. Ningn arreglo de datos puede ser mayor de 64 Kb. El cdigo y los datos del programa pueden ocupar ms de 64 Kb, pero ningn arreglo de datos puede ser mayor de 64 Kb. El cdigo y los datos son far. El cdigo y los datos del programa pueden ocupar ms de 64 Kb y los arreglos de datos puede exceder los 64 Kb. El cdigo y los datos son far. Los apuntadores a elementos dentro de un arreglo son far. Tabla 2.1. Modelos de memoria
compact
large huge
2Los
modelos de memoria descritos corresponden a los modelos de memoria utilizados por Turbo C y muchos otros compiladores para la PC y sistema operativo MS-DOS.
Pgina 31
Pgina 32
Directivas de segmento estndar El modelo de programa que se lista en la figura 2.5 presenta un marco de trabajo que sustituye las directivas de segmento simplificadas por las directivas de segmento estndar. Las directivas de segmento simplificadas hacen ms fcil el trabajo de ligar mdulos de lenguaje ensamblador con programas escritos en lenguajes de alto nivel. Las directivas de segmento estndar, por su parte, proporcionan un control de segmento ms completo y son utilizadas para programas escritos totalmente en lenguaje ensamblador.
Pgina 33
La directiva SEGMENT SEGMENT define el inicio de un segmento. La etiqueta precediendo a la directiva SEGMENT es el nombre del segmento; Por ejemplo, en el programa modelo anterior, la lnea
Datos SEGMENT WORD PUBLIC 'DATA'
Define el inicio de un segmento llamado DATOS. La directiva SEGMENT puede especificar opcionalmente a un conjunto de atributos de segmento que le dan instrucciones al ligador y al ensamblador de cmo establecer y combinar los segmentos. Los atributos pueden ser especificados en cualquier orden y no es necesario proporcionarlos todos para un segmento. El atributo de alineacin El atributo opcional align define el rango de direcciones de memoria de la que puede seleccionarse una direccin de inicio para el segmento. Los valores que puede tomar un atributo se muestra en la tabla 2.2.
MC Genaro Alberto Gmez Chi. Pgina 34
DWORD
PARA PAGE
Si no se proporciona el atributo de alineacin, por omisin se utiliza el tipo PARA. El ligador utiliza la informacin de alineacin para determinar la direccin de inicio relativa para cada segmento. El DOS utiliza esta informacin para calcular la direccin de inicio actual cuando el programa es cargado en memoria. El atributo de combinacin El atributo opcional combine define cmo combinar segmentos que tienen el mismo nombre. El atributo de combinacin puede tener cualquiera de los siguientes valores mostrados en la tabla 2.3.
Tipo de combinacin PUBLIC Significado Concatena todos los segmentos que tienen el mismo nombre para formar un segmento simple contiguo. Todas las direcciones de instrucciones y datos en el nuevo segmento son relativos a un registro de segmento simple y todos los desplazamientos son ajustados para que representen la distancia desde el inicio del segmento.
Pgina 35
COMMON
MEMORY
AT address
Si ningn atributo de combinacin es proporcionado, el segmento tendr un atributo PRIVATE (Privado). Los segmentos que tienen el mismo nombre no son combinados. Cada segmento recibe su propio segmento fsico cuando es cargado en memoria. Aunque un nombre de segmento puede ser usado ms de una vez en un archivo fuente, cada definicin de segmento que usa el mismo nombre debe tener exactamente los mismos atributos o atributos que no caen en conflictos. Si los atributos son dados para una definicin de segmento inicial, las definiciones subsecuentes para ese segmento no necesitan especificar los atributos. Normalmente en un programa deber proporcionarse al menos un segmento de pila (teniendo un atributo de combinacin STACK). Si no se declara segmento de pila, el ligador generalmente desplegar un mensaje de precaucin. Deber ignorarse este mensaje si se
MC Genaro Alberto Gmez Chi. Pgina 36
Finaliza el segmento cuyo nombre es DATOS, y que anteriormente debi ser iniciado con una directiva SEGMENT. Cuando se utilizan directivas de segmento estndar, debe finalizarse explcitamente todos los segmentos que se definan. La directiva ASSUME ASSUME le dice a Turbo Assembler qu segmento inicializa un registro de segmento dado. Una directiva ASSUME CS: se requiere en todos los programas que usan las directivas de segmento estndar, debido a que TASM necesita conocer el segmento de cdigo para inicializar un programa ejecutable. Adems, usualmente tambin se necesitan directivas ASSUME DS: y ASSUME ES: para que Turbo Assembler sepa qu localizaciones de memoria pueden direccionarse en un momento dado.
Pgina 37
SEGMENT WORD 'CODE' ASSUME cs:Code ProgramStart: mov ax,Data1 mov ds,ax ;Inicializa DS con Data1 ASSUME ds:Data1 mov ax,[Var2] ;Trata de cargar Var2 en AX --Esto ;causar un error, puesto que Var2 ;no puede ser encontrado en el ;segmento Data1 ... mov ah,4Ch int 21h Code ENDS END ProgramStart
Durante el ensamblado de este programa, ocurrir un error debido a que el cdigo trata de acceder la variable de memoria VAR2 cuando el registro DS est puesto al segmento DATA1, y VAR2 no puede ser direccionado a menos que DS sea puesto al segmento DATA2. Es importante entender que TASM no sabe en ese momento que DS ha sido puesto al segmento DATA1; en cambio, usando el enunciado ASSUME, se le dice a Turbo Assembler que haga esa suposicin. ASSUME es la manera en que se le dice al ensamblador qu registros de segmento estn inicializados en un momento dado, de tal forma que TASM puede hacerte saber cundo se ha intentado algo imposible. Sin embargo, todos los errores de este tipo no pueden ser atrapados por Turbo Assembler. Siempre que una referencia a memoria involucra una variable de memoria con nombre, tal como las variables VAR1 y VAR2 anteriores, TASM puede checar la validez de la referencia, puesto que cada variable de memoria con nombre est explcitamente asociada con un segmento. No hay forma de que el ensamblador pueda saber qu segmento pretende acceder una instruccin como esta:
mov al,[bx]
Pgina 38
ProgramStart: mov ax,Data1 mov ds,ax; Inicializa DS con Data1 ASSUME ds:Data1 mov ax,Data2 mov es,ax ASSUME es:Data2 mov ax,[Var2] ;Trata de cargar Var2 en AX --Esto ; causar un error, puesto que Var2 ;no puede ser encontrado en el ;segmento Data1 ... mov ah,4Ch int 21h Code ENDS END ProgramStart
Al ensamblar este programa TASM no reporta ningn error, pero no significa que est permitiendo al programador hacer un error. Lo que hace el ensamblador es modificar la lnea
mov ax,[Var2]
Para acceder VAR2 relativo al registro de segmento ES en vez del registro de segmento DS. Las dos directivas ASSUME han informado a TASM que DS est puesto al segmento DATA1 y que ES est usando el segmento DATA2. Entonces, cuando la instruccin MOV intenta acceder a VAR2, que est en el segmento DATA2, Turbo Assembler concluye correctamente que no hay manera de que VAR2 pueda ser accesada relativa a DS; sin embargo, VAR2 puede
MC Genaro Alberto Gmez Chi. Pgina 39
Pgina 40
ByteVar DB WordVar DWordVar QWordVar TWordVar ... mov mov int ... add ... add adc
;2 bytes (1 palabra) ;4 bytes (1 doble palabra) ;8 bytes (1 quadword) ;10 bytes ;# Fn DOS de salida en pantalla ; Carcter a desplegar ;Invoca al DOS para desplegar car.
Inicializacin de arreglos Pueden aparecer mltiples valores en una sola directiva de definicin de datos. Por ejemplo:
Arreglo DW 0, 1, 2, 3, 4
Crea un arreglo de cinco elementos (de una palabra de tamao) cuyo nombre es ARREGLO. Cualquier nmero de valores que se ajusten en una lnea puede ser usado con las directivas de definicin de datos. En caso de que un arreglo sea demasiado grande como para ajustarse en una sola lnea, puede declararse en varias lneas, sin requerir definir etiquetas para cada una de las lneas de definicin de datos; solamente se define la etiqueta en la primera lnea del arreglo. Por ejemplo, el siguiente cdigo crea un arreglo de elementos de doble palabra llamado ARRCUADRADOS, consistente de los cuadrados de los primeros 15 nmeros enteros:
MC Genaro Alberto Gmez Chi. Pgina 41
Turbo Assembler permite definir bloques de memoria inicializados a un valor dado con el operador DUP. Por ejemplo,
BlankArray DW 100h DUP(0)
Crea un arreglo denominado BLANKARRAY, consistiendo de 256 palabras (decimales) inicializados a cero. De la misma manera, la siguiente lnea crea un arreglo de 92 bytes, cada uno inicializado con el carcter A:
ArrayOfA DB 92 DUP('A')
Inicializando cadenas de caracteres Los caracteres son operandos vlidos para las directivas de definicin de datos, as que puede definirse una cadena de caracteres utilizando los criterios establecidos anteriormente. Ejemplo
Cadena DB 'A', 'B', 'C', 'D'
Las cadenas de caracteres se definen como arreglos con elementos del tamao de un byte, puesto que cada carcter debe almacenarse en este tipo de datos. Turbo Assembler permite definir una cadena de caracteres de una manera similar a como se realiza en los lenguajes de alto nivel, agrupando los caracteres dentro de comillas simples:
Cadena DB 'ABCD'
Si se desea utilizar los caracteres de Retorno de Carro/Alimentacin de Lnea, deben listarse separadamente sus correspondientes valores. La siguiente lnea define una cadena de texto seguida de un carcter de Retorno de Carro, un carcter de Alimentacin de Lnea y un byte cero, de terminacin de cadena, tal y como se hace en el Lenguaje C.
HelloMsg DB 'Hola, mundo', 0Dh, 0Ah, 0
Pgina 42
Siempre que una etiqueta es usada como un operando en una directiva de definicin de datos, es el valor de la etiqueta el que se usa, no el valor almacenado en esa etiqueta. En el ejemplo anterior, el valor inicial de BUFFERPTR es el desplazamiento de BUFFER en el segmento .DATA, no el valor cero que est almacenado en BUFFER. Datos no inicializados Algunas veces no tiene sentido asignar un valor inicial a una variable de memoria. Por ejemplo, supngase que un programa lee los siguientes diez caracteres escritos en el teclado en un arreglo llamado KEYBUFFER:
... mov mov cx,10 bx,OFFSET KeyBuffer ;# de cars. a leer ;Los cars. a ser ;ledos ; almacenados en KeyBuffer
ah,1 ;# Fn DOS para entrada del teclado 21h ;Obtiene el siguiente carcter [bx],al ;Guarda el carcter bx ;Apunta a la sig. Localidad de ; Almacenamiento para sig. car. GetKeyLoop
Pero realmente no tiene sentido, puesto que los valores iniciales en KEYBUFFER son inmediatamente sobrescritos en el ciclo GETKEYLOOP. Lo que realmente se necesita es una manera de definir variables de memoria sin inicializar. Turbo Assembler proporciona esta capacidad con el signo de interrogacin (?).
MC Genaro Alberto Gmez Chi. Pgina 43
Esta lnea reserva 10 bytes iniciando en la etiqueta KEYBUFFER, pero no inicializa estos bytes con valor alguno. Obviamente, el programador debe asegurarse de inicializar una variable de memoria no inicializada en la definicin, antes de usarla en el programa. Localizaciones de memoria con nombre Como vimos anteriormente, con la directiva de definicin de datos DB se asigna nombre a una variable de memoria. La directiva LABEL es otra manera de asignar un nombre de una localidad de memoria, pero sin localizar almacenamiento alguno. LABEL permite especificar el nombre de una etiqueta y su tipo sin tener que definir dato alguno. Por ejemplo, el arreglo KEYBUFFER puede definirse tambin de la siguiente forma:
KeyBuffer ... LABEL BYTE DB 10 DUP(?) ...
Una etiqueta definida con LABEL puede ser de los siguientes tipos:
BYTE WORD DWORD FWORD PWORD QWORD TBYTE NEAR FAR PROC UNKNOWN
LOS TIPOS DE DATOS BYTE, WORD, DWORD, FWORD, PWORD, QWORD Y TBYTE son autoexplcitos, etiquetando elementos de 1, 2, 4, 6, 8 y 10 bytes, respectivamente. A continuacin se presenta un ejemplo, donde una variable de memoria es inicializada como un par de bytes, pero es accedida como una palabra:
... .DATA LABEL WORD DB 1,2 ... .CODE ...
WordPtr
Pgina 44
2.
En este caso, AL es cargado con 1 (el primer byte de WORDPTR) y AH es cargado con
Las etiquetas definidas mediante la directiva LABEL pueden utilizarse en expresiones de directivas de definicin de datos. Por ejemplo, las siguientes lneas inicializan la variable WORDARRAYLENGTH con la longitud en bytes de WORDARRAY:
... WordArray DW 50 DUP(0) WordArrayEnd LABEL WORD WordArrayLength DW (WordArrayEnd - WordArray) ... Si se desea calcular la longitud de WORDARRAY
en palabras de lugar de calcularlo en bytes, nicamente hay que dividir la longitud en bytes por dos;
WordArrayLengthInWords DW (WordArrayEnd - WordArray)/2
NEAR y FAR son usados en el cdigo para seleccionar el tipo de llamada a procedimiento o bifurcacin (salto) necesitado para alcanzar determinada etiqueta. Por ejemplo, en el siguiente ejemplo el primer JMP es un salto far (cargando CS e IP) debido a que es una etiqueta FAR, mientras que el segundo salto es un salto near (cargando nicamente IP) debido a que es una etiqueta NEAR:
... .CODE ... LABEL FAR LABEL NEAR mov ax,1 ... jmp FarLabel ... jmp NearLabel ...
FarLabel NearLAbel
Cuando se usan las directivas de segmento simplificadas, PROC es una manera conveniente de definir una etiqueta en el tamao apropiado, NEAR o FAR, para el modelo de cdigo actual. Cuando el modelo de memoria es TINY, SMALL o COMPACT, LABEL PROC es similar a LABEL NEAR; cuando el modelo de memoria es MEDIUM, LARGE o HUGE, LABEL PROC es similar a LABEL FAR. Esto significa que si se cambia el modelo de memoria, se pueden cambiar ciertas etiquetas automticamente tambin. Por ejemplo, en
.MODEL small
Pgina 45
EntryPoint
ENTRYPOINT es NEAR, pero si se cambia el modelo de memoria a LARGE, ENTRYPOINT se convertir a FAR. Normalmente el programador usa la directiva PROC en lugar de LABEL, para definir la clase de puntos de entrada que se desee cambiar conforme cambie el modelo de memoria; sin embargo, algunas veces se necesitar ms de un punto de entrada a una subrutina y entonces puede hacerse uso de LABEL, adems de PROC. Finalmente, LABEL UNKNOWN es simplemente una forma de decir que no se sabe qu tipo de datos tendr la etiqueta que se define. Modos de direccionamiento Los operandos de las instrucciones pueden especificarse en diferentes formas conocidas como modos de direccionamiento. Los modos de direccionamiento le dicen al microprocesador cmo calcular el valor actual del operando de una instruccin en tiempo de ejecucin. Existen 3 modos de direccionamiento: inmediato, de registro y de memoria. Los operandos de memoria pueden ser divididos en dos grupos, operandos de memoria directos y operandos de memoria indirectos. El microprocesador decodificar el modo de direccionamiento que est siendo referenciado por la sintaxis de la operacin. Aunque dos enunciados pueden ser similares y sus mnemnicos de instruccin sean los mismos, el ensamblador producir cdigo mquina diferente para una instruccin cuando es usada con diferentes modos de direccionamiento. Los mnemnicos de instruccin en lenguaje ensamblador pueden tener dos o ms operandos que siempre son trabajados de derecha a izquierda. El operando de la derecha es el operando fuente. Especifica el dato que ser utilizado, pero no cambiado, en la ejecucin de la instruccin. El operando de la izquierda es el operando destino. Especifica el dato que ser utilizado y posiblemente cambiado por la instruccin. Direccionamiento inmediato Consisten de datos numricos constantes que son conocidos o calculados en tiempo de ensamble del programa. El dato a ser utilizado se especifica como un valor constante
MC Genaro Alberto Gmez Chi. Pgina 46
Pgina 48
Pgina 49
Instrucciones de transferencia de datos Las instrucciones de transferencia de datos nos permiten mover datos de un punto a otro. En general, los datos pueden ser movidos en tamaos de un byte o una palabra a la vez. Mover los datos puede parecer un concepto demasiado simple, pero la situacin se complica debido a los diferentes modos disponibles para direccionar los datos a ser movidos. La instruccin MOV mueve un dato entre los registros internos del 8086 y la memoria. Verdaderamente, ms que mover la instruccin MOV almacena una copia del operando fuente en el operando destino, sin afectar al primero. La sintaxis de esta instruccin es la siguiente:
mov destino fuente
Puede interpretarse esta instruccin de la siguiente forma: mueve el contenido de fuente hacia destino. Es importante subrayar que, por lo general, las instrucciones de
MC Genaro Alberto Gmez Chi. Pgina 50
Una constante Una expresin que evale a un valor constante Un registro de propsito general Una localidad de memoria accesada con cualquiera de los modos de direccionamiento de memoria discutidos anteriormente. Como operando destino puede usarse cualquier registro de propsito general o una localidad de memoria. Con la instruccin MOV es posible copiar valores de tamao BYTE o palabra (WORD). En muchos casos, los operandos de MOV le dicen a Turbo Assembler exactamente qu tamao de datos ser utilizado. Si un registro de segmento est involucrado en la operacin de copia, entonces el tamao de los datos debe ser del tamao del registro. Por ejemplo, los tamaos de los datos de las siguientes instrucciones son claros:
... mov mov ... al,1 dx,1 ;Operandos de tamao byte ;Operandos de tamao palabra
De manera similar, las localizaciones de memoria tienen un tamao inherente, de tal forma que los tamaos de los datos son conocidos por TASM:
... .DATA DB DW ... .CODE ... mov mov ...
TestChar TempPtr
? TestChar
[TestChar],'A' [TempPtr],0
Algunas veces, los operandos de la instruccin MOV no tendrn un tamao definido inherente. Por ejemplo, en la siguiente instruccin, el ensamblador no tiene forma de conocer el tamao de los operandos involucrados en MOV.
MC Genaro Alberto Gmez Chi. Pgina 51
Y, de hecho, TASM determinar que no tiene forma de ensamblar la instruccin. Esta situacin se repite cuando el programador considera conveniente acceder temporalmente una variable del tamao de una palabra como un byte o viceversa. TASM proporciona los medios para definir flexiblemente los tamaos de los datos en la forma de los operadores WORD PTR y BYTE PTR. WORD PTR le dice a Turbo Assembler que trate un operando de memoria determinado dimensionado como una palabra, y BYTE PTR le dice a TASM que accese un operando de memoria como un operando de tamao byte, sin considerar su tamao predefinido. Por ejemplo, la ltima lnea de cdigo puede reescribirse para almacenar un valor 1 de tamao palabra en la direccin de memoria apuntada por BX.
mov WORD PTR [BX],1
WORD PTR y BYTE PTR no tienen sentido cuando son aplicados a registros, puestos que los registros son de tamao fijo. Accediendo a registros de segmento Aunque la instruccin MOV puede utilizarse para mover valores a y desde registros de segmento, este es un caso especial, ms limitado que los otros usos de MOV. Si un registro de segmento es un operando de MOV, el otro operando debe ser un registro de propsito general o una localidad de memoria. No es posible cargar directamente una constante en un registro de segmento y un registro de segmento no puede ser copiado directamente a otro registro de segmento. Por ejemplo, a continuacin se muestran dos formas de inicializar el registro de segmento ES con el valor del segmento .DATA.
DataSeg DW ... .DATA @data ... .CODE ... mov ax,@data mov es,ax ... mov es,[DataSeg] ...
Es importante notar que la instruccin MOV no es la nica instruccin que limita el uso de los registros de segmento; la mayora de las instrucciones no pueden hacer uso de los registros de segmento como operandos.
MC Genaro Alberto Gmez Chi. Pgina 52
Carga el registro AX con el contenido de la palabra en el desplazamiento BP+4 en el segmento de pila. Acceso a puertos de Entrada/Salida Las instrucciones IN y OUT son usados para acceder los puertos de entrada/salida del 8086. Los dispositivos externos como terminales, impresoras y manejadores de disco, se comunican con el microprocesador va los puertos de E/S. Un byte de 8 bits o una palabra de 16 bits puede ser transferido a travs de un puerto de E/S. Dentro del 8086, los datos deben ser enviados siempre (o recibidos) del registro acumulador, AX. En los casos en que se transfieren nicamente 8 bits, se usa la mitad baja del acumulador, AL. La direccin de E/S se especifica como el contenido del registro DX, o como un valor inmediato contenido en la instruccin. En el caso posterior, solamente los primeros 256 puertos de E/S (direcciones de E/S 00h a FFh) pueden ser accesadas. Se muestran a continuacin ejemplos de uso de las instrucciones IN y OUT.
in out mov al,2Fh ;Entrada de un byte del puerto 2Fh 5,al ;Salida de un byte hacia el ;puerto 5 dx,3FCh
Pgina 53
Intercambiando datos La instruccin XCHG intercambia el contenido de sus dos operandos. El segundo operando de la instruccin XCHG debe ser siempre un registro. El primer operando puede ser accesado usando cualquiera de los modos de direccionamiento descritos en la unidad anterior, excepto el modo inmediato. La operacin de XCHG se ilustra a continuacin:
mov mov xchg ax,5 bx,10 ax,bx ; AX = 5 ; BX = 10 ; AX = 10, BX = 5
La instruccin XLATB, o trasladar, realiza una operacin de bsqueda en tabla. El contenido del registro AL se agrega al contenido del registro BX, y el valor resultante es usado como una direccin de memoria. El byte en esta direccin de memoria se coloca en el registro AL. Normalmente, esta instruccin se utiliza inicializando el registro BX para que apunte al inicio de la tabla de traduccin. La instruccin XLATB despus convierte el valor del byte en AL a su correspondiente valor de la tabla. Instrucciones aritmticas Las instrucciones aritmticas son usadas para realizar clculos aritmticos. Las instrucciones ADD, SUB y CMP tienen dos operandos. Como siempre, el primer operando especificado servir como destino para el resultado. As, la instruccin
add ax,bx
Agregar el contenido del registro AX al contenido del registro BX y colocar el resultado en el registro AX. Similarmente, la instruccin
sub ax,bx
Substraer el contenido del registro BX del contenido del registro AX y colocar el resultado en el registro AX. La instruccin de comparacin, CMP, realiza la misma operacin que la instruccin SUB, pero sin afectar a ninguno de los operandos. Es usada principalmente para activar las banderas, tal como se explic anteriormente. Las instrucciones INC, DEC y NEG utilizan slo un operando. Puede ser direccionado usando cualquiera de los mtodos de direccionamiento de memoria, excepto el inmediato. La instruccin INC (incremento) incrementa en uno a su operando.
Pgina 54
La flexibilidad de estas instrucciones se ve incrementada por nuestra habilidad para usarlas con operandos de byte o palabra. En adicin, todas las instrucciones aritmticas, afectan varios bits del registro bandera para indicar el estado de su resultado. Las instrucciones de transferencia condicional pueden utilizarse para probar estos bits y cambiar el flujo de un programa. La multiplicacin y la divisin son funciones avanzadas del microprocesador y son un poco menos flexibles de usar que las funciones aritmticas ms comunes discutidas anteriormente. El operando destino es siempre el registro acumulador (AX), por lo que slo un operando fuente se codifica con la instruccin. Es importante aclarar que cuando se multiplica un byte por un byte, el resultado puede ser tan grande como una palabra. Por lo tanto, en una operacin de multiplicacin de bytes, el operando fuente (un byte) se multiplica por el contenido del registro AL, y el resultado (una palabra) es colocado en el registro AX. En el caso de una operacin de multiplicacin entre palabras, el operando fuente (una palabra) se multiplica por el contenido del registro AX. El resultado puede ser tan grande como 32 bits: la palabra de orden bajo se coloca en el registro AX y la palabra de orden superior se coloca en el registro DX. Inversamente, en una operacin de divisin utilizando bytes, el numerador, tomado como el registro entero AX, se divide por el operando fuente de un byte. El cociente es colocado en AL, y el residuo se coloca en AH. Una operacin de divisin utilizando palabras, asume un numerador de 32 bits, con la palabra de alto orden tomado del registro DX y la palabra de bajo orden tomado del registro AX. Este numerador es dividido por el operando fuente de una palabra. El cociente se coloca en AX y el residuo en DX. Las instrucciones MUL y DIV anteriormente explicadas realizan multiplicacin y divisin sin signo, respectivamente. La multiplicacin y la divisin signada pueden realizarse con las versiones de operandos de tipo entero de estas instrucciones, llamadas IMUL e IDIV. Instrucciones lgicas Las instrucciones aritmticas siempre asumen que sus operandos representan informacin numrica. Por el contraste, las instrucciones lgicas tratan a sus operandos como simples cadenas de bits. La instruccin NOT simplemente invierte cada bit en su operando, cambiando todos los ceros a unos y todos los unos a ceros. Las instrucciones AND, OR y XOR usan dos operandos: las combinaciones de operandos disponibles son las mismas que las disponibles
MC Genaro Alberto Gmez Chi. Pgina 55
La instruccin TEST realiza la misma funcin que la instruccin AND, con la diferencia que el operando destino no es alterado. Es usado principalmente para probar si uno o ms bits especficos en un byte o palabra estn puestos (son uno). Las instrucciones lgicas siempre aclaran (ponen en cero) las banderas de acarreo (CF) y desbordamiento (OF). Adems, ellas ponen (hacen uno) la bandera de cero (ZF) para indicar si el resultado fue cero o no. Las instrucciones de desplazamiento (shift) mueven los bits hacia un lado (esto es, de izquierda a derecha o de derecha a izquierda) dentro de sus operandos. SHL (desplazamiento a la izquierda) mueve cada bit del operando destino un lugar hacia la izquierda, o hacia el bit ms significativo. El bit ms significativo es desplazado fuera del operando hacia la bandera de acarreo; el bit menos significativo es llenado con el bit cero. La figura 2.7 muestra cmo el valor 10010110b (96h) almacenado en el registro AL es desplazado hacia la izquierda con la instruccin
shl al, 1
El resultado es el valor 00101100b (2Ch), que se deposita en el mismo registro AL. La bandera de acarreo almacenar el valor 1, inicialmente en el bit ms significativo de AL. El uso ms comn de la instruccin potencias de dos.
SHL
Pgina 56
AL Bandera de acarreo
La instruccin SHR (desplazamiento a la derecha) es similar a SHL, slo que realiza el desplazamiento de 1 o cl bits hacia la derecha. El bit menos significativo es colocado en la bandera de acarreo y el bit ms significativo se rellena con cero. La instruccin SHR es utilizada para realizar divisiones sin signo por potencias de dos.
AL Bandera de acarreo
Instrucciones de transferencia de control Saltos incondicionales La instruccin fundamental de bifurcacin en los microprocesadores de la familia 80x86 es la instruccin JMP. La instruccin JMP instruye al 8086 para que ejecute la instruccin en la etiqueta destino como la instruccin que sigue a JMP. Por ejemplo, cuando finaliza la ejecucin del siguiente segmento de cdigo
... mov jmp AddOneToAX: inc ax,1 AddTwoToAX ax
Pgina 57
ADD
JMP
Instruye al 8086 para que se le asigne al apuntador de instrucciones, el registro IP, el desplazamiento de la etiqueta AddTwoToAX, para que la siguiente instruccin a ejecutar sea
add ax,2
Algunas veces junto con la instruccin JMP se utiliza el operador SHORT. JMP usualmente utiliza un desplazamiento de 16 bits para apuntar a la etiqueta destino; SHORT instruye a TASM para que utilize un desplazamiento de 8 bits, ahorrando un byte por instruccin JMP. Por ejemplo, el ltimo ejemplo es dos bytes ms pequeo con las siguientes modificaciones:
... mov jmp AddOneToAX: inc jmp AddTwoToAX: add AXIsSet: ... ax,1 SHORT AddTwoToAX ax SHORT AXIsSet ax,2
La desventaja en usar el operador SHORT es que algunos saltos cortos pueden alcanzar a las etiquetas que se encuentran nicamente dentro del alcance de 128 bytes de la instruccin JMP, de tal forma que TASM puede informar que no puede alcanzar una etiqueta determinada debido a que est fuera del alcance de la instruccin JMP que utiliza un operador SHORT. nicamente tiene sentido utilizar saltos SHORT cuando se hacen saltos hacia adelante en el cdigo, debido a que TASM inteligentemente hace cortos los saltos hacia atrs cuando estn dentro del alcance del destino; los saltos hacia atrs que estn ms all de los 128 bytes de la instruccin JMP automticamente son tomados como saltos con desplazamiento de 16 bits.
MC Genaro Alberto Gmez Chi. Pgina 58
... CSeg1 SEGMENT ASSUME cs:CSeg1 ... FarTarget LABEL FAR ... Cseg1 ENDS ... CSeg2 SEGMENT ASSUME cs:CSeg2 ... jmp FarTarget ; este es un salto far ... Cseg2 ENDS ...
Realiza un salto a otro segmento de cdigo. Finalmente, puede saltarse a una direccin almacenada en un registro o en una variable de memoria. Por ejemplo,
... mov jmp ... TestLabel: ... ax, OFFSET TestLabel ax
Saltos condicionales Los saltos como los descritos en la seccin anterior son nicamente parte de lo necesario para escribir programas tiles. La mayor parte de los programas se benefician de los saltos basados en la toma de decisiones. Una instruccin de salto condicional puede
MC Genaro Alberto Gmez Chi. Pgina 59
Primero, el cdigo obtiene una tecla del teclado a travs de la funcin 1 del DOS. Despus, utiliza la instruccin CMP para comparar el carcter ledo con la letra A. La instruccin CMP hace que la bandera de cero (ZF) sea 1, si el resultado de la comparacin es igual, o sea aclarada (0), si la comparacin evala a diferente. La instruccin JE es una instruccin de salto condicional que salta a la etiqueta destino slo si la bandera de cero es 1. De otra forma, se ejecutar la instruccin inmediata a la instruccin JE, en este caso una instruccin MOV. La bandera de cero ser 1 slo cuando se presione la tecla A, y nicamente entonces saltar el 8086 a la instruccin PUSH en la etiqueta AWasTyped. El 8086 proporciona una gran variedad de saltos condicionales, proporcionando la habilidad de saltar conforme el estado de cualquier bandera o combinacin de banderas. Puede saltarse condicionalmente respecto al estado de las banderas de cero, acarreo, signo, paridad y desbordamiento y de acuerdo a la combinacin de banderas que indique el resultado de operaciones con nmeros con signo.
Nemnico JA JAE JB JBE JE JNE JG JGE JL JLE Significado Sinnimo Significado Salta si es superior JNBE Salta si no es inferior o igual Salta si es superior o igual JNB Salta si no es inferior Salta si es inferior JNAE Salta si no es superior o igual Salta si es inferior o igual JNA Salta si no es superior Salta si es igual JZ Salta si el resultado es cero Salta si no es igual JNZ Salta si el resultado no es cero Salta si es mayor que JNLE Salta si no es menor o igual que Salta si es mayor o igual que JNL Salta si no es menor que Salta si es menor que JNGE Salta si no es mayor o igual que Salta si es menor o igual que JNG Salta si no es mayor que Tabla 2.7. Nemnicos de instruccin de saltos condicionales y sus sinnimos
Pgina 60
No mayor que JNA Tabla 2.8 Pruebas aritmticas tiles despus de una instruccin CMP.
Instrucciones de iteracin Una iteracin es un bloque de cdigo que finaliza con un salto condicional, de tal forma que el cdigo puede ser ejecutado repetidamente hasta que la condicin de terminacin sea alcanzada. El microprocesador 8086 proporciona varias instrucciones especiales para realizar iteraciones. La instruccin loop Supngase que se desea imprimir una cadena de una longitud de 10 caracteres. Esto podra ser realizado con el siguiente cdigo: Sin embargo, existe una forma ms fcil de hacerlo mediante la instruccin LOOP. La instruccin LOOP decrementa el contenido del registro CX y finaliza la iteracin si CX ha alcanzado el valor de cero. Si CX es diferente de cero, entonces se ejecutar la instruccin indicada por la etiqueta destino, operando de la instruccin LOOP. La instruccin LOOPE hace lo mismo que LOOP, excepto que LOOPE finalizar el ciclo si CX llega a cero o si la bandera de cero es 1. Es importante recordar que la bandera de cero es 1, cuando el resultado de una operacin aritmtica es cero o si los dos operandos en la ltima comparacin son iguales. La instruccin LOOPNE, por su parte, finalizar el ciclo si CX es cero o la bandera de cero es 0.
MC Genaro Alberto Gmez Chi. Pgina 61
La instruccin LODS, que carga un byte o palabra de memoria hacia el acumulador, puede usarse para trasladar bytes, con su variante LODSB, o palabras, utilizando LODSW. LODSB carga el byte direccionado por DS:SI hacia AL, e incrementa o decrementa SI dependiendo del estado de la bandera de direccin. Si la bandera de direccin es 0 (puesta con CLD), entonces SI es incrementado; si la bandera de direccin es 1 (puesta con STD), entonces SI es decrementado. Es importante notar que la bandera de direccin controla la direccin en que los registros apuntadores son modificados para todas las instrucciones de cadena. Por ejemplo, la instruccin LODSB en la siguiente porcin de cdigo
... cld mov lodsb ...
si,0
Carga AL con el contenido del byte en el desplazamiento 0 del segmento de datos e incrementa SI por 1. Es equivalente a
...
Pgina 62
Sin embargo,
lodsb
LODSW es similar a LODSB, salvo que la palabra direccionada por DS:SI es cargada en AX y SI es incrementado o decrementado por 2, en lugar de por 1. Por ejemplo,
carga la palabra en el desplazamiento 10 del segmento de datos hacia AX y despus decrementa SI por 2.
STOS
es el complemento de LODS. Escribe un valor de byte o palabra del acumulador hacia una localidad de memoria apuntada por ES:DI, e incrementa o decrementa DI. STOSB escribe el byte en AL hacia la localidad de memoria apuntada por ES:DI y despus incrementa o decrementa DI, dependiendo de la bandera de direccin. Por ejemplo,
STOS
di,0FFFFh al,55h
Escribe el valor 55h al byte en el desplazamiento 0FFFFh en el segmento apuntado por ES y despus decrementa DI a 0FFFEh. STOSW hace lo mismo, al escribir un valor 16 bits de AX hacia la direccin ES:DI y despus incrementa o decrementa DI por 2. Por ejemplo:
... cld mov mov stosw di,0FFEh ax,102h
Pgina 63
Escribe el valor de palabra 102h de AX hacia el desplazamiento 0FFEh en el segmento apuntado por ES y despus incrementa DI a 1000h.
LODS y STOS trabajan juntos para el copiado de buffers. Por ejemplo, la siguiente subrutina copia una cadena terminada en cero, en DS:SI hacia la cadena ES:DI.
; Subrutina para copiar una cadena terminada con ASCII cero hacia otra cadena. ; Entrada: ; DS:SI - Cadena fuente ; ES:SI - Cadena destino ; Salida: ; Ninguna ; Registros destrudos: ; AL,SI,DI CopyString PROC cld ; Hace qu SI y DI se incremente con ; la inst. de cadena CopyStringLoop: lodsb ; Obtiene carcter de la cadena fuente stosb ; Almacena carcter en la cadena destino cmp al,0 ; Es el carcter 0 para terminar ; la cadena? jnz CopyStringLoop ; no, ve por el siguiente ; carcter ret CopyString ENDP
MOVS
es similar a LODS y STOS en una sola instruccin. MOVS lee el byte o palabra almacenados en DS:SI y despus escribe el valor en la direccin ES:DI. El byte o palabra no pasa por registro alguno y, de esta manera, AX no es modificado. La siguiente porcin de cdigo muestra como funciona MOVS para copiar bloques de bytes que no estn terminados con el ASCII cero.
MOVS
... mov mov mov mov mov mov mov cld CopyLoop:
cx,ARRAY_LENGTH_IN_WORDS si,OFFSET SourceArray ax,SEG SourceArray ds,ax di,OFFSET DestArray ax,SEG DestArray es,ax
Pgina 64
Prefijos de repeticin de cadenas Mientras el cdigo en el ltimo ejemplo parece eficiente, existe una manera de realizar la misma tarea de mover bloques de byte en una sola instruccin. El 8086 cuenta con la opcin de prefijo de repeticin, REP, en las instrucciones de cadena.
REP no es una instruccin; es un prefijo de instruccin. Los prefijos de instruccin modifican la operacin de la siguiente instruccin en el cdigo. REP indica que la siguiente instruccin de cadena se ejecute repetidamente hasta que el registro CX sea cero. (Si CX es cero cuando la instruccin a repetir inicia, la instruccin se ejecuta cero veces - en otras palabras no hace nada).
Esta instruccin simple mover un bloque de hasta 65,535 palabras (0FFFFh) de la direccin de memoria iniciando en DS:SI a la localidad en ES:DI.
REP puede ser usada con LODS y STOS, como con MOVS (y tambin con SCAS y CMPS). Es importante aclarar que REP nicamente funciona con las instrucciones
de
CMPS
es usada para inspeccionar la memoria buscando una equivalencia o no equivalencia de un valor particular de tamao byte o palabra. Como con todas las instrucciones de cadena SCAS viene en dos formas: SCASB y SCASW.
SCAS
Pgina 65
El siguiente ejemplo, encuentra la primera ocurrencia de la letra 't' minscula en la cadena de texto TEXTSTRING.
... .DATA TextString DB 'Este es un test',0 TEXT_STRING_LENGTH EQU ($-TextString) ... .CODE ... mov ax,@data mov es,ax mov di,OFFSET TextString ;ES:DI apunta al ; inicio de TextString mov al,'t' ; Carcter a buscar mov cx,TEXT_STRING-LENGTH ; Longitud de la cadena ; a inspeccionar cld ScanLoop: scasb ; El contenido de ES:DI es igual a 't' je Found_t ; S; se encontr 't' loop ScanLoop ; No se encontr 't' ... ; Se encontr una 't' Found_t: dec di
Ntese que DI es decrementado despus de encontrar 't', lo que refleja que, despus de ejecutar la instruccin de cadena, los registros apuntador (DI, SI, o ambos) no apuntan a la localidad de memoria recientemente accesada, sino que apuntan a la siguiente (o anterior) localidad de memoria de la que se acces. En el ejemplo anterior, DI apunta al byte que sigue a la localidad de memoria donde se encuentra 't' que fue encontrada y debe ser ajustada para compensar este desfasamiento. Una porcin de cdigo similar a la anterior, pero sin utilizar instrucciones de cadena, se muestra a continuacin:
... ScanLoop: cmp je
es:[di],al Found_t
Pgina 66
En este ejemplo, el registro DI es incrementado despus de que la instruccin ejecuta para evitar alterar las banderas con la instruccin INC.
se
Es importante hacer la observacin que las instrucciones de cadena nunca modifican las banderas para reflejar los cambios que realizaron a SI, DI y/o CX. LODS, STOS y MOVS no modifican ninguna bandera, y SCAS y CMPS nicamente cambian las banderas de acuerdo a los resultados de las comparaciones realizadas. Otros prefijos de repeticin El prefijo REP pudo utilizarse en el ejemplo de encontrar la 't' en la cadena. Sin embargo, puede desearse agregar flexibilidad a la comparacin y desear detener la iteracin cuando se encuentre una equivalencia o desigualdad entre los valores a comparar. Dos variantes de REP pueden ser utilizadas con SCAS (y tambin con CMPS): REPE y REPNE.
REPE (tambin conocida como REPZ) le dice al 8086 que repita SCAS (o CMPS) hasta que CX sea cero u ocurra una desigualdad entre los valores a comparar. REPE puede ser traducido como el prefijo "repite mientras sean iguales". Por otra parte, REPNE (conocido tambin como REPNZ) le dice al 8086 que repita SCAS (o CMPS) hasta que CX sea cero u ocurra una equivalencia. Puede tomarse a REPNE como el prefijo "repite mientras no sean iguales".
La siguiente porcin de cdigo utiliza una instruccin TEXTSTRING en busca del carcter 't'.
... mov mov mov mov mov cld repne
SCASB
para inspeccionar
ax,@data es,ax di,OFFSET TextString ; ES:DI apunta al inicio de TextString al,'t' ; Carcter a buscar cx,TEXT_STRING_LENGTH ; Longitud de la cadena a inspeccionar ; Inspecciona incrementando DI scasb ; Inspecciona la cadena completa mientras ; ES:DI y AL no sean iguales je Found_t ; S, se encontr ; No se encontr 't' ... ; Se encontr 't' Found_t: dec di ; Hace que apunte exactamente a 't' ...
Pgina 67
tamao.
CMPSB,
La siguiente porcin de cdigo prueba si los primeros 50 elementos de dos arreglos con elementos de tamao palabra son idnticos, usando REP CMPSW:
... mov si,OFFSET Array1 mov ax,SEG Array1 mov ds,ax mov di,OFFSET Array2 mov ax,SEG Array2 mov es,ax mov cx,50 cld repe cmpsw jne ArraysAreDifferent ; Los primeros 50 elementos son idnticos ... ; Al menos un elemento difiere entre los dos arreglos ArraysAreDifferent: dec si dec si dec di dec di ...
Instrucciones de control del procesador La familia de procesadores 80x86 proporciona instrucciones para el control del procesador. La tabla x.xx muestra las instrucciones ms importantes de este grupo que permiten establecer o aclarar las banderas de acarreo, direccin e interrupcin de manera directa. Adems, existe una instruccin de complemento de la bandera de acarreo, CMC, que permite invertir el estado actual de la bandera de acarreo.
MC Genaro Alberto Gmez Chi. Pgina 68
Pgina 69