Ensamblador
Transcript of Ensamblador
Folleto Complementario de
Arquitectura de Máquinas Computadoras II
Programación en Lenguaje Ensamblador
Elaborado por:
Ing. José Díaz Chow
Managua, Octubre de 2013
UNIVERSIDAD NACIONAL DE INGENIERIA
RECINTO UNIVERSITARIO SIMON BOLIVAR
Facultad de Electrotecnia y Computación Departamento de Arquitectura y Sistemas
INDICE DE CONTENIDO
4. PROGRAMACION EN ENSAMBLADOR ..................................................................................... 1
4.1 EL LENGUAJE ENSAMBLADOR. .................................................................................................... 1 4.2 ALGORITMIZACIÓN Y PSEUDOCÓDIGO. ........................................................................................ 1
4.2.1 Implementación de las estructuras de control de flujo ........................................................... 2 4.3 ENSAMBLADORES Y HERRAMIENTAS DE PROGRAMACIÓN. .......................................................... 3 4.4 LA ARQUITECTURA DE LA FAMILIA IX86 ..................................................................................... 4
4.4.1 Introducción............................................................................................................................ 4 4.4.2 Organización .......................................................................................................................... 4 4.4.3 Modelo de Memoria ................................................................................................................ 5
4.5 EL LENGUAJE ENSAMBLADOR DE LA FAMILIA IX86 ..................................................................... 7 4.5.1 Formato de una sentencia en ensamblador. ........................................................................... 7 4.5.2 Palabras Reservadas .............................................................................................................. 8 4.5.3 Expresiones Constantes u Operandos inmediatos: ................................................................. 9
4.5.3.1 Constantes Enteras Simbólicas................................................................................................... 10 4.5.4 Operadores ............................................................................................................................10 4.5.5 Tipos de datos ........................................................................................................................11
4.5.5.1 Variables de Memoria ................................................................................................................ 11 4.5.5.2 Tipos de datos compuestos ......................................................................................................... 11
4.5.6 Modos de direccionamiento ...................................................................................................12 4.5.7 El Conjunto de Instrucciones .................................................................................................13
4.5.7.1 Instrucciones de Copiado de datos ............................................................................................. 13 4.5.7.2 Adición y sustracción de enteros ................................................................................................ 16 4.5.7.3 Instrucciones de Multiplicación y División: ............................................................................... 17 4.5.7.4 Instrucciones de Operaciones a nivel de BITS: .......................................................................... 19 4.5.7.5 Instrucciones de Lógica y control de programa.......................................................................... 21
4.6 LA COMPUTADORA PERSONAL BASADA EN CPUS IX86. .............................................................25 4.6.1 El video de la PC ...................................................................................................................25
4.6.1.1 La pantalla .................................................................................................................................. 25 4.6.1.2 Procesamiento básico de pantalla ............................................................................................... 25
4.6.2 La entrada estándar de la PC ................................................................................................27 4.6.2.1 Procesamiento básico de teclado ................................................................................................ 27
ANEXO A: LISTA DE PALABRAS RESERVADAS. .........................................................................................30 ANEXO B: EL CONJUNTO DE INSTRUCCIONES. ...........................................................................................32
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 1
1. PROGRAMACION EN ENSAMBLADOR
1.1 El Lenguaje Ensamblador.
Hoy día, estamos acostumbrados a programar en lenguajes de alto nivel, como C,
Pascal, Java, C# o Visual Basic, que son similares al lenguaje natural humano, pero muy
diferentes al lenguaje nativo del procesador. En los lenguajes de alto nivel, empleamos el
paradigma de programación estructurada, donde tenemos estructuras de control de
programa similares a las estructuras lógicas del pensamiento humano, que facilitan la
programación (condicionales como el if-then-else e iterativas como el while, for y
repeat), el procesador, en cambio solo nos permite una ejecución secuencial de
instrucciones, e instrucciones de salto cuando sea requerido modificar la dirección del
flujo de programa.
El único vocabulario que el procesador puede entender es su conjunto de instrucciones.
Para comunicarse efectivamente con él, un programador debe escribir su código fuente
empleando sentencias formadas por instrucciones de este conjunto, con sus operandos.
Sabemos que el CPU sólo es capaz de interpretar estas instrucciones cuando están
expresadas en binario, que es lo que llamamos lenguaje de máquina. Sin embargo, para
un ser humano, esto implicaría conocer cada código de operación y formato de cada
instrucción además de codificar cada operando correctamente, lo cual sería bastante
dificultoso además de tedioso y tardado. Para facilitar un poco el proceso de la
programación a bajo nivel, se implementó el lenguaje ensamblador, que provee
nombres mnemotécnicos para cada operación, que es más fácil de recordar para el
programador. Así, luego, un programa denominado “ensamblador”, puede convertir estos
mnemónicos y operandos en formato binario según el formato de cada instrucción.
Para programar en lenguaje ensamblador es necesario realizar un cambio de pensamiento
en nuestra forma de programar, implementando las estructuras de control de programa en
base a las instrucciones de control de flujo que nos provee el procesador.
1.2 Algoritmización y Pseudocódigo.
Para desarrollar un programa de computadora que resuelva un problema del
mundo real, es conveniente primero representar ese problema en un modelo
computacional que permita validar nuestra idea de solución, y luego, a partir del modelo,
codificamos nuestro programa con mayor confianza que funcionará bien para los
propósitos definidos. Se denomina algoritmo a tal modelo de solución de un problema.
Podemos definirlo como la serie de pasos secuenciales, no ambiguos y finitos requeridos
para resolver un problema.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 2 Prof. José Díaz Chow
Existen diversas formas de describir un algoritmo. Por ejemplo, mediante un diagrama
de flujo, esquemas de bloque Nassi-Scheiderman o pseudocódigo.
Como hemos anotado, el lenguaje ensamblador carece de las estructuras de control de
flujo y, en este momento, es extraño para nosotros. Por tanto, es de gran importancia
especificar un modelo computacional de la solución del problema, que nos guíe
eficazmente, antes de comenzar a implementarla.
Por la misma falta de estructura del ensamblador, la forma más idónea para representar
tal algoritmo es mediante pseudocódigo.
1.2.1 Implementación de las estructuras de control de flujo
El conjunto de instrucciones de la arquitectura x86 brinda instrucciones de salto o
bifurcación que permiten implementar las estructuras de control de flujo que ofrece un
lenguaje de alto nivel, pero de una forma más trabajosa.
Estas instrucciones permiten implementar saltos incondicionales, saltos condicionales,
llamadas a subrutinas y llamadas a interrupciones o servicios del sistema.
Por ejemplo, para implementar un If-Then-Else, se verifica la condición, normalmente
con la instrucción de comparación CMP y luego se salta a la parte then o a la parte else en
función de los resultados.
If: Cmp a, b
Je Then
Jmp Else
Then:
; Cuerpo del Then
Jmp End_If
Else:
; Cuerpo del Else
End_If:
Un ciclo se implementa de forma similar. Considermos el caso de un while – End While.
Primero se verifica la condición. Si no se cumple, saltar al fin del ciclo. Un repeat es muy
similar con la salvedad que la condición se verifica al final del cuerpo del repeat. Un for
requiere además un contador, aunque la familia ix86 provee la instrucción LOOP que lo
implementa explícitamente.
While: Cmp a, b
Jne End_While
; Cuerpo del While
Jmp While
End_While:
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 3
1.3 Ensambladores y Herramientas de Programación.
Como hemos mencionado anteriormente, un ensamblador es un programa que
traduce los mnemónicos del lenguaje ensamblador a lenguaje de máquina (código objeto)
que el procesador puede ejecutar directamente.
No obstante, no basta ensamblar un programa para que éste sea ejecutable por parte del
sistema operativo. Un segundo programa denominado enlazador (linker) convierte el
código objeto en un programa ejecutable que puede ser de tipo ejecutable estándar: exe o
de tipo comando: com (programa pequeño de menos de 640k de tamaño).
Para la programación de nuestros ejemplos usaremos primordialmente Microsoft Macro
Assembler (MASM). También experimentaremos un poco con las herramientas de
Borland: Tasm y Tlink. Para los estudiosos, se dispone de una serie de ensambladores
gratuitos para la arquitectura de 32 bits.
Finalmente, sus programas pueden llamar librerías de terceros a fin de no reinventar la
rueda. Estas librerías son anexadas a su ejecutable en tiempo de enlace.
Para ensamblar y enlazar un programa con las herramientas de Microsoft, basta usar el
programa ML que ensambla y enlaza de un solo paso (este en realidad invoca a ambos
módulos). Para hacerlo con las herramientas de Borland, ensamblamos con Tasm y
enlazamos con tlink.
Por ejemplo, para poder ejecutar el programa Hola.asm del laboratorio 3, con
herramientas de Microsoft basta:
Prompt> ml Hola.asm Prompt> Hola
Para hacerlo con las herramientas de Borland:
Prompt> Tasm –z Hola.asm Prompt> TLink Hola Prompt> Hola
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 4 Prof. José Díaz Chow
1.4 La Arquitectura de la Familia ix86
Podemos decir que la familia de arquitecturas de Intel x86, tiene dos generaciones
bien diferenciadas: la arquitectura de 16 bits que es la generadora de la familia y la
arquitectura de 32 bits, más moderna y versátil. En este curso, nos enfocaremos en los
principios y características básicas de la arquitectura de 16 bits.
1.4.1 Introducción
La familia 80x86 nace con el lanzamiento del microprocesador 8086 y su primo 8088.
Ambos idénticos en su arquitectura de 16 bits pero diferentes en su interfaz de bus. (el
8088 tenía una ruta de 8 bits para guardar compatibilidad con su predecesor 8080).
Sorprendentemente, esta familia de procesadores que dan soporte a la IBM PC y
compatibles desde su introducción en 1981 hasta hoy día, guardan compatibilidad en
arquitectura hacia atrás. La tabla a continuación muestra la evolución de estos CPUs en
cuanto a tamaño de registros, Memoria que es capaz de direccionar y velocidad de
cómputo.
Procesador Tamaño Registros
[bits] Ancho bus
[bits] Memoria que
direcciona Velocidad
[MHz]
8088 16 8 1 MB 4.71
80188 16 8 1 MB 6
8086 16 16 1 MB 4.71
80186 16 16 1 MB 6
80286 16 16 16 MB 4.7, 8, 12
80386 32 32 4 GB 25, 33
80486 32 32 4 GB 33, 66, 100
Pentium, PRO, mmx 32 64 4 GB 75 … 233
Pentium II 32 64 4 GB 266 … 450
Pentium III 32 64 4 GB 450 … 1,300
Pentium IV 32 64 4 GB 1,300 … 3,600
1.4.2 Organización
Intel organiza el Datapath de estos microprocesadores en dos unidades lógicas: La unidad
de ejecución (EU) y la Unidad de Interfaz de Bus (BIU). La EU contiene a la ALU, los
registros de propósito general y punteros así como el de banderas. Algunos autores
defienden que también contiene a la unidad de control. La BIU contiene los registros de
control de programa (PC) y direccionamiento segmentado, la lógica de acceso al bus y
una cola de instrucciones (de 2 a 8 instrucciones según CPU).
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 5
Figura 1. Organización básica del 8086
1.4.3 Modelo de Memoria
La memoria principal a que acceden estos procesadores se compone en parte de
RAM de lectura/escritura y ROM que contiene el software del sistema (Programa de
configuración del sistema y la BIOS).
El esquema básico de direccionamiento del 8086 original es de 1MB define. La figura 2
muestra el mapa de memoria definido para la PC, computadora basada en este
procesador, que integra 640KB de memoria principal para ejecución de programas de
usuario, denominada Memoria Convencional. El resto del 1MB, es denominada memoria
alta o superior, aloja la ROM con un espacio de 64 KB básicos para setup (configuración
de parámetros) y 192 KB para extensión y el BIOS.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 6 Prof. José Díaz Chow
Figura 2. Mapa de la memoria 8086.
Un aspecto importante a considerar del sistema de memoria que manejan los 80x86 es el
ordenamiento de bytes. Intel emplea para estos little endian, es decir que el byte menos
significativo se almacena en la posición más baja, al inverso de cómo se ordenan a lo
interno de los registros. (Big endian es al contrario: más significativo en posición más
baja).
La arquitectura de 16 bits de la famila x86 implementa un modelo de memoria
denominado segmentado, donde cada programa de usuario, reside en segmentos de
memoria. Cada programa puede tener uno o más segmentos para datos, uno o más
segmentos para código, otro para la pila y un extra segmento.
En el modelo de programación segmentado, el cálculo de direcciones es desplazado, para
lo cual emplea registros de base de segmento, lo cual permite que sean re-localizables en
memoria. Se definen cuatro tipos de segmentos básicos: Data (Datos), Code (Código),
Stack (Pila) y Extra (Extra para extender código o datos). Los registros base para éstos
son: DS, CS, SS y ES respectivamente (Ver figura 1). Los segmentos deben tener un
tamaño múltiplo de 16 bytes. En modo real (monotarea) puede ser de hasta 64KB.
Las direcciones físicas de memoria de 1MB (20 bits) se obtienen mediante un modo de
direccionamiento desplazado, donde el registro base del segmento se desplaza 4
posiciones a la derecha (se multiplica por 10H) y luego se suma al valor del
desplazamiento para obtener la dirección física de 20 bits. Por ejemplo, suponga que el
DS tiene 045FH y el desplazamiento para el dato X es 32H, entonces, DS se desplaza 4
posiciones volviéndose su contenido 045F0H a lo que se suma el 32H para obtener
04622H.
Es importante recordar que el modelo de programación del 8086 es segmentado y que el
modo [dirección] que podríamos considerar como “absoluto” (porque definimos
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 7
directamente la dirección de memoria a la que queremos acceder) se refiere a una
dirección que implícitamente está desplazada. Por ejemplo, basándonos en el caso del
párrafo anterior, la instrucción MOVE AX, [0032] carga en el registro AX el valor de
M(DS:32).
La arquitectura x86 de 16 bits de Intel evolucionó a una arquitectura de 32 bits cuando
apareció el procesador Intel 80386 en el año 1985, denominada inicialmente i386 o x86-
32 y finalmente IA-32. En la arquitectura de 32 bits, los registros se extienden a 32 bits
(Por ejemplo EAX, cuyos 16 bits menos significativos corresponden a AX, y así todos
los registros de propósito general). Asimismo, la arquitectura de 32 bits, dado que
permite acceder a 4GB de direcciones lineales de memoria, emplea un modelo de
memoria denominada FLAT, en el cual el direccionamiento ya no es segmentado.
Posteriormente (de 1999 a 2003) AMD amplió la arquitectura de 32 bits de Intel a una de
64 bits y la llamó, inicialmente x86-64, y finalmente AMD64. Intel adoptó estas
extensiones bajo el nombre de IA-32e, EM64T o Intel x64. La arquitectura de 64 bits
puede trabajar en dos modos: el compatible y el nativo o puro. Un procesador en modo
compatible puede ejecutar instrucciones en ensamblador x86 mediante traducción, pero si
está en modo nativo no.
1.5 El Lenguaje Ensamblador de la Familia ix86
Un programa en lenguaje ensamblador está compuesto por una secuencia de
sentencias. Estas sentencias representan tanto instrucciones del procesador como
directivas o comandos al ensamblador.
1.5.1 Formato de una sentencia en ensamblador.
Una sentencia en ensamblador se estructura de la siguiente forma:
[[nombre:]] [[operacion]] [[operandos]] [[;comentario]]
Donde nombre: es un identificador de etiqueta de código, que es una referencia simbólica
a la dirección de la instrucción y a la instrucción misma. El componente opcional
operacion representa una instrucción del procesador o una directiva o comando del
ensamblador. Los operandos representan los operandos de las instrucciones o parámetros
de las directivas y finalmente, un comentario es una facilidad para documentar la
sentencia e inicia con un punto y coma (;) y termina al final de la línea.
Identificadores
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 8 Prof. José Díaz Chow
Un identificador es un nombre que se asigna a una definición a fin de poder
referirse a ella de forma única. Usamos identificadores para nombrar constantes,
variables, procedimientos, segmentos, tipos de datos definidos por el usuario y etiquetas
de código (que representan la dirección de una instrucción). Los identificadores pueden
tener una longitud máxima de 247 caracteres. Algunas restricciones a observar en la
definición de nombres son:
Los identificadores pueden usar caracteres alfanuméricos (A–Z), dígitos (0–9) o los
caracteres especiales: @ _ $ ?
Un identificador no puede comenzar con un dígito. Se recomienda evitar usar @ también
para iniciar los identificadores porque MASM ha definido este carácter como inicio de
símbolos predeterminados que son palabras reservadas.
El lenguaje ensamblador es normalmente case insensitive, es decir, que no hace
diferencias entre mayúsculas y minúsculas. Por ejemplo, en ensamblador, los
identificadores MES y Mes son nombres idénticos y se refieren, por tanto al mismo
objeto.
1.5.2 Palabras Reservadas
Son aquellas palabras que tienen un significado especial en el lenguaje ensamblador o en
el programa ensamblador y que por tanto no deben emplearse como nombres o
identificadores en los programas. La mayoría de ensambladores generan error si se usa
una palabra reservada como identificador. Comúnmente se tienen como palabras
reservadas las siguientes:
Instrucciones: nombres de las operaciones que puede ejecutar el CPU.
Directivas: Comandos para el ensamblador.
Atributos: Valores específicos empleados en directivas.
Operadores: Empleados en expresiones.
Símbolos Predefinidos: Que definen cierta información dentro del programa.
En el MASM, la OPTION NOKEYWORD PalabraReservada permite deshabilitar el
estado de palabra reservada a PalabraReservada. Por ejemplo, para eliminar el estatus de
palabra reservada de la instrucción STR, el operador MASK y la directive NAME,
podemos usar la sentencia siguiente:
OPTION NOKEYWORD:<STR MASK NAME>
El Anexo A provee una lista completa de todas las palabras reservadas del MASM.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 9
Operación
Las operaciones representan instrucciones del procesador como add (suma), mov (copia
valores) o int (interrupción). También pueden representar directivas del ensamblador
como SEGMENT, DB o EQU. Posteriormente estudiaremos las instrucciones y las
directivas del ensamblador en detalle.
Operandos
Los operandos en ensamblador pueden estar expresados en diferentes modos de
direccionamiento. Un modo de direccionamiento indica cómo obtener el valor del
operando. Estos operandos pueden estar expresados en diferentes tipos de datos. En
términos generales, éstos son números enteros. A continuación mostramos diferentes
tipos de direccionamiento de los operandos:
1.5.3 Expresiones Constantes u Operandos inmediatos:
Una constante entera se compone de una secuencia de números que pueden estar tener
además un sufijo que indica la base en que está expresado el número. Por ejemplo, en las
sentencias siguientes:
mov ax, 25
mov bx, 0B3h
Los números 25 and 0B3h son constantes enteras. La h al final de 0B3 es un sufijo de base
que indica que está expresado en hexadecimal. Los números en hexadecimal se prefijan
además con 0 si el primer dígito es no numérico (0-9). Los sufijos de base o Radix son:
y o b para binary (Nótese que si la base por defecto es Hex, no puede usarse b)
o o q para octal
t o d para decimal (Nótese que si la base por defecto es Hex, no puede usarse d)
h para hexadecimal
Nuevamente, los sufijos pueden estar en mayúsculas o minúsculas. Si no se especifica la
base del número, el ensamblador asume que está expresado en la base predeterminada,
que por defecto es decimal. Se puede cambiar la base por defecto con la directiva
.RADIX.
Las expresiones enteras pueden contener además de constantes enteras, operadores de
desplazamiento, aritméticos y lógicos. El ensamblador evalúa y reemplaza el valor en
tiempo de ensamble.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 10 Prof. José Díaz Chow
1.5.3.1 Constantes Enteras Simbólicas
Se pueden definir constantes simbólicas enteras mediante la directiva EQU o el signo de
igual (=). Estas directivas asignan el valor durante tiempo de ensamble realizando
sustitución en el código generado. Se pueden usar para facilitar la legibilidad y el
mantenimiento de los programas al evitar tener números mágicos en código. Por ejemplo,
para tener identificadores simbólicos para ciertos códigos de exploración del teclado:
SCAN_A EQU 30
SCAN_B EQU 48
SCAN_ESC EQU 1
Las directivas EQU e = tienen diferentes propósitos. EQU define una constante cuyo
valor no se puede modificar posteriormente en el programa, en tanto, el valor definido
con el = sí. La sintaxis de EQU es:
ConstanteSimbolica EQU expression
Donde ConstanteSimbolica es un nombre único de su elección (excepto palabras
reservadas) y expresion puede ser una constante entera, una expresión entera, una cadena
de caracteres o una expresión que evalúa a una dirección de memoria.
El ejemplo siguiente ilustra el uso de EQU:
column EQU 80 ; Constante. Define 80 caracteres por columna
row EQU 25 ; Constante. Define 25 líneas por pantalla
screen EQU column * row ; Constante. Define tamaño en caracteres de la
; Pantalla. Evalúa en 2000
line EQU row ; Constante. Line equivale a 25
1.5.4 Operadores
Los operadores son usados en expresiones constantes. El valor de la expresión se
determina en tiempo de ensamble y no cambia en tiempo de ejecución. Es importante
notar la diferencia entre las operaciones del procesador y los operadores. Por ejemplo, la
palabra reservada ADD es una instrucción y el signo + es el operador de suma.
Las reglas que rigen lo operación de expresiones son:
Las operaciones en paréntesis se ejecutan antes que las adyacentes.
Las operaciones Binarias de mayor precedencia se ejecutan primero.
Operaciones de igual precedencia se ejecutan de izquierda a derecha.
Las operaciones Unarias de igual precedencia se ejecutan de derecha a izquierda.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 11
1.5.5 Tipos de datos
Un tipo de datos describe un conjunto de valores, principalmente Enteros. Una
variable de un tipo dado puede tener cualquier valor dentro del rango especificado para
ese tipo. Un dato entero de un byte, suele usarse también como un carácter, mediante el
código ASCII. Hoy día algunos ensambladores soportan otros códigos de dos bytes por
carácter.
El ensamblador de la familia x86 define algunos tipos de datos intrínsecos que algunos
ensambladores han extendido. En función de si se usa o no signo, una misma cantidad de
bits puede fungir como dos tipos de datos diferentes. Por defecto estos tipos son:
BYTE (8 bits), WORD (16 bits), DWORD (32 bits), QWORD (64 bits) y TBYTE (80
bits).
1.5.5.1 Variables de Memoria
La directiva Dx define una variable un tipo de datos definido x, donde x es la inicial de
los tipos, según fueron listados arriba. Por ejemplo DB define una variable tipo byte:
Mem8 DB 01H
Mem16 DW 0123H
Mem32 DD 01234567H
Una forma equivalente es:
Mem8 BYTE 01H
Mem16 WORD 0123H
Mem32 DWORD 01234567H
1.5.5.2 Tipos de datos compuestos
Se puede tratar secuencias de unidades de datos del mismo tipo como arreglos. Por
ejemplo, se pueden tratar secuencias de bytes como cadenas. Los tipos de datos pueden
tener atributos como el tipo de lenguaje compatible langtype y la distancia distance
(NEAR o FAR). Un dato FAR, está almacenado en un segmento de datos diferente.
El programador puede crear tipos compuestos de datos de diferentes tipos en
ensambladores avanzados como MASM, mediante directivas como STRUCT, UNION y
RECORD (contiene bits) y definir sus propios tipos con la directiva TYPEDEF que
asigna a un tipo cualificado un nombre. Por ejemplo:
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 12 Prof. José Díaz Chow
CHAR TYPEDEF BYTE
El tipo cualificado es cualquier tipo o un puntero a tipo, de la forma:
[[distancia]] PTR [[tipo]]
Donde distancia es NEAR, FAR y tipo es cualquier tipo definido previamente. Ejemplo:
CHAR TYPEDEF BYTE
PCHAR TYPEDEF PTR CHAR
1.5.6 Modos de direccionamiento
En ensamblador de la familia 80x86, tenemos los modos básicos de direccionamiento
inmediato, directo de registro y directo de memoria. En este último modo es necesario
especificar que dado el modelo segmentado del 8086, las variables deben ser
relocalizables en cualquier segmento de memoria en que se carguen, por tanto, el directo
de memoria con que trata el programador normalmente es en realidad una modo
desplazado relativo al segmento de datos activo en el momento. Por ejemplo,
.data
mem8 db 25
.code
. . .
move al, mem8
En este caso, mem8 representa una variable de memoria relocalizable. Suponga que
mem8 inicia a partir del byte 18 del segmento de datos, entonces mem8 equivaldría a
escribir [18] y su dirección absoluta sería en realidad CS:18, es decir: CS << 4 + 18.
Usted puede especificar una dirección efectivamente absoluta, si es preciso,
especificando el registro de segmento a considerar de la forma Registro de Segmento:
Desplazamiento, como se muestra:
Move ax, ES:bx
Existe también una serie de modos complejos muy poderosos. Tenemos el modo
indirecto de registro: Move ax, [bx], muy utilizado. En este caso nótese que los
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 13
corchetes en ensamblador ix86 se denominan especificadores de índice y representan una
referencia a memoria o indirección.
Tenemos también una serie de modos desplazados: base-desplazamiento, indizados, base-
índice y los base-índice con escalación. Normalmente los registros BP, BX se llaman
registros base y SI y DI registros de índice. Un modo base, parte de un registro base + un
desplazamiento inmediato. Un modo indizado, parte de una dirección base + un registro
de índice opcional + un desplazamiento inmediato opcional. El modo base-índice parte de
una dirección base + un registro de índice + un desplazamiento inmediato opcional y el
modo con escalación, que está disponible solo en arquitectura de 32 bits, permite una
dirección generada a partir de un registro base o general + un registro de índice que puede
estar escalado, es decir multiplicado por un factor (0, 1, 2, 4 u 8) + un desplazamiento
opcional.
Ejemplos: base: [bx+4], BX[4]
Indice: TABLA [2], [TABLA+2], TABLA[DI]
b-i: Tabla[bx][di]
escalado: [BX+DI*4+2]
1.5.7 El Conjunto de Instrucciones
Podemos agrupar las instrucciones que conforman el repertorio de la familia ix86
ya sea en función de la operación que realizan o del CPU con que se introdujo. A fin de
no ser extensivos con este acápite, nos enfocaremos en el estudio de las instrucciones más
utilizadas. En el anexo B, añadiremos la lista completa de las instrucciones del 8086.
1.5.7.1 Instrucciones de Copiado de datos
Las principales instrucciones para copiado de datos son MOV (Move o mueve),
XCHG (Exchange o intercambio), CWD (Convert Word to Double, convierte una
palabra en doble), y CBW (Convert Byte to Word, convierte un byte en palabra).
La instrucción MOV, copia el segundo operando (fuente) al primero (destino). Es
importante notar que solo uno de los operandos puede residir en memoria. Veamos unos
ejemplos:
; Copia de valores inmediatos
mov ax, 7 ; Valor Inmediato a Registro
mov mem, 7 ; Valor Inmediato a memoria
mov mem[bx], 7 ; Valor Inmediato a memoria de forma indirecta
; Copia de Valores en Registros
mov mem, ax ; De Registro a memoria
mov mem[bx], ax ; De Registro a memoria de forma indirecta
mov ax, bx ; De Registro a Registro
mov ds, ax ; De Registro a Registro de Segmento
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 14 Prof. José Díaz Chow
; Copia de Valores en memoria
mov ax, mem ; De memoria a Registro
mov ds, mem ; De memoria a Registro de Segmento
; Copia de Valores en memoria de forma indirecta
mov ax, mem[bx] ; De memoria indirecta a Registro
mov ds, mem[bx] ; De memoria indirecta a Registro de Segmento
; Copia de Valores en Registros de Segmento
mov mem, ds ; De Registro de Segmento a memoria
mov mem[bx], ds ; De Registro de Segmento a memoria indirecta
mov ax, ds ; De Registro de Segmento a Registro general
Existen algunas operaciones de copiado que no pueden hacerse en una sola operación y
requieren dos instrucciones, por ejemplo: ; Copia un Operando Inmediato a Registro de Segmento
mov ax, DGROUP ; Carga AX con el valor inmediato
mov ds, ax ; Copia AX al Registro de Segmento
; Copia de memoria a memoria
mov ax, mem1 ; Carga AX con un valor desde memoria
mov mem2, ax ; Copia AX a otra localidad de memoria
; Copiar valor de un Registro de segmento a otro
mov ax, ds ; Carga AX con un Registro de Segmento
mov es, ax ; Copia AX a otro Registro de Segmento
Los movimientos de un inmediato de menor tamaño a un registro de mayor tamaño son
automáticamente extendidos. Los movimientos entre registros deben ser del mismo
tamaño. Como los registros pueden expresarse en diferentes tamaños, y mover valores a
registros desde fuente de tamaños más pequeños puede dejar inconsistente un registro de
mayor tamaño (por ejemplo, un movimiento a AL puede dejar inconsistente el valor de
AX), es importante hacer extensión de signo de enteros para convertir datos a un tamaño
mayor. En este cometido, son muy útiles las instrucciones de conversión:
Instruccion Extensión de Signo en registro:
CBW (convierte byte a word) AL to AX
CWD (convierte word a doubleword) AX to DX:AX
CWDE (convierte word a doubleword extended)* AX to EAX
CDQ (convierte doubleword a quadword)* EAX to EDX:EAX
*Usa registros de 32 bits.
Es importante notar que en arquitectura de 16 bits, una palabra doble se almacena en un
par de registros de 16 bits (DX:AX) en tanto que en la arquitectura de 32 bits o
“extendida” la palabra doble extendida se almacena en un registro de 32 bits (EAX) lo
cual justifica la existencia de dos instrucciones CWD y CWDE. Veamos unos ejemplos:
.DATA mem8 SBYTE -5
mem16 SWORD +5
mem32 SDWORD -5
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 15
.CODE
.
.
.
mov al, mem8 ; Carga -5 en precision de 8 bits(FBh)
cbw ; Convierte a -5 en 16 bits (FFFBh) en AX
mov ax, mem16 ; Carga +5 en precision de 16 bits
cwd ; Convierte a +5 en 32 bits (0000:0005h) en DX:AX
mov ax, mem16 ; Carga +5 en precision de 16 bits
cwde ; Convierte a +5 en 32 bits (00000005h) en EAX
mov eax, mem32 ; Carga -5 en precision de 8 bits (FFFFFFFBh)
cdq ; Convert to 64-bit -5
; (FFFFFFFF:FFFFFFFBh) in EDX:EAX
Dado que la aritmética del procesador es por defecto con signo, el programador debe
garantizar una correcta extensión de cero cuando trabaja sin signo con tamaños parciales
de los registros, lo cual no se puede lograr con las instrucciones de conversión, por
ejemplo :
.DATA
mem8 BYTE 251
.CODE
.
.
.
mov al, mem8 ; Carga 251 (FBh) en 8 bits sin signo desde memoria
sub ah, ah ; Pone en 0 la parte alta del registro (AH)
; AX = 251 (00FBh ). Con cbw sería -5 (FFFBh)
Las instrucciones MOVSX y MOVZX, disponibles solo en los CPUs de 32 bits,
permiten hacer copia con extensión de signo y extensión de cero respectivamente, de
forma directa. El equivalente de nuestro ejemplo anterior sería:
; Ejemplo de extension sin signo
movzx ax, mem8 ; Carga en ax O0FBh (16 bits) desde FBH(8 bits)en mem
La instrucción XCHG intercambia los valores de sus operandos. Se puede intercambiar
valores entre registros, memoria y registros, pero no de memoria a memoria.
xchg ax, bx ; Pone el contenido de AX en BX y el de BX en AX
xchg memory, ax ; Intercambia el contenido de AX con el de la celda memory
; xchg mem1, mem2 ; Ilegal!
Además de datos, es importante poder mover direcciones a los registros que nos permitan
utilizarlos como punteros a memoria. Para tales efectos tenemos la instrucción LEA y el
operador OFFSET que nos permiten copiar la dirección relativa al DS de una variable de
memoria:
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 16 Prof. José Díaz Chow
.DATA
mem BYTE 20 DUP(?)
.CODE
lea bx, mem ; Carga en bx la dirección del arreglo mem
mov ah, [bx] ; copia en ah el primer byte en mem
Una operación equivalente a LEA del ejemplo, con el operador OFFSET es:
mov bx, offset mem ; Carga en bx la dirección (offset) de mem
1.5.7.2 Adición y sustracción de enteros
Las instrucciones ADD, ADC, INC, SUB, SBB, y DEC permiten sumar, incrementar,
restar y decrementar valores enteros respectivamente.
Estas instrucciones tienen dos restricciones:
1. Si hay dos operandos, solo uno puede residir en memoria.
2. Si hay dos operandos, ambos deben ser del mismo tamaño.
Para lograr el Segundo requisito, es factible usar el operador PTR para forzar a un
operando al tamaño requerido. Por ejemplo, si Buffer es un arreglo de bytes y BX apunta
a un elemento del mismo, puedes sumar una palabra desde Buffer con:
add ax, WORD PTR Buffer[bx] ; Suma una palabra desde un arreglo de bytes.
El siguiente ejemplo muestra diferentes sumas y restas en 8 y 16 bits:
.DATA
mem8 BYTE 39
.CODE
; Addition
; signed unsigned
mov al, 26 ; Start with register 26 26
inc al ; Increment 1 1
add al, 76 ; Add immediate 76 + 76
; ---- ----
; 103 103
add al, mem8 ; Add memory 39 + 39
; ---- ----
mov ah, al ; Copy to AH -114 142
+overflow
add al, ah ; Add register 142
; ----
; 28+carry
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 17
; Subtraction
; signed unsigned
mov al, 95 ; Load register 95 95
dec al ; Decrement -1 -1
sub al, 23 ; Subtract immediate -23 -23
; ---- ----
; 71 71
sub al, mem8 ; Subtract memory -122 -122
; ---- ----
; -51 205+sign
mov ah, 119 ; Load register 119
sub al, ah ; and subtract -51
; ----
; 86+overflow
1.5.7.3 Instrucciones de Multiplicación y División:
Para la multiplicación y división de enteros tenemos MUL, IMUL, DIV e IDIV. MUL e
DIV realizan multiplicación y división sin signo en tanto que IMUL e IDIV la hacen con
signo.
La instrucción MUL multiplica sin signo: Mul usa por defecto un operando pre-
definido e implícito: el acumulador: AH, AX y EAX.
MUL OP ; acumulador acumulador * OP
La multiplicación de dos operandos de 8 bits da por resultado un producto de16 bits en
AX, Multiplicación de dos operandos de 16 bits resulta en un producto de 32 bits en
DX:AX. Dos operandos de 32 bits dan un producto de 64 bits en EDX:EAX.
.DATA
mem16 SWORD -30000
.CODE
.
.
.
; 8-bit unsigned multiply
mov al, 23 ; Load AL 23
mov bl, 24 ; Load BL * 24
mul bl ; Multiply BL -----
; Product in AX 552
; overflow and carry set
; 16-bit signed multiply
mov ax, 50 ; Load AX 50
; -30000
imul mem16 ; Multiply memory -----
; Product in DX:AX -1500000
; overflow and carry set
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 18 Prof. José Díaz Chow
La instrucción IMUL multiplica con signo.
Varias formas:
IMUL Reg16, Inmediato
IMUL Reg16, { Memoria16| Reg16}, Inmediato
IMUL R, {Reg | Memoria} (CPUs de 32 bits)
En general: IMUL d, f, [f2]
d d * f | d f * f2
imul dx, 456 ; Multiply DX times 456 on 80186-80486
imul ax, [bx],6 ; Multiply the value pointed to by BX
; by 6 and put the result in AX
imul dx, ax ; Multiply DX times AX on 80386
imul ax, [bx] ; Multiply AX by the value pointed to
; by BX on 80386
La instrucción DIV divide sin signo e IDIV con signo.
Tiene un dividendo implícito (AH, DX:AX o EDX:EAX). El divisor puede ser un
operando de memoria o Registro, excepto aquellos deparados para Cociente y Residuo.
Puede ser necesario hacer extensión de signo o de zero a fin de lograr o ajustar el
dividendo a la cantidad explícita de bits.
Tamaño del
dividendo Dividendo
Tamaño del
divisor
Cociente
Residuo
16 bits AX 8 bits AL AH
32 bits DX:AX 16 bits AX DX
64 bits EDX:EAX 32 bits EAX EDX
.DATA
mem16 SWORD -2000
mem32 SDWORD 500000
.CODE
.
.
.
; Divide 16-bit unsigned by 8-bit
mov ax, 700 ; Load dividend 700
mov bl, 36 ; Load divisor DIV 36
div bl ; Divide BL ------
; Quotient in AL 19
; Remainder in AH 16
; Divide 32-bit signed by 16-bit
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 19
mov ax, WORD PTR mem32[0] ; Load into DX:AX
mov dx, WORD PTR mem32[2] ; 500000
idiv mem16 ; DIV -2000
; Divide memory ------
; Quotient in AX -250
; Remainder in DX 0
; Divide 16-bit signed by 16-bit
mov ax, WORD PTR mem16 ; Load into AX -2000
cwd ; Extend to DX:AX
mov bx,-421 ; DIV -421
idiv bx ; Divide by BX -----
; Quotient in AX 4
; Remainder in DX -316
1.5.7.4 Instrucciones de Operaciones a nivel de BITS:
Operaciones lógicas:
AND, OR, XOR hacen operaciones lógicas bit a bit en dos operandos. Dejando el
resultado en el primero. NOT complementa (niega) el operando. Note que además de la
operación en sí misma, existe gran utilidad en estas operaciones para el testeo y
establecimiento de valores de bits en posiciones específicas. Un OR con 1 establece en 1
el bit correspondiente y un AND con 0 limpia en 0 el valor del bit correspondiente.
mov ax, 035h ; Load value 00110101
and ax, 0FBh ; Clear bit 2 AND 11111011
; --------
; Value is now 31h 00110001
or ax, 016h ; Set bits 4,2,1 OR 00010110
; --------
; Value is now 37h 00110111
xor ax, 0ADh ; Toggle bits 7,5,3,2,0 XOR 10101101
; --------
; Value is now 9Ah 10011010
not ax ; Value is now 65h 01100101
;AND example - converts characters to uppercase
mov ah, 7 ; Get character without echo
int 21h
and al, 11011111y ; Convert to uppercase by clearing bit 5
cmp al, 'Y' ; Is it Y?
je yes ; If so, do Yes actions
. ; Else do No actions
.
yes: .
;OR example - compares operand to 0
or bx, bx ; Compare to 0
jg positive ; BX is positive
jl negative ; BX is negative
; else BX is zero
;XOR example - sets a register to 0
xor cx, cx ; 2 bytes, 3 clocks on 8088
sub cx, cx ; 2 bytes, 3 clocks on 8088
mov cx, 0 ; 3 bytes, 4 clocks on 8088
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 20 Prof. José Díaz Chow
Operaciones de desplazamiento de bits.
Las operaciones SHL y SHR hacen desplazamiento lógico a izquierda y derecha
respectivamente. SAL y SAR hacen desplazamiento aritmético a izquierda y
deredcha. ROL y ROR hacen rotaciones a izquierda y derecha. Cabe mencionar que
estas instrucciones se expresan con la forma: OP d, f . Estas realizan los
desplazamientos correspondientes en d en la cantidad de f bits. El bit desplazado se
copia a C como referencia, en cada caso excepto en las rotaciones. Existen dos
instrucciones más, RCL y RCR, que hacen las rotaciones a izquierda y derecha
involucrando (pasando a través) de C.
El 8086 solo admitía f=1 inmediato o el registro CL. Actualmente se puede usar
cualquier I de 8 bits. SHL y SAL multiplican d por 2f. SHR y SAR dividen d entre
2f. SAR es una división con Signo. La división con SAR redondea negativos hacia
abajo (al contrario de IDIV!).
shr bx, 4 ; 9 clocks, 3 bytes on 80286
-- Con 8086 :
mov cl, 4 ; 2 clocks, 3 bytes on 80286
shr bx, cl ; 9 clocks, 2 bytes on 80286
; 11 clocks, 5 bytes total
--- Otro ejemplo:
.DATA
masker BYTE 00000010y ; Mask that may change at run time
.CODE
.
.
.
mov cl, 2 ; Rotate two at a time
mov bl, 57h ; Load value to be changed 01010111y
rol masker, cl ; Rotate two to left 00001000y
or bl, masker ; Turn on masked values ---------
; New value is 05Fh 01011111y
rol masker, cl ; Rotate two more 00100000y
or bl, masker ; Turn on masked values ---------
; New value is 07Fh 01111111y
---Multiplicaciones
mul_10 MACRO factor ; Factor must be unsigned
mov ax, factor ; Load into AX
shl ax, 1 ; AX = factor * 2
mov bx, ax ; Save copy in BX
shl ax, 1 ; AX = factor * 4
shl ax, 1 ; AX = factor * 8
add ax, bx ; AX = (factor * 8) + (factor * 2)
ENDM ; AX = factor * 10
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 21
-- Divisiones
div_512 MACRO dividend ; Dividend must be unsigned
mov ax, dividend ; Load into AX
shr ax, 1 ; AX = dividend / 2 (unsigned)
xchg al, ah ; XCHG is like rotate right 8
; AL = (dividend / 2) / 256
cbw ; Clear upper byte
ENDM ; AX = (dividend / 512)
1.5.7.5 Instrucciones de Lógica y control de programa.
La instrucción JMP es un salto incondicional.
La forma básica de usar JMP es con etiquetas de código.
JMP d ; IP IP + d ( con d short y near )
A20:
...
Jmp A20
La instrucción LOOP es un salto con contador.
Loop implementa un for – Next. La cantidad de ciclos o iteraciones del loop se
define en CX. En cada ciclo, loop decrementa CX automáticamente y detiene el
ciclo cuando CX =0.
Mov cx, 10
A20:
...
Loop A20
La instrucción CMP compara dos valores.
Es la base para saltos condicionales. CMP realiza una comparación mediante una resta
que no afecta al operando destino. CMP establece las banderas C, O, S, Z, P, AC
cmp bx, 0 ; Compara Bx=0
jz B50 ; Si Bx = 0 salta a la dirección de etiqueta B50:
Las instrucciones de salto condicional.
Existen una serie de instrucciones en ensamblador que permiten cambiar el flujo
actual del programa en función del resultado de una expresión lógica o más
explícitamente del estado de configuración de ciertas banderas. Normalmente, estas
banderas son las que establece la instrucción CMP.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 22 Prof. José Díaz Chow
Las instrucciones de salto condicional guardan la forma JX donde J significa “salta si” y
X representa la comparación realizada o banderas consultadas. Por ejemplo JE salta si el
resultado de una comparación previa con CMP es que ambos operandos son iguales (E de
Equal), así mismo, JZ, salta si la bandera Z (cero) está establecida. Ambas instrucciones
son idénticas pues hacen el mismo trabajo, sin embargo, es posible que alguna de ellas
sea más legible en algún contexto de programación.
Es importante notar las diferencias en la comparaciones entre aritmética con signo y sin
signo. Por ejemplo, en precisión de 8 bits el número FBH representa -5 en aritmética con
signo y 251 en aritmética sin signo. Es obvio que son dos cantidades muy diferentes en
cada contexto, por eso la arquitectura de la familia ix86 define instrucciones de salto
condicional para cada tipo de aritmética. En aritmética con signo, decimos que dos
operandos son iguales o que uno es mayor o menor que el otro (E de equal, G de greater
than y L de less than), En cambio, en aritmética sin signo, decimos que son iguales, o que
uno está por encima o por debajo del otro, respectivamente (E de equal, A de above y B
de below).
Instrucciones de llamadas a procedimientos
Hasta el momento hemos experimentado con programas en ensamblador con un solo
procedimiento (programa principal), sin embargo, al igual que en los programas en
lenguaje de alto nivel, el ensamblador soporta la definición e invocación de
procedimientos.
Un procedimiento se declara en el segmento de código mediante la estructura:
nombreProc PROC distancia
…
nombreProc ENDP
El operador Distancia, indica si el procedimiento es cercano (NEAR) porque está
definido en el mismo segmento de código o es lejano (FAR) cuando está definido en otro
segmento de código.
La instrucción CALL permite invocar a un procedimiento desde un programa en
ensamblador. Todo procedimiento debe tener una instrucción RET al final, que retorna el
control al programa que lo invocó.
El paso de parámetros y de resultados se realiza mediante la pila. Es importante, por
tanto tener en cuenta que CALL mete el IP en la pila (2 bytes) al momento de recuperar
los parámetros. El IP que guarda CALL, lo restaura RET, por tanto, el programador de
procedimientos, debe tener cuidado de dejar el SP en el mismo punto donde lo encontró.
Ejemplo:
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 23
Title Llamadas
.model small
.stack 64
.data
.code
Begin Proc Far
Call Proc1
; …
mov ax, 4c00h
int 21h
Begin EndP
Proc1 Proc Near
Call Proc2
; …
Ret
Proc1 EndP
Proc2 Proc Near
; …
Ret
Proc2 EndP
End Begin ; Fin del porgrama
La instrucción INT:
Interrumpe el programa que se ejecuta actualmente para realizar una llamada a una
función del sistema operativo o de las rutinas de la ROM BIOS.
Los servicios de la ROM BIOS
Uno de los recursos más valiosos que asiste al programador de ensamblador de la PC son
los servicios de la ROM BIOS. Estos servicios se refieren a una serie de rutinas de
entrada salida (Basic Input Output Services) que se encuentran almacenadas en la
memoria ROM del sistema. Estas rutinas permiten acceder y programar el hardware
básico de la PC.
Todos los servicios de la BIOS se invocan mediante interrupciones. Estos servicios
pueden agruparse en cinco temas de acuerdo al objetivo. Cada tema contiene una serie de
servicios organizados en torno a la estructura hardware o función que soportan,
empleando una interrupción diferente para cada grupo de servicios, según muestra la
tabla:
Interrupción
Uso Hex Dec
Servicios de dispositivos periféricos
10H 16 Servicios de video
13H 19 Servicios de disco
14H 20 Servicios de comunicaciones seriales
15H 21 Servicios del sistema
16H 22 Servicios del teclado
17H 23 Servicios de impresión
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 24 Prof. José Díaz Chow
Servicios de estado del equipo
11H 17 Listado de equipamiento del sistema
12H 18 Tamaño de memoria
Servicios de fecha y tiempo
1AH 26 Servicios de hora y fecha
Servicio de impresión de pantalla
5H 5 Impresión de la pantalla
Servicios especiales
18H 24 Activar la ROM Basic
19H 25 Activar rutina de arranque
Llamadas al sistema operativo DOS: INT 21H
Aunque el DOS reserva para su uso muchas interrupciones (desde la 20H hasta la 3FH),
normalmente los servicios del sistema los proporciona a través de solo cinco de ellas:
20H, 21H, 25H, 26H y 27H.
Interrupción
Descripción Hex Dec
20H 32 Terminación de programa
21H 33 Servicios generales del DOS
25H 37 Lectura absoluta de disco
26H 38 Escritura absoluta en disco
27H 39 Terminar y quedar residente
Para efectos de este curso nos centraremos en los servicios generales o interrupción 21H.
La interrupción 21h, provee una serie de funciones. Para invocar a un servicio del DOS
mediante la interrupción 21H, se establece el número de función en AH y el parámetro en
AL.
Por ejemplo:
Mov ah, 4CH ; Función regresar al DOS
Mov al, 0 ; Valor de retorno = 0, normal.
Int 21H ; Llama al DOS.
Equivale a:
Mov ax, 4C00H ; Función regresar al DOS normalmente.
Int 21H ; Llama al DOS.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 25
1.6 La Computadora Personal basada en CPUs ix86.
1.6.1 El video de la PC
El video en la PC se obtiene gracias a un adaptador gráfico que genera las señales de
video y un monitor que las presenta en una pantalla. Existen básicamente dos modos
generales de video en la PC: el Modo carácter o texto y el modo gráfico.
En el contexto de este curso, solamente consideraremos el modo texto, a las funciones
más básicas y simples de video.
1.6.1.1 La pantalla
La pantalla de la PC en modo texto representa una matriz de caracteres organizados en
filas y columnas. El modo de video de texto más conocido es el de 25 filas por 80
columnas. El primer carácter en la esquina superior izquierda de la pantalla tiene la
posición fila 0, columna 0 (0,0). El carácter en la esquina inferior izquierda tiene la
posición (24,0). El de la esquina superior derecha (0,79) y el de la inferior derecha es la
(24, 79).
La pantalla del monitor puede presentar los datos que se escriben en un buffer de video
que es un área de memoria a la que tiene acceso el programador.
Esta área de memoria de video está organizada en páginas, de la cual solo una se muestra
a la vez. Esto que permite escribir varias pantallas de video directamente en memoria y
luego intercambiar entre ellas para hacer cambios rápidos de contenido en la pantalla.
Cada carácter pintado en la pantalla se representa por dos bytes en la memoria. Uno
almacena los atributos de visualización y el otro el código ASCII del carácter. Los
atributos pueden ser: Color de frente, color de fondo, intensidad y parpadeo.
1.6.1.2 Procesamiento básico de pantalla
En este curso abordaremos brevemente las funciones más básicas de procesamiento en
pantalla proporcionadas por algunas funciones de la interrupción 10H de la BIOS:
Limpiar la pantalla, posicionar el cursor, pintar un carácter con y sin atributo. Finalmente
estudiaremos como escribir una cadena completa mediante el servico 09H de la
interrupción de servicios del sistema del DOS, int 21H.
En términos generales, la Int 10H espera que la función a ejecutar se escriba en el registro
AH y en AL los parámetros básicos. Si la cantidad de parámetros crece, emplea los otros
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 26 Prof. José Díaz Chow
registros generales para completarlos. Por ejemplo, BH y BL sirven regularmente para
definir ya sea atributo en modo texto o el número de la página de video a afectar. CX y
DX para coordenadas de la ventana (CH, CL: Fila, Columna de la esquina superior
izquierda; DH, DL: Fila, Columna de la esquina inferior derecha).
Borrar la pantalla
La función 6H de la int 10H permite definir una ventana rectangular y deslizar su
contenido. Esto puede emplearse para borrar la pantalla.
El siguiente código limpia la pantalla completa:
Mov ah, 06h ;Selecciona función
Mov al, 00h ; Limpiar toda la ventana seleccionada
Mov bh, 07h ; Blanco sobre negro.
Mov cx, 0000h ; Esquina Sup. Izq: (0,0)
Mov dx, 184fh ; Esquina Inf. Der: (24,79)
Int 10H
Posicionar el cursor
La función 02h de la Int 10H del BIOS permite posicionar el cursor en la pantalla. Según
lo acostumbrado de escribe en AH la función (Ah2h). En BH se escribe el número de
página (por defecto 0), y en DH, DL, la Fila, Columna de la posición a establecer para el
cursor.
Mov ah, 02h ; Selecciona función
Mov bh, 00h ; Página por defecto.
Mov dh, 05 ; Posiciona el cursor en
Mov dl, 12 ; la posición (5,12)
Int 10H
Escribir un carácter en la posición actual del cursor
La función 09h de la Int 10H del BIOS permite escribir (y repetir) un carácter con un
atributo determinado en la posicionar actual del cursor en la pantalla. La función 0Ah
hace lo mismo pero sin considerar atributo (el carácter se escribe con el atributo actual).
Como siempre, en AH se escribe la función (Ah09h | 0Ah). En Al se pone el carácter a
escribir. En BL se escribe el atributo de video y en CX, la cantidad de veces a escribir el
carácter en pantalla.
Mov ah, 09h ; Selecciona función escribe con atributo
Mov al, ‘A’ ; Escribir una A
Mov bl, 14h ; Atributo de color rojo sobre azul.
Mov cx, 01 ; Solo pintarla 1 vez
Int 10H
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 27
Mov ah, 0ah ; Selecciona función escribe sin atributo
Mov al, ‘A’ ; Escribir una A
Mov cx, 01 ; Solo pintarla 1 vez
Int 10H
Despliegue de cadenas en pantalla con función del DOS
La función 09h de la Int 21H del DOS permite desplegar una cadena completa. Esta
cadena debe estar delimitada por el “guardián” del DOS, el carácter ´$´. Similar a las
interrupciones del BIOS, la Int 21H requiere recibir la función en AH. La dirección de la
cadena a desplegar se requiere en DX:
.data
Saludo db “Hola amigos,”, 01H, ‘$’
.code
. . .
Mov ah, 09h ; Selecciona función de despliegue del DOS
lea dx, Saludo ; Dirección de inicio de la cadena
Int 21H
1.6.2 La entrada estándar de la PC
En la IBM PC y compatibles, se ha definido el teclado como el dispositivo de entrada
estándar. El teclado es un dispositivo que presenta un conjunto de teclas en una
disposición estándar. Cuando el usuario presiona una tecla, en realidad cierra un circuito
al unir el contacto en la intersección de la fila y columna correspondiente a la tecla. Estas
señales alimentan un codificador que genera un código de exploración del teclado en
función de la posición de la tecla en la matriz. Por ejemplo, la tecla ESC que se encuentra
en la esquina superior izquierda del teclado corresponde al código de exploración 1, F1
que le sigue es 2, y así en lo sucesivo.
Además de generarse el código de exploración, el controlador del teclado, genera una
interrupción de hardware. La BIOS trata esta interrupción llevando al Buffer del teclado
el carácter correspondiente a la tecla pulsada pero ya en código ASCII. Por ejemplo, el
ESC sería un 27.
1.6.2.1 Procesamiento básico de teclado
En el contexto de este curso, exploraremos algunas de las funciones más básicas de
teclado, empleando la interrupción 16H de la BIOS y el servicio 0AH del DOS.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 28 Prof. José Díaz Chow
Leer el siguiente carácter del teclado
La función 00H de la Int 16H del BIOS, permiten esperar y leer el próximo carácter
desde el teclado. Si no hay un carácter en el buffer, la función se queda esperando
indefinidamente por la pulsación de un carácter. El carácter leído queda en AL. Cabe
mencionar que si se pulsó un carácter especial, como las teclas de función, se generan dos
bytes, el primero es un 0 y el segundo es la definición de la tecla.
El siguiente código lee el próximo carácter del teclado:
Mov ah, 00h ; Selecciona función de lectura
Int 16H
. . .
Cmp al, 27 ; Se tecleó ESC?
Comprobar si existe un carácter en el buffer del teclado
Frecuentemente, no queremos esperar a que presionen un carácter sino, que queremos
monitorear si se hizo de forma transparente. Esto nos lo permite la función 01h de la Int
16H del BIOS. Si se encontraba un carácter en el buffer, la función establece la bandera Z
a 1 y retorna en AL el carácter en el buffer, pero no lo retira de allí. Habría que invocar la
función 00h para hacerlo. El siguiente código muestra el uso de la función:
leerCar:
Mov ah, 01h ; Selecciona función verificar
Int 16H ; Invoca a función
jz HayCaracter ; Página por defecto.
Jmp leerCar
HayCaracter :
Mov ah, 00h ; Selecciona función leer
Int 16H ; lee el carácter en AL
Leer una cadena completa desde el teclado
El DOS nos provee una importante función o servicio que permite leer toda una cadena
desde el teclado, poniendo a disposición nuestra todas las teclas de edición además
(BackSpace, Delete, etc).
Requiere la definición de un espacio de memoria en el área de datos donde especificar
parámetros de la función y guardar la cadena leída. El ejemplo a continuación lee una
cadena de un máximo de 20 caracteres desde el teclado.
.data
; Definición de la lista de parámetros
ParLeer Label Byte
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 29
MaxLon db 20
LonReal db ?
Cadena db 20 dup(‘ ‘)
.code
mov ah, 0ah ; Solicita función de lectura
lea dx, ParLeer ; provee la dirección de la lista de par
int 21h ; invoca al DOS
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 30 Prof. José Díaz Chow
Anexo A: Lista de Palabras Reservadas.
Podemos identificar cuatro categorías de Palabras reservadas en el ensamblador de la
familia ix86:
Nombres de registros, como AX y AH.
Instrucciones simbólicas, como ADD y MOV.
Directivas (instrucciones para el ensamblador), como PROC y END.
Operadores, como DUP y SEG.
No se deben emplear estas palabras para definir datos, pues estas pueden confundir al
ensamblador o causar un error al ensamblar.
Nombres de registros:
AH, AL, AX, EAX
BH, BL, BX, EBX
CH, CL, CX, ECX
DH, DL, DX, EDX
DI, EDI
BP, EBP
SI, ESI
CS, DS, SS, ES, FS, GS
IP, EIP, SP
Instrucciones simbólicas:
AAA, AAD, AAM, AAS; ADC, ADD, AND, ARPL,
BOUND, BSF, BSR, BTn,
CALL, CBW, CDQ, CLC, CLD, CLI, CLTS, CMC, CMP, CMPSn, CWDn,
DAA, DAS, DEC, DIV,
ENTER, ESC,
HLT,
IDIV, IMUL, IN, INC, INSw, INT, INTO, IRET,
JA, JAE, JB, JBE, JCXZ, JE, JECXZ, JG, JGE, JL, JLE, JMP,
JNA, JNAE, JNB, JNBE, JNE, JNG, JNGE, JNL, JNLE, JNO,
JNP, JNS, JNZ, JO, JP, JPE, JPO, JS, JZ,
LAHF, LAR, LDS, LEA, LEAVE, LES, LFS, LGDT, LGS,
LIDT, LLDT, LMSW, LOCK, LODSn,
LOOP, LOOPE, LOOPNE, LOOPNZ, LOOPZ, LSL, LSS, LSS, LTR,
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 31
MOV, MOVSn, MOVSX, MOVZX, MUL,
NEG, NOP, NOT,
OR, OUTn,
POP, POPA, POPAD, POPF, POPFD, PUSH, PUSHAD,
PUSHF, PUSHFD,
RCL, RCR, REN, REP, REPE, REPNE, REPNZ, REPZ,
RET, RETF, ROL, ROR,
SAHF, SAL, SAR, SBB, SCASn, SETnn, SGDT, SHL, SHLD, SHR, SHRD,
SIDT, SLDT, SMSW, STC, STD, STI, STOSn, STR, SUB,
TEST, VERR, VERRW, WAIT, XCHG, XLAT, XOR
Directivas:
ALIGN,.ALPHA, ASSUME,
.CODE, COMM, COMMENT, CONST, CREF,
DATA, .DATA?, DB, DD, DF, DOSSEG, DQ, DT, DW,
ELSE, END, ENDIF, ENDM, ENDP, ENDS,
EQU,.ERRnn, EVEN, EXITM, EXTRN,
.FARDATA, .FARDATA?,
GROUP,
IF, IFI, IF2, IFB, IFDEF, IFDIF, IFE, IFIDN, IFNB, IFNDEF, INCLUDE,
INCLUDELIB, IRP, IRPC,
LABEL, LALL, LFCOND, LIST, LOCAL,
MACRO, MODEL, NAME,
ORG, OUT, PAGE, PROC, PUBLIC, PURGE,
RADIX, RECORD, REPT, SALL, SEGMENT, SEQ, SFCOND, STACK,
STRUC, SUBTTL,.TFCOND, TITLE,.XALL, .XCREF,.XLIST
Operadores:
AND, BYTE, COMMENT, CON, DUP,
EQ, FAR, GE, GT, HIGH, LE, LENGTH, LINE, LOW, LT,
MASK, MOD, NE, NEAR, NOT, NOTHING,
OFFSET, OR, PTR, SEG, SHL, SHORT, SHR, SIZE, STACK, THIS, TYPE,
WHILE, WIDTH, WORD, XOR
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 32 Prof. José Díaz Chow
Anexo B: El conjunto de Instrucciones.
I.- Conjunto de Instrucciones de la Familia ix86. Listado General:
I.
Aritméticas
ADD: Suma binaria.
ADC: Suma con acarreo.
INC: Incremento en uno.
SUB: Resta binaria.
SUBB: Resta con el bit prestado.
DEC: Decremento en uno.
MUL: Multiplicación.
IMUL: Multiplicación con signo.
DIV: División entera.
IDIV: División entera con signo
NEG: Negación aritmética.
Lógicas
AND: Y lógica.
NOT: Negación lógica.
OR: O lógica.
XOR: O Exclusiva lógica.
Corrimiento de bits
RCL: Rotación a izquierda con acarreo.
RCR: Rotación a derecha con acarreo.
ROL: Rotación a izquierda.
ROR: Rotación a derecha.
SAL: Corrimiento aritmético a izquierda.
SAR: Corrimiento aritmético a derecha.
SHL: Corrimiento lógico a izquierda.
SHR: Corrimiento lógico a derecha.
SHLD: Corrimiento lógico a izquierda en doble precisión.
SHRD: Corrimiento lógico a derecha en doble precisión.
Comparación
CMP: Comparación
CMPS: Comparación de cadenas de caracteres
TEST: Verificación de bits
BSF/BSR: Exploración de bits (32bits).
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 33
BT/BTC/BTR/BTS: Prueba o test de bits (32 bits).
Conversión de Tipo
CBW: Convierte byte a palabra.
CDQ: Convierte palabra doble a cuádruiple.
CWD: Convierte palabra a palabra doble.
CWDE: Convierte palabra a palabra doble extendida.
Conversión ASCII-BCD
AAA: Ajuste ASCII después de sumar.
AAD: Ajuste ASCII antes de dividir
AAM: Ajuste ASCII después de multiplicar
AAS: Ajuste ASCII después de restar.
DAA: Ajuste decimal después de sumar.
DAS: Ajuste decimal después de restar.
Transferencia de datos
MOV: Transfiere o copia datos enteros.
MOVS: Transfiere cadenas de caracteres.
MOVSX: Mueve con extensión de signo.
MOVZX: Mueve con extensión de cero.
LEA: Carga dirección efectiva.
LDS: Carga el registro de segmento de datos.
LES: Carga el registro de segmento extra.
LSS: Carga el registro de segmento de pila.
LODS: Carga una cadena.
STOS: Almacena una cadena.
XCHG: Intercambia el contenido de los operandos.
XLAT: Traducción.
Operaciones con la pila
PUSH: Introduce un elemento a la pila.
POP: Remueve un elemento de la pila.
PUSHA: Introduce los GPR a la pila.
POPA: Restaura los GPR desde la pila.
Transferencia de Entrada-Salida
IN: Lee desde un puerto E/S a un registro.
OUT: Escribe a un puerto de E/S.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 34 Prof. José Díaz Chow
Operaciones con banderas
CLC: Limpiar acarreo.
CLD: Limpiar dirección.
CLI: Limpiar interrupción.
STC: Establece la bandera de acarreo.
STD: Establece la bandera de acarreo.
STI: Establece la bandera de acarreo.
CMC: Complementa acarreo.
LAHF: Cargar banderas en AH.
SAHF: Cargar AH en banderas.
PUSHF: Introduce las banderas a la pila.
POPF: Restaura banderas desde la pila.
Operaciones con cadenas
CMPS: Compara cadenas.
LODS: Carga cadena.
MOVS: Mueve una cadena.
REP: Repite una cadena.
REPE: Repite la cadena mientras sea igual a.
REPZ: Repite la cadena mientras sea cero.
REPNE: Repite la cadena mientras sea igual a.
REPNZ: Repite la cadena mientras sea cero.
SCAS: Explora una cadena.
STOS: Almacena una cadena.
Operaciones de control de programa
CALL: Llamada a procedimiento.
RET: Regreso de procedimiento.
RETN/RETF: Regreso cercano / lejano.
INT: Llamada a Interrupción.
IRET: Regreso de la interrupción.
INTO: Interrupción de desborde.
JMP: Salto incondicional.
JA/JNBE: Salta si mayor / No menor o igual.
JAE/JNB: Salta si mayor o igual / No es menor.
JB/JNAE: Salta si es menor / No es mayor o igual.
JBE/JNA: Salta si es menor o igual / No es mayor.
JC/JNC: Salta si hay acarreo / No hay acarreo
JCXZ: Salta si CX es cero,
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 35
JE/JZ: Salta si es igual / Es cero.
JG/JNLE: Salta si es mayor / No es menor o igual.
JGE/JNL: Salta si es mayor o igual / No es menor.
JL/JNGE: Salta si es menor / No es mayor o igual.
JLE/JNG: Salta si es menor o igual / No mayor.
JNE/JNZ: Salta si no es igual / No es cero.
JNP/JPO: Salta si no hay paridad / Paridad es par.
JO/JNO: Salta si hay desbordamiento / No hay desbordamiento.
JP/JPE: Salta si hay paridad / Paridad es par.
JS/JNS: Salta si el signo es negativo / Es positivo.
Ciclos
LOOP: Repetir el ciclo.
LOOPE: Repetir mientras sea igual a.
LOOPZ: Repetir mientras sea cero.
LOOPNE: Repetir mientras no sea igual a.
LOOPNZ: Repetir mientras no sea cero.
Control del procesador
ESC: Escape.
HLT: Introduce en estado de detención.
LOCK: Bloquea el bus.
NOP: No operar.
WAIT: Pone el procesador en estado de espera.
II.- Conjunto de Instrucciones de la Familia ix86. Listado detallado:
En la siguiente tabla se muestran encolumnados los Mnemónicos (como MOV), los operandos (como fuente, destino) y la descripción de la operación. Los operandos son combinaciones entre tipos (registro, memoria e inmediato) con los direccionamientos admitidos en cada instrucción. Las instrucciones IN y OUT admiten un cuarto tipo de operando: puertos de I/O, con direccionamiento registro o inmediato.
II.1- Instrucciones de movimientos de datos
MOV destino,fuente ;la única instrucción que utiliza todos los tipos de direccionamiento
XCHG destino,fuente ;Intercambia los contenidos de destino y fuente
XLAT tabla_fuente ;carga el registro AL con el byte direccionado por (BX+AL)
LAHF ;carga las flags S, Z, A, P y C en AH
SAHF ;guarda AH en el registro de flags
LDS destino,fuente ;transfiere un puntero de 32 bits al registro DS y al registro destino
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 36 Prof. José Díaz Chow
LES destino,fuente ;transfiere un puntero de 32 bits al registro ES y al registro destino
LEA destino,fuente ;transfiere el offset de fuente (una dirección) a destino (un registro)
PUSH fuente ;guarda fuente en el stack (en la dirección SS:SP)
POP destino ;recupera del stack (dirección SS:SP-1) y guarda en registro destino
PUSHF ;almacena el registro de flags en/desde el stack
POPF ;recupera el registro de flags en/desde el stack
PUSHA ; almacena los reg DI,SI,BP,SP,BX,DX,CX,AX en/desde el stack
POPA ;recupera los reg DI,SI,BP,SP,BX,DX,CX,AX en/desde el stack
IN origen ;carga desde un puerto origen un byte o word en AL o AX
OUT destino ;escribe Al o AX en el puerto destino (direccionamiento inmediato o DX)
II.2- Las operaciones aritméticas
ADD destino,fuente ;suma fuente + destino y guarda el resultado en destino
ADC destino,fuente ;suma fuente + destino + Carry y guarda el resultado en destino
SUB destino,fuente ;resta destino - fuente y guarda el resultado en destino
SUB destino,fuente ;resta destino - fuente - Carry y guarda el resultado en destino
MUL fuente ;multiplica AL o AX * fuente y guarda el resultado en DX:AX
IMUL fuente ;igual que la anterior pero con numeros enteros con signo
DIV fuente ;divide DX:AX / fuente y guarda cociente en AX y resto en DX
IDIV fuente ;igual que la anterior pero con numeros enteros con signo
AND destino,fuente ;opera destino AND fuente y guarda resultado en destino
OR destino,fuente ;opera destino OR fuente y guarda el resultado en destino
XOR destino,fuente ;opera destino XOR fuente y guarda el resultado en destino
NOT destino ;el NOT cambia todos los 1 en 0 y los 0 en 1 de destino.
NEG destino ;NEG realiza el complemento a 2 de destino
INC destino ;Incremente en 1 el contenido de destino
DEC destino ;Decrementa en 1 el contenido de destino
DAA / DAS ;Efectúa el ajuste decimal en suma / resta del registro AL
AAA/AAD/
AAM/AAS ;ajustan el registro AL a valor decimal desempaquetado (para aplicar en
operaciones suma, resta, multiplicación y división)
II.3- Instrucciones de rotación
RCL destino,contador ;rota destino a través de carry a la izquierda contador veces
RCR destino,contador ;rota destino a través de carry a la derecha contador veces
ROL destino,contador ;rota destino a la izquierda contador veces
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 37
ROR destino,contador ;rota destino a la derecha contador veces
SAL destino,contador ;desplaza destino a la izquierda contador veces y rellena con ceros
SAR destino,contador ;desplaza destino a la derecha contador veces y rellena con bit SF
SHR destino,contador ;desplaza destino a la derecha contador veces y rellena con ceros
NOTAS SOBRE INSTRUCCIONES DE ROTACIÓN
El bit SF (signo) es el que está más a la izquierda : si destino es operando es de 8 bits"SF" es el bit número 7 y si destino es un operando de 16 bits, es el bit número 15.
En el procesador 8086 se permite un dato inmediato en lugar de especificar un registro como contador solo si ese dato inmediato es 1. Por lo tanto, para uno de esos procesadores la instrucción RCL AX,1 es válida mientras que la RCL AX,5 no lo es. A partir de 80286 se puede especificar cualquier numero de rotaciones como dato inmediato. Como DEBUG presupone 8086, cualquier valor inmediato distinto de 1 da error.
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 38 Prof. José Díaz Chow
Si en un programa para 8086 se desean rotar más de un bit a la vez, el valor contador se carga en CL
Para rotar un nibble (lo que es muy común en la conversión de binario a BCD) es más rápido y ocupa menos memoria si se utilizan 4 rotaciones de contador igual a 1 que si se utiliza el registro CL
Las instrucciones SAL y SHL son equivalentes La flag de Overflow cambia con una logica precisa si la rotación es de una
posición. En caso de rotaciones mayores, OVF queda indefinida. En los procesadores 80286 en adelante la rotación se hace MODULO 32, es decir
que se rotará la cantidad de veces igual al resto de la división contador/32, o sea que ROL AX,33 equivale a ROL AX,1 o ROL AX,65.
Una rotación con CL=0 equivale a un NOP de dos bytes
II.4.- Instrucciones de comparación
CMP destino,fuente ;compara fuente y destino. Modifica las flags V, Z, S, C, P y AC
TEST destino,fuente ;AND entre fuente y destino . Ninguno de los operandos cambia.
TEST modifica las mismas flags que CMP pero siempre deja a V = 0 y C = 0.
II.5.- Instrucciones de strings
CMPS string_destino,string_fuente ;compara las dos cadenas de a bytes o words
CMPSB string_destino,string_fuente ;origen y destino indicados por DS:SI y ES:DI (bytes)
CMPSW string_destino,string_fuente ;origen y destino indicados por DS:SI y ES:DI (words)
LODS string_fuente ;mueve un byte o una word desde fuente a AL o AX
LODSB string_fuente ;origen indicado por DS:SI (mueve un byte a AL)
LODSW string_fuente ;origen indicado por DS:SI (mueve una word a AX)
STOS string_destino ;mueve un byte o una word al destino desde AL o AX
STOSB string_destino ;destino indicado por ES:DI (mueve AL a un byte)
STOSW string_destino ;destino indicado por ES:DI (mueve AX a una word)
MOVS string_destino,string_fuente ;mueve un byte o word de fuente a destino
MOVSB string_destino,string_fuente ;origen y destino indicados por DS:SI y ES:DI (un byte)
MOVSW string_destino,string_fuente ;origen y destino indicados por DS:SI y ES:DI (una word)
SCAS string_destino ;compara la cadena de destino con AL o AX
SCASB string_destino ;destino indicado por ES:DI (compara AL con un byte)
SCASW string_destino ;destino indicado por ES:DI (compara AX con una word)
En todos los casos, si se utiliza el prefijo REP, la cantidad de elementos de la cadena a operar está dada por el contenido del registro CX, si no es un solo elemento de la cadena. A cada operación, CX es decrementado y SI y DI son incrementados o decrementados de acuerdo con el estado de la flag de dirección (Si D=0, se incrementan). El incremento o decremento de estos registros se hace de a uno si son operaciones de bytes o de a dos si
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I I
Elaborado por: José Díaz Chow Página 39
son de a words. Para los casos en que se especifica el largo del operando con la B o W final, la string_destino está apuntada por ES:DI, la string_fuente está apuntada por DS:SI .
II.6- Instrucciones de repetición
LOOP offset ;decrementa CX. Si CX no es cero, salta a offset (IP = IP + offset)
LOOPZ offset ;decrementa CX, Si CX <> 0 y Z = 1 , salta a offset (IP = IP + offset)
LOOPNZ offset ;decrementa CX, Si CX <> 0 y Z = 0 , salta a offset (IP = IP + offset)
En todos los casos, si no se produce el salto, se ejecuta la próxima instrucción
REP instrucción ;decrementa CX y repite la siguiente instrucción MOVS o STOS hasta que CX=0
REPZ instrucción ;igual que REP, pero para CMPS y SCAS. Repite si la flag Z queda en 1 (igualdad)
REPNZ instrucción ;igual queREPZ, pero repite si la flag Z queda en 0 (las cadenas son distintas)
II.7.- Instrucciones de salto
CALL destino ;llama a procedimiento. IP <-- offset de destino y CS <-- segmento de destino
RET valor ;retorna desde un procedimiento (el inverso de CALL), valor es opcional
INT número ;llamado a interrupción. CS:IP <-- vector de INT.Las flags se guardan en el stack
INTO ;llama a la INT 4 si la flag de overflow (V) está en 1 cuando se ejecuta la
instrucción
IRET ;retorna de interrupción al programa restaurando flags
JMP dirección ;Salta incondicionalmente al lugar indicado por dirección
JA offset ;salta a IP + offset si las flags C=0 Y Z=0 (salta si primer operando es mayor)
JAE offset ;salta a IP + offset si la flag C=0 (salta si primer operando es mayor o igual)
JB offset ;salta a IP + offset si las flags C=1 (salta si primer operando es menor)(igual a JC)
JBE offset ;salta a IP + offset si las flags C=1 o Z=1 (salta si primer operando es menor o
igual)
JZ offset ;salta a IP + offset si las flags Z=1 (salta si primer operando es igual al
segundo)(=JE)
JG offset ;salta a IP + offset si las flags S=V Y Z=0 (salta si primer operando es mayor)
JGE offset ;salta a IP + offset si las flags S=V (salta si primer operando es mayor o igual)
JL offset ;salta a IP + offset si las flags S<>V (salta si primer operando es menor)
JLE offset ;salta a IP + offset si las flags S<>V o Z=1(salta si primer operando es menor o
igual)
JNC offset ;salta a IP + offset si la flag C=0 (salta si no hay carry)
JNZ offset ;salta a IP + offset si la flag Z=0 (salta si no son iguales o no es cero)
JNO offset ;salta a IP + offset si la flag V=0 (salta si no hay overflow)
A R Q U I T E C T U R A D E M Á Q U I N A S C O M P U T A D O R A S I , C U R S O 2 0 0 4 .
Página 40 Prof. José Díaz Chow
JNP offset ;salta a IP + offset si la flag P=0 (salta si no hay paridad -o la paridad es impar
=JPO)
JNS offset ;salta a IP + offset si la flag S=0 (salta si no hay hay bit de signo)
JO offset ;salta a IP + offset si la flag V=1 (salta si hay desbordamiento -overflow)
JP offset ;salta a IP + offset si la flag P=1 (salta si la paridad es par ) (=JPE)
JS offset ;salta a IP + offset si la flag S=1 (salta si el signo es negativo)
JCXZ offset ;salta a IP + offset si la flag CX=0 (salta si el registro CX es cero)
Las instrucciones de saltos por Above o Below se refieren entre dos valores sin signo (JA, JAE, JB y JBE), mientras que las Greater y Less se refieren a la relación entre dos valores con
signo (JG, JGE, JL y JLE).
II.8.- Instrucciones que afectan flags
CLC/CMC/STC ;pone a cero / complementa / pone en 1 la flag C (carry)
CLD/STD ;pone a cero / uno la flag de dirección (D=0 hace que SI y DI se incrementen)
CLI/STI ;deshabilita / habilita las interrupciones por hardware enmascarables
II.9.- Instrucciones misceláneas
NOP ;no-operación: el procesador pasa a la instrucción siguiente sin hacer nada
CBW ;convierte el byte de AL en palabra (AX), copiando el bit 7 a todo el registro AH
CWD ;convierte word en double-word, copiando bit 15 de AX a todo el registro DX
HLT ;el procesador se detiene hasta que llegue un Reset o una interrupción por hard.