Ensamblador

44
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

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.