Sie sind auf Seite 1von 81

=============================================================================

TEMA 1 - CONCEPTOS FUNDAMENTALES SOBRE ESTRUCTURA DE COMPUTADORES.


=============================================================================

=============================================================================
1.1 Concepto de computador.
=============================================================================

Un computador es una mquina que puede resolver problemas ejecutando una


secuencia de instrucciones.
Un programa es la secuencia de instrucciones que describe cmo ejecutar una
tarea, tarea que sirve para resolver un problema.
El lenguaje mquina es el conjunto de instrucciones primitivas de un computador.
Dichas instrucciones se combinan de una determinada manera para especificar lo
que el ordenador debe realizar, y por ello forman un lenguaje, al que se
denomina lenguaje mquina. Es un conjunto de relativamente pocas instrucciones.
Esas instrucciones son muy sencillas; sirven para expresar acciones simples (por
ejemplo, copiar un dato de memoria hacia un registro del procesador, sumar un
valor al contenido de un registro, etc.).
Todos los programas a ejecutar por el computador deben ser previamente
convertidos a una secuencia de instrucciones de lenguaje mquina.
Es muy incmodo programar un computador en lenguaje mquina. Por ello, para
programar se utilizan los lenguajes de alto nivel, que resultan ms cmodos para
el programador. Para que un programa escrito en un lenguaje de alto nivel pueda
ser ejecutado en un computador, hay que traducirlo a lenguaje mquina; ese
trabajo de traduccin lo hacen los compiladores de los lenguajes de alto nivel.

-1-

=============================================================================
1.2 Niveles de estudio de un computador.
=============================================================================

Primer nivel. Descripcin geomtrica y de componentes. Estructura fsica de la


mquina, ubicacin espacial de sus elementos.
Segundo nivel. Descripcin de circuito electrnico. Se estudia cmo los
elementos electrnicos estn agrupados formando circuitos lgicos. Est entre la
electrnica analgica y la digital.
Tercer nivel. Descripcin de cmo se unen los elementos lgicos simples (puertas
lgicas) para formar circuitos que realicen funciones especficas (registros,
contadores, etc.). Corresponde a la electrnica digital.
Cuarto nivel. Nivel de transferencia entre registros (o nivel RTL). Un registro
es un lugar donde se almacena informacin. Se estudian los flujos de informacin
entre los diferentes registros. Es el nivel que nos va a ocupar en esta
asignatura.
Quinto nivel. Se describe el computador como una caja negra que realiza
funciones recibiendo rdenes del exterior y devolviendo resultados. Nivel al que
percibe el computador un usuario con una interfaz de alto nivel.

=============================================================================
1.3 Concepto de arquitectura de computadores y de organizacin de computadores.
=============================================================================

Arquitectura de un computador: son los atributos de un sistema computador que


son visibles a un programador. Por ejemplo, son aspectos referentes a la
arquitectura de un computador el lenguaje mquina, los bits usados para
representar los diversos tipos de datos y el modo de direccionar la memoria.
Organizacin de un computador: es la descripcin de las unidades funcionales de
un sistema computador y de cmo estn interconectadas. Por ejemplo, son aspectos
referentes a la organizacin de computadores las seales de control utilizadas,
las interfaces entre el computador y el exterior, la tecnologa utilizada en la
construccin de la memoria y cmo son los circuitos que implementan las
operaciones aritmticas y lgicas.
Ambos trminos hacen referencia a aspectos que pueden ser estudiados en todos
los computadores.
Una familia de computadores es un conjunto de computadores que tienen la misma
arquitectura pero diferente organizacin.
Esta asignatura se orienta al estudio de la arquitectura del computador.

-2-

=============================================================================
TEMA 2. Componentes y funcionamiento de un computador. La arquitectura IA-32.
=============================================================================

=============================================================================
2.1 La arquitectura Von Neumann.
=============================================================================
Un computador construido segn la arquitectura Von Neumann se caracteriza
porque:
a) Est integrado por tres elementos: la CPU, la memoria y el conjunto de
unidades de entrada/salida (E/S).
b) Los datos e instrucciones se almacenan en una memoria sobre la que se puede
leer y escribir.
c) Se accede a los contenidos de la memoria utilizando una direccin. Cada dato
se almacena en un lugar de la memoria que tiene asociado una direccin, y para
acceder al dato se suministra la direccin a la memoria, la cual a su vez
devuelve el dato.
d) Las instrucciones de un programa se ejecutan en un orden que coincide con la
secuencia de almacenamiento del programa dentro de la memoria.

=============================================================================
2.1.2 La CPU.
=============================================================================
La CPU est integrada por un conjunto de componentes lgicos que sirven para
almacenar datos y realizar operaciones aritmticas y lgicas con ellos.

-3-

Ese conjunto de componentes lgicos est incluido dentro de una configuracin


que permite hacer un uso general de las funciones aritmticas y lgicas
disponibles. En concreto hay unos circuitos (el "hardware") y esos circuitos
pueden realizar funciones diferentes: se selecciona la funcin que van a
realizar aplicando unas seales de control sobre ellos.
En conjunto, el funcionamiento es el siguiente: la CPU acepta datos y seales de
control y produce resultados.
Dentro de la CPU hay una parte de circuitera encargada de generar las seales
de control que a su vez hacen que el resto de circuitos lleven a cabo funciones
especficas. Para cada funcin a realizar en la prctica hay que suministrar una
secuencia de seales de control al circuito encargado de ejecutarla. Hay una
parte de la CPU que genera esas secuencias de seales de control.
Para que la CPU active las seales de control correspondientes a una secuencia
concreta (la cual a su vez da lugar a la ejecucin de una operacin en un
circuito) dispone de un cdigo especfico asociado a cada una de esas
secuencias, y adems hay una parte de la circuitera que es capaz de generar las
seales de control cuando reconoce ese cdigo.
Cada uno de los cdigos anteriores es una instruccin mquina. El conjunto de
todas ellas forma el lenguaje mquina del computador al que pertenece la CPU, o
simplemente se le conoce tambin como el juego de instrucciones del mismo. Una
secuencia de esas instrucciones forma un programa, que pertenece as al conjunto
del "software" que puede ejecutar el computador.

=============================================================================
2.1.3 La memoria.
=============================================================================
En la memoria se almacena la secuencia de instrucciones o programa y los datos
que van a ser utilizados en la ejecucin de ese programa.
Su funcionalidad se resume as:
a) En ella se leen las instrucciones que constituyen el programa.
b) En ella se leen los datos necesarios para la ejecucin.
c) En ella se escriben los resultados de la ejecucin de las instrucciones de la
memoria.
Dentro de la memoria hay ubicaciones en las que se puede almacenar informacin.
Cada una de ellas tiene asignado un nombre o direccin. Para acceder a esa
ubicacin se suministra a la memoria esa direccin. Por ello a veces se dice
simplemente que "la CPU accede a la direccin".
=============================================================================
2.1.4 Las unidades de entrada/salida.
=============================================================================
Sirven para intercambiar datos entre los dispositivos externos y la memoria del
computador, o en ocasiones entre ellos y la CPU directamente. Ese intercambio
puede ser de entrada de datos hacia el computador o de salida de los mismos
hacia el exterior. A esos dispositivos externos se los denomina dispositivos
perifricos del computador o simplemente perifricos.
En general la CPU accede a los dispositivos de entrada/salida anlogamente a
como lo hace a la memoria: los dispositivos de entrada/salida tienen asociadas
unas ubicaciones especficas sobre las que la CPU puede leer o escribir. Cada
ubicacin tiene una direccin. El conjunto de todas ellas es el conjunto de
direcciones del sistema de entrada/salida de ese computador. As, la CPU puede

-4-

enviar datos hacia un dispositivo de salida o leer datos de un dispositivo de


entrada. La diferencia entre las direcciones de memoria y las del sistema de
entrada/salida es que estas ltimas estn asociadas a las ubicaciones de lectura
o escritura de los dispositivos externos.

=============================================================================
2.2 La arquitectura Intel de 32 bits: IA-32.
=============================================================================
=============================================================================
2.2.1 Introduccin.
=============================================================================

Estudiaremos las caractersticas de la arquitectura de los computadores sobre un


tipo concreto de computador construido segn el concepto arquitectnico de Von
Neumann. En concreto, vamos a tomar como referencia computadores tipo PC basados
en microprocesadores de Intel actuales (Pentium y Core). La arquitectura de
ellos se conoce como la "Arquitectura Intel de 32 bits" o simplemente "IA-32".
Vamos a estudiar los elementos ms bsicos del lenguaje mquina IA-32. se es el
lenguaje de todos los microprocesadores IA-32, que son todos los procesadores de
Intel actualmente utilizados en los PCs comerciales.
Los procesadores de Intel basados en la arquitectura IA-32 son:
a) El procesador Pentium (1993)
b) Los procesadores basados en la microarquitectura P6: el Pentium Pro (1995),
el Pentium II (1997) y el Pentium III (1999)
c) El procesador Pentium IV, basado en la microarquitectura P7 o "Net-Burst"
(2001).
d) Los procesadores de microarquitectura Intel Core (2006).
Vamos a comentar los aspectos de la IA-32 apoyndonos sobre las caractersticas
de un computador PC tpico basado en cualquiera de los procesadores Intel
mencionados. Comentaremos a continuacin los elementos que integran el sistema y
sus caractersticas.

=============================================================================
2.2.2 El bus del sistema.
=============================================================================

Es el elemento que conecta los distintos componentes de la arquitectura V.N.


En un sistema como el tomado de referencia hay tres buses: el bus de
direcciones, el bus de datos y el bus de control. Juntos constituyen lo que se
denomina como el bus del sistema.
El bus de datos tiene 64 bits de ancho y permite transferencias de 16, 32 y 64
bits. Sirve para mover informacin entre una posicin particular de la memoria o
un dispositivo de E/S y la CPU.
El bus de direcciones sirve para transmitir a la memoria o a un dispositivo de
E/S las direcciones de las posiciones a las que la CPU desea acceder (para leer
o escribir sobre ellas). El sistema asocia una direccin a cada posicin de la
memoria y a cada posicin de los dispositivos de E/S. Si la CPU desea acceder a
alguna posicin, coloca su direccin en el bus de direcciones. La circuitera
interna de la memoria y de los dispositivos de E/S hace dos cosas: 1) reconoce
esa direccin como propia (esto es, que corresponde a una de las ubicaciones a

-5-

las que puede acceder), 2) internamente pone en marcha las acciones necesarias
para leer el dato y colocar dicho dato en el bus de datos, en una operacin de
lectura, o tomar el dato del bus de datos y almacenarlo en la ubicacin que
corresponda, en una operacin de escritura. El bus de direcciones tiene 32 bits
(salvo extensiones).
El bus de control est integrado por seales que
procesador con el resto del sistema. Entre estas
seales de lectura y escritura sobre la memoria,
lneas de interrupcin y las lneas de estado, y

controlan cmo se comunica el


seales se incluyen: las
el reloj del sistema, las
hay otras ms.

El reloj del sistema es una seal elctrica alterna entre dos niveles lgicos.
Es la responsable de toda la sincronizacin dentro del computador; su
importancia deriva de que la CPU internamente es un complejo sistema lgico
sncrono. La frecuencia de esa seal alterna es lo que se denomina la frecuencia
de reloj del sistema. A un perodo completo de esa seal es a lo que se denomina
el ciclo de reloj del sistema. La ejecucin de cada instruccin mquina consume
varios ciclos de reloj (pueden ser menos de 10, decenas, centenas o incluso ms
de 1000 ciclos).

=============================================================================
2.2.3 El subsistema de memoria.
=============================================================================
La memoria es direccionable a nivel de byte: con una direccin de 32 bits
referenciamos una posicin de memoria en la que se almacena 1 byte.
La memoria es equivalente a una array de 4x2^30 posiciones, cada una capaz de
almacenar 1 byte, por tanto son 4 Gigabytes. (1 Gigabyte=2^30 bytes).
Para ejecutar "leer el contenido de la direccin X de memoria" cosa que
representamos simplemente como:
CPU <--- Memoria(X)
se siguen tres pasos:
1) La CPU coloca en el bus de direcciones la direccin X.
2) La CPU activa la lnea de lectura del bus de control.
3) La CPU lee el dato que aparece en el bus de datos, despus de haberlo
colocado en l la memoria.
Definiciones de trminos habitualmente utilizados en relacin a la memoria:
1)
2)
3)
4)

Posicin de memoria: es un byte, esto es, 8 bits almacenados en memoria.


Palabra: son 2 bytes, esto es, 16 bits almacenados en memoria.
Palabra doble: son 4 bytes, esto es, 32 bits almacenados en memoria.
Palabra cudruple: son 8 bytes, esto es, 64 bits almacenados en memoria.

Se denomina tiempo de acceso a memoria al nmero de ciclos de reloj necesarios


para acceder a una posicin de la memoria para leer o escribir sobre ella. Ese
tiempo de acceso puede variar desde uno hasta millares de ciclos, y en general
son varios ciclos de reloj.
La memoria cach es una memoria que se coloca entre el procesador y la memoria
principal del sistema. Sirve para acelerar el acceso a memoria. Es de pequeo
tamao. Es muy rpida. Se carga con informacin que toma de la memoria principal
en porciones que abarcan muchas direcciones, y a esas porciones se las denomina
bloques de cach. Cuando el procesador accede a memoria puede ocurrir que la
informacin que necesita est en la cach; entonces ya no necesita accecer a la
memoria principal, y a ello se le denomina un acierto de la cach. O bien puede
ocurrir que esa informacin no est en la cach (porque la cach es mucho ms

-6-

pequea que la memoria principal, para ser ms rpida que sta); a ello se le
denomina un fallo de la cach. Cuando hay un fallo de la cach, la informacin
que necesita el procesador hay que ir a buscarla a la memoria principal. Se
tarda mucho menos tiempo en leer o escribir algo en la cach que en hacerlo en
la memoria principal del sistema.
=============================================================================
2.2.4 El subsistema de entrada/salida.
=============================================================================
Funcionalmente es anlogo al subsistema de memoria. Se direccionan sus
posiciones a travs del bus de direcciones. Utiliza direcciones de un ancho de
16 bits, lo que permite un total de 65536 direcciones de entrada/salida.
=============================================================================
2.3 Caractersticas de la CPU en IA-32.
=============================================================================
Comentamos a continuacin los elementos ms representativos de la CPU.
=============================================================================
2.3.1. Los registros de la CPU.
=============================================================================
Los registros son lugares de almacenamiento de informacin que estn dentro de
la CPU.
De ellos se toman datos para las operaciones aritmticas y lgicas de la CPU, y
sobre ellos se escriben los resultados. En ocasiones, algunos datos de esas
operaciones la CPU los toma directamente de la memoria, o deposita directamente
en la memoria los resultados.
Los principales registros de la CPU en IA-32 son:
1) El conjunto de registros de propsito general. Son registros de 32 bits de
ancho. Sirven para almacenar datos temporalmente. Los principales son: registro
EAX o registro acumulador, EBX o registro de direccin base, ECX o registro
contador y EDX o registro de datos.
2) El registro de puntero de instruccin. Es un registro de 32 bits. Contiene la
direccin de la memoria a partir de la que est almacenada la siguiente
instruccin a ejecutar.
3) El registro de banderas ("flags"). Es un registro de 32 bits. Sus bits
informan sobre el estado de funcionamiento del procesador o sobre el resultado
de ciertas operaciones.
=============================================================================
2.3.2 La unidad aritmtico-lgica (ALU).
=============================================================================
Es la parte de la CPU en la que tienen lugar la mayora de las operaciones
ejecutadas por ella.
Por ejemplo, para realizar lo siguiente:
"sumar 5 al contenido del registro EAX"
La CPU hara:
1) Copiar el valor del registro EAX en una entrada de la ALU.
2) Enviar el valor 5 a otra entrada de la ALU.
3) Ordenar a la ALU que sume los valores que tiene depositados en sus entradas.

-7-

4) Copiar en EAX el resultado que aparece en la salida de la ALU.


=============================================================================
2.3.3 Unidad de interfaz de bus (BIU).
=============================================================================
Se encarga de manejar los buses de datos y direcciones cuando la CPU debe
acceder a posiciones de la memoria o del sistema de E/S.
=============================================================================
2.3.4 La unidad de control y el juego de instrucciones.
=============================================================================
La CPU internamente posee una unidad de control (UC). Cada una de las
instrucciones del juego de instrucciones de la CPU (o del lenguaje mquina)
tiene asociado un cdigo numrico, que se denomina "cdigo de operacin" y que
se codifica en binario. La UC es capaz de reconocer ese cdigo para que la CPU
ejecute una instruccin.
La UC se encarga de hacer que la CPU traiga de la memoria las instrucciones del
programa. As, trae el cdigo binario de cada instruccin, y lo trae de la
posicin de memoria a la que apunta en cada momento el "puntero de instruccin",
que ser el registro que almacena la direccin de memoria a partir de la que se
aloja ese cdigo.
Despus, la UC coloca el cdigo en otro registro interno de la CPU denominado
"registro de decodificacin". Sobre l realiza el trabajo de identificar la
accin a desarrollar. Una vez identificada, comienza la ejecucin de la
instruccin.
Los cdigos de operacin tienen un tamao que es mltiplo de 8 bits. En ellos se
codifica la operacin a realizar y qu operandos estn involucrados en ella.
Esos operandos pueden ser un dato inmediato (un nmero), un registro o una
posicin de memoria.
Para referirnos a los cdigos de operacin utilizaremos una notacin simblica.
Asociamos a cada cdigo un trmino al que denominamos "mnemnico".
Ejemplos de cdigos de operacin y sus mnemnicos:
a) 11110100 es un cdigo de operacin binario de 8 bits, que se representa por
medio del mnemnico "hlt".
b) 10001001:11001000 es un cdigo de operacin de 16 bits, 2 bytes, que se
representa por medio de "mov cx,ax".
c) 0x9b:0xdb:0xe1 es un cdigo de operacin de 24 bits, 3 bytes (expresado en
hexadecimal) que se representa por "fdisi".
Escribimos programas que puedan ser ejecutados por la CPU utilizando los
mnemnicos, en lugar de los cdigos binarios. Los programas as escritos se dice
que lo estn en lenguaje ensamblador. Esos programas pueden ser traducidos
directamente a lenguaje mquina, cosa que en la prctica se hace por medio de un
programa al que se denomina ensamblador.

=============================================================================
2.4 Organizacin fsica de la memoria en IA-32.
=============================================================================
Consideraremos siempre un espacio de memoria de 4 Gigabytes.

-8-

Por medio de direcciones de 32 bits podemos direccionar cualquier posicin de la


memoria.
IA-32 admite el concepto de segmentacin. Un segmento de memoria es una porcin
de la memoria que comienza a partir de una determinada direccin.
El direccionamiento en IA-32 puede ser de dos tipos:
a)Lineal o plano: se suministra una sola direccin (32 bits) que sirve para
seleccionar una posicin de la memoria.
b)Segmentado: se suministran dos nmeros para especificar una direccin; a esos
nmeros se les denomina segmento y desplazamiento. La direccin de memoria se
obtiene sumando el desplazamiento al resultado de realizar cierta operacin
sobre el nmero de segmento.
En nuestro estudio utilizaremos siempre un direccionamiento lineal o plano sobre
un espacio de memoria de 4 Gigabytes. Obsrvese que los registros utilizados son
de 32 bits, y por tanto tienen tamao suficiente como para almacenar una
direccin de dicho espacio. Nunca vamos a utilizar directamente la segmentacin
en este curso.
=============================================================================
2.5 Resumen de los registros de la CPU en IA-32.
=============================================================================
Dentro de los registros de la CPU hay porciones las cuales a su vez pueden ser
utilizadas como registros independientes. Como tales, reciben su propio nombre.
Numeramos los bits de los registros comenzando por el bit 0, que representa el
bit menos significativo del dato almacenado en el registro. En nuestras
representaciones, colocaremos el bit ms significativo siempre en la posicin
que se encuentre ms hacia la izquierda. Por tanto, el bit cero ser siempre el
que se encuentre ms hacia la derecha.
Para explicar cmo partes de un registro a su vez forman otros registros,
comentaremos detalladamente el caso del registro EAX. El registro EAX consta de
32 bits (bits 0 a 31). Los bits 0 a 7 de este registro forman el registro AL.
Los bits 8 al 15 de EAX forman el registro AH. Por otra parte, los bits 0 al 15
(en conjunto) forman el registro AX. As podemos decir que el registro AX est
formado por los 16 bits menos significativos del registro EAX; que el registro
AL est formado por los 8 bits menos significativos del registro AX, y que el
registro AH est formado por los 8 bits ms significativos del registro AX.
Lo mismo que hemos dicho del registro EAX podemos decirlo de los registros EBX,
ECX y EDX. En resumen:
EAX: bits 0 al 31 (todos los bits del registro). AX, bits 0 al 15. AL, bits 0 al
7. AH, bits 8 al 15.
EBX: bits 0 al 31 (todos los bits del registro). BX, bits 0 al 15. BL, bits 0 al
7. BH, bits 8 al 15.
ECX: bits 0 al 31 (todos los bits del registro). CX, bits 0 al 15. CL, bits 0 al
7. CH, bits 8 al 15.
EDX: bits 0 al 31 (todos los bits del registro). DX, bits 0 al 15. DL, bits 0 al
7. DH, bits 8 al 15.

Hay otros registros de 32 bits, que a su vez contienen registros de 16 bits, que
son los siguientes:

-9-

ESI: bits 0 al 31 (todos los bits del registro). SI, bits 0 al 15. Se denomina
registro ndice de fuente.
EDI: bits 0 al 31 (todos los bits del registro). DI, bits 0 al 15. Se denomina
registro ndice de destino.
EBP: bits 0 al 31 (todos los bits del registro). BP, bits 0 al 15. Se denomina
registro puntero de base.
ESP: bits 0 al 31 (todos los bits del registro). SP, bits 0 al 15. Se denomina
registro de puntero de pila.
EFLAGS: bits 0 al 31 (todos los bits del registro). FLAGS, bits 0 al 15. Se
denomina registro de banderas o de estado.
Adems hay otros registros de 16 bits, que no vamos a utilizar en este curso, y
que se denominan CS, DS, ES, FS, GS y SS. Se les denomina registros de segmento.
Finalmente est el registro de 32 bits EIP, al que se denomina registro de
puntero de instruccin. En dicho registro se almacena la direccin de la
siguiente instruccin a ejecutar. Va variando (aumentando o disminuyendo)
durante la ejecucin del programa, para estar apuntando siempre a la direccin
que en cada momento corresponda.
=============================================================================
2.6 El juego de instrucciones en IA-32.
=============================================================================
Podemos clasificar las principales instrucciones de IA-32 dentro de los
siguientes grupos:
1) De movimiento de datos.
2) De conversin de datos.
3) Aritmticas.
4) Lgicas y de manipulacin de datos a nivel de bit.
5) De control de flujo de los programas (saltos, llamadas a subrutinas e
interrupciones).
6) De entrada/salida.
7) De manipulacin de cadenas de caracteres o de bloques de memoria.
8) De aritmtica de punto flotante.
9) MMX (extensiones para gestin de multimedia).
10) SSE (extensiones para computacin tipo SIMD)
En el resto de la asignatura estudiaremos la funcionalidad de la mayor parte de
los grupos de instrucciones mencionados.

- 10 -

- 11 -

=============================================================================
TEMA 3. Instrucciones de movimiento de datos.
=============================================================================
=============================================================================
3.1 Introduccin.
=============================================================================
Son instrucciones que mueven informacin entre diversos lugares de
almacenamiento.
Los lugares de almacenamiento involucrados pueden ser: registros, posiciones de
la memoria, la pila (que es una zona de la memoria que soporta un tipo de
manipulacin especial).
En general, a lo largo de la asignatura vamos a utilizar la siguiente notacin:
1) Para referirnos a registros:
- Con "reg" nos referiremos a cualquiera de los registros de propsito general,
de cualquier tamao.
- Con "reg8", "reg16" o "reg32" nos referiremos respectivamente a registros de
8, 16 o 32 bits.

2) Para referirnos a la memoria:


- Con "mem" hacemos referencia a una direccin de memoria a partir de la cual se
ha almacenado 1 byte de informacin (esto es, el byte que se almacena en esa
direccin). Recordemos que toda direccin de memoria se compone de 32 bits.

- 12 -

- Con "mem16" hacemos referencia a una direccin a partir de la que se almacena


una palabra (2 bytes, 16 bits). Por tanto, hace referencia a dos ubicaciones de
memoria consecutivas. Para referirnos a esa zona de memoria, utilizamos la
direccin de la ubicacin ms baja. As, si a partir de mem16 tenemos almacenada
una palabra, tendremos almacenado:
En la direccin mem16: el byte bajo de la palabra
En la direccin mem16+1: el byte alto de la palabra
- Con "mem32" hacemos referencia a una direccin a partir de la que se almacena
una palabra doble (4 bytes, 32 bits). Por tanto hace referencia a cuatro
ubicaciones de memoria consecutivas. Para referirnos a esa zona de memoria,
utilizamos la direccin de la ubicacin ms baja. As, si a partir de mem32
hemos depositado los bytes 0, 1, 2 y 3 de una palabra doble (el byte 0 ser el
menos significativo), tendremos almacenados esos bytes en la memoria as:
En la direccin mem32: byte 0 (menos significativo)
En la direccin mem32+1: byte 1
En la direccin mem32+2: byte 2
En la direccin mem32+3: byte 3 (ms significativo)
Para referirnos a las posiciones de la memoria nunca utilizaremos el valor
numrico de la direccin directamente. Siempre nos referiremos a ellas por medio
de una etiqueta. La etiqueta es un nombre que asignamos a una direccin de
memoria. En los programas hay una zona donde se establece: a) qu etiquetas hay,
b) el tipo de dato que se va a almacenar a partir de la direccin asignada a
cada etiqueta (esto es, bytes, palabras o palabras dobles).
En muchas ocasiones, se utilizar el trmino "mem" no para referirnos a una
direccin de memoria a partir de la que almacenamos 1 byte, sino en general para
referirnos a una a partir de la que se almacena no importa qu tamao de dato.
Es anlogo a la forma en que se puede utilizar "reg".

=============================================================================
3.2 Instrucciones de copia de datos entre lugares de almacenamiento.
=============================================================================
Tienen el mnemnico comn MOV.
Funcin: "mov destino, fuente" hace que se copie el contenido de fuente en
destino, sin que se modifique el contenido de fuente.
Utilizacin:
1)
2)
3)
4)
5)

mov
mov
mov
mov
mov

reg,
mem,
reg,
mem,
reg,

reg
reg
mem
dato inmediato
dato inmediato

mem y reg pueden ser ambos de 8, 16 y 32 bits. Ambos deben tener el mismo
tamao.
mov no permite copiar directamente de una ubicacin de memoria hacia otra. Para
llevar algo de una posicin de memoria hacia otra es necesario hacer una copia
intermedia de los datos en un registro.
Los "datos inmediatos" son valores que estn incluidos dentro de la propia
instruccin. Por ejemplo "mov al,5" indica cargar el valor 5 en al, y ese 5 se
expresa dentro de la instruccin. Los datos inmediatos pueden ser nmeros o
cadenas de caracteres. El ensamblador que utilizaremos en la asignatura soporta
los siguientes formatos para la codificacin de los datos inmediatos:

- 13 -

a) Datos inmediatos numricos:


- Enteros en base 10: ejemplo, mov ax, 13
- Hexadecimales: pueden expresarse con sufijo h (por ejemplo, mov al, a2h) o sin
sufijo poniendo delante 0x (por ejemplo, mov al, 0xa2).
- Octales: se expresan con el sufijo q (por ejemplo, mov ax, 7777q).
- Binarios: se expresan con el sufijo b (por ejemplo, mov al, 10010011b).

b) Caracteres y cadenas de caracteres: se escriben entre comillas simples. Por


ejemplo, mov eax, 'abcd' da lugar a que en el registro eax se almacene
0x64636261. 0x64, 0x63, 0x62, 0x61 respectivamente son los cdigos ASCII de la
d, c, b y a, en hexadecimal. El de la a se ha almacenado en el byte
menos significativo de eax, y el de la d en el byte ms significativo.
=============================================================================
3.3 Instrucciones de intercambio de contenido entre lugares de almacenamiento.
=============================================================================
Instruccin: XCHG.
Sirve para intercambiar el contenido de dos lugares de almacenamiento. Los
lugares especificados deben ser del mismo tamao en bits.
Utilizacin:
1) xchg reg, mem
2) xchg reg, reg

=============================================================================
3.4 Obtencin de direcciones efectivas de la memoria.
=============================================================================
Instruccin: LEA
Sirve para cargar un registro de propsito general con la direccin efectiva de
una posicin de memoria.
Utilizacin:
1) lea reg16, mem : copia en reg16 los 16 bits ms bajos de la direccin de
memoria etiquetada como mem (esto es, no de lo almacenado en la memoria, sino
los 16 bits ms bajos de los 32 bits que expresan esa direccin).
2) lea reg32, mem
memoria mem.

: copia en reg32 los 32 bits que expresan la direccin de

En los dos casos anteriores, mem puede ser, por ejemplo, una etiqueta.
=============================================================================
3.5 Instrucciones de manejo de la pila.
=============================================================================
En IA-32 la pila es una zona de la memoria sobre la que se construye una pila
LIFO. Cuando se copian datos en la pila, la pila "crece hacia abajo" en la
memoria, esto es, el ltimo byte cargado se carga siempre en una direccin de
memoria que se obtiene restando 1 a la direccin de memoria en la que se carg

- 14 -

el penltimo byte cargado. As, los datos introducidos ms recientemente se


sitan en posiciones de memoria que numricamente son cada vez ms bajas.
La pila se comienza a construir en una posicin de memoria elevada.
En la pila siempre hay una direccin que es la "cabeza de la pila". La cabeza de
la pila indica la menor de las direcciones ocupadas por la pila, y por tanto es
la direccin del ltimo byte que fue introducido en la pila. La direccin de
cabeza de la pila siempre est almacenada en el registro de propsito general
ESP (al que por ello se denomina registro de puntero de pila). Cuando se saca un
byte de la pila, se saca de la direccin ESP, y ESP aumenta en una unidad, para
seguir apuntando a la cabeza de la pila. Cuando se introduce un byte en la pila,
se introduce en la direccin (ESP-1) y ESP disminuye en una unidad por la misma
razn.
As, en la pila se pueden guardar valores y recuperar los valores guardados.
Para ello hay instrucciones especficas de manipulacin de la pila.
La pila se utiliza para almacenar el contenido de registros u otras posiciones
de memoria y para otros usos como pasar parmetros a llamadas de procedimientos.
Cuando se introduce en la pila una palabra, es como si se introdujeran en la
pila dos bytes consecutivos: primero el byte alto y luego el byte bajo; por
ello, el byte bajo quedar almacenado en una posicin de memoria ms baja que el
byte alto. Cuando se introduce en la pila una palabra doble, es como si se
introdujeran en la pila cuatro bytes consecutivos: primero el byte 3, luego el
byte 2, luego el byte 1 y por ltimo el byte 0. Por ello si miramos la zona de
la memoria donde se construye la pila, veramos en la direccin a la que apunta
ESP el byte 0, en ESP+1 el byte 1, en ESP+2 el byte 2 y finalmente en ESP+3 el
byte 3.
Las instrucciones de manipulacin de la pila son:
PUSH

para introducir algo en la pila.

POP

para sacar algo de la pila.

Utilizacin de estas instrucciones:


1) Para sacar o meter en la pila una palabra de o hacia un registro de 16 bits:
push reg16: mete en la pila 2 bytes (el contenido de reg16), comenzando por
la parte alta de reg16.
pop reg16: saca de la pila 2 bytes para cargarlos en el registro reg16. El
primer byte sacado de la pila lo almacena en la parte baja de reg16 y el segundo
byte lo almacena en la parte alta de reg16.

2) Para sacar de o introducir en la pila una palabra doble desde o hacia un


registro de 32 bits:
push reg32: mete en la pila 4 bytes (el contenido de reg32), comenzando por
el byte 3 y terminando por el byte 0 de reg 32.
pop reg32: saca de la pila 4 bytes y rellena con ellos el registro reg32,
comenzando por el byte 0 y terminando por el byte 3.

- 15 -

3) Para sacar de o meter en la pila un grupo de bytes (palabra o palabra doble)


que estn almacenados en la memoria a partir de la posicin mem:
push word mem16
push dword mem32
pop word mem16
pop dword mem32
Como una etiqueta de memoria lo nico que especifica es una direccin de
memoria, para indicar cuntos bytes se deben sacar o meter de la pila, se coloca
la partcula word (que expresa 2 bytes, esto es, movimiento de una palabra) o
bien la partcula dword (que expresa 4 bytes, esto es, movimiento de una palabra
doble).
4) Para sacar de o meter en la pila el contenido de todos los registros de
propsito general de 16 bits se utilizan pusha y popa. El contenido de esos
registros se carga con pusha en el orden siguiente: ax-cx-dx-bx-sp-bp-si-di, y
se extraen con popa en el orden inverso.
5) Para hacer algo anlogo con los registros de propsito general de 32 bits se
utiliza pushad y popad. El orden seguido es el mismo, colocando "e" delante de
los nombres de registro para obtener los nombres de los registros de 32 bits.
6) Para meter en y sacar de la pila los 16 bits del registro FLAGS se utiliza
pushf y popf.
7) Para meter en y sacar de la pila los 32 bits del registro EFLAGS se utiliza
pushfd y popfd.
=============================================================================
3.6 Otras instrucciones de movimiento de datos.
=============================================================================
LAHF copia la parte baja del registro FLAGS (bits 0 a 7) en el registro AH.
SAHF copia el contenido del registro AH sobre los bits 0 al 7 del registro
FLAGS.

- 16 -

- 17 -

=============================================================================
TEMA 4. INSTRUCCIONES DE CONVERSIN DE DATOS.
=============================================================================
=============================================================================
4.1 Instrucciones de extensin de la representacin con y sin signo.
=============================================================================
En IA-32 se pueden representar nmeros con signo. Para ello se utiliza la
representacin en complemento a 2.
Caractersticas de la representacin en complemento a 2:
- Consideremos que los nmeros son codificados utilizando n bits.
- Si el bit ms significativo es 0, se trata de un nmero positivo. Si es 1, se
trata de un nmero negativo.
- La representacin de un nmero positivo se obtiene representando ese nmero
ocupando (n-1) bits y colocando un cero a la izquierda de ese grupo de n-1 bits.
- Para representar un nmero negativo con n bits en complemento a 2 se hace lo
siguiente:
1)
2)
en n
3)
4)

Se toma el valor absoluto del nmero.


Se obtiene la representacin de ese valor absoluto como un valor positivo
bits.
Se aplica NOT (inversin) a todos los bits de esa representacin.
Se suma 1 al resultado binario de esa operacin.

- 18 -

Nota: cuando se expresa un nmero en complemento a 2 hay que tener muy presente
el nmero de bits utilizados para su representacin. Por ejemplo, -17 en 8 bits
sera (expresado en hexadecimal y complemento a 2) 0xef, mientras que en 16 bits
sera 0xffef.
La finalidad de las instrucciones de extensin es convertir representaciones de
nmeros de 8 a 16 bits, de 8 a 32 bits o de 16 a 32 bits para nmeros
representados con signo o sin signo. En general la extensin de la
representacin de un nmero sin signo simplemente se obtiene rellenando con 0
los bits de mayor orden del nuevo formato. Y la extensin de la representacin
de un nmero con signo se llevar a cabo de acuerdo con las reglas de la
representacin en complemento a 2.
Las instrucciones de extensin sin signo se construyen como MOVZX destino,
fuente. Su funcionalidad es copiar en destino el valor almacenado en fuente con
la extensin correspondiente al tamao destino.
Anlogamente, las instrucciones de extensin con signo se construyen como MOVSX
destino, fuente. Su funcionalidad es anloga.
Las instrucciones MOVSX se utilizan as:
movsx
movsx
movsx
movsx
movsx
movsx

reg16,
reg16,
reg32,
reg32,
reg32,
reg32,

mem8
reg8
mem8
reg8
mem16
reg16

Las instrucciones MOVZX se utilizan anlogamente a las MOVSX.


Hay otras instrucciones de extensin que resultan muy tiles:
- cbw: extiende con signo los 8 bits del registro al sobre los 16 bits del
registro ax.
- cwd: extiende con signo los 16 bits del registro ax sobre los 32 bits del par
de registros dx:ax.
- cdq: extiende con signo los 32 bits del registro eax sobre los 64 bits del par
de registros edx:eax.

=============================================================================
4.2 Conversin "little endian" / "big endian".
=============================================================================
Para almacenar el contenido de registros, palabras o palabras dobles en la
memoria hay dos posibles convenciones que se denominan "little endian" y "big
endian". Unas arquitecturas siguen una convencin, y otras la otra.
- Convencin "little endian": en un conjunto de bytes que representan algo, el
byte menos significativo aparece almacenado en la posicin de memoria ms baja.
Por ejemplo, al almacenar el contenido del registro eax en la memoria a partir
de la direccin X, los bits eax(0-7) se almacenaran en X, los eax(8-15) en X+1,
los eax(16-23) en X+2 y los eax(24-31) en X+3.
- Convencin "big endian": en un conjunto de bytes que representan algo, el byte
de menor orden aparece en la direccin de memoria ms alta. Por ejemplo, si se
desea almacenar la palabra doble 0x11223344 a partir de la direccin de memoria
Y, en la memoria encontraramos 0x11 en Y, 0x22 en Y+1, 0x33 en Y+2, y 0x44 en
Y+3.

- 19 -

La instruccin BSWAP sirve para realizar los cambios necesarios para pasar de
valores almacenados segn la convencin "little endian" a "big endian" y
viceversa.
Utilizacin: bswap reg32.
Funcionalidad: intercambia el contenido del byte 0 de reg32 con el del byte 3, y
el del byte 1 con el del byte 2.
El inters de este concepto y esta instruccin es que IA-32 (y en general, los
procesadores de Intel) utiliza convencin little-endian (lo mismo que otras
arquitecturas), pero hay otras que utilizan convencin big-endian (por ejemplo,
procesadores de Motorola). Cuando hay que intercambiar datos almacenados en
memoria entre computadores con diferente convencin, hay que realizar cuidadosas
transformaciones de los datos utilizando bswap.

- 20 -

=============================================================================

TEMA 5. INSTRUCCIONES ARITMTICAS.


=============================================================================
=============================================================================
5.1 Introduccin.
=============================================================================
IA-32 suministra instrucciones aritmticas de: suma, resta, cambio de signo,
comparacin, multiplicacin y divisin/obtencin de resto.
El registro EFLAGS (registro de estado del procesador, o registro de banderas)
se ve afectado por la ejecucin de las instrucciones aritmticas. Sus funciones
son: 1) mantiene el actual modo de funcionamiento de la CPU, 2) informa sobre
determinados sucesos relacionados con la ejecucin de ciertas instrucciones.
Vamos a comentar los principales bits de EFLAGS que cumplen con esta funcin.

- 21 -

Estos bits son:


Bit
Bit
Bit
Bit
Bit
Bit

0
2
4
6
7
11

C (se le denomina bandera C).


P
A
Z
S
0

Significado de esas banderas:


1) Bandera O (bit 11): se la denomina bandera de desbordamiento. Despus de
ejecutar una operacin aritmtica O se pone a uno si el resultado no cabe en el
operando destino, supuesto que estamos considerando nmeros en representacin
con signo. Por ejemplo, supongamos que hacemos lo siguiente:
al <-- 0x7f
al <-- al + 1
Despus de realizada esta segunda operacin, en al queda 0x80, lo cual no es el
resultado correcto en representacin con signo, pues al ser el resultado un
nmero positivo, el primer bit debera estar a cero: como mnimo, debera ser
0x080, pero eso no cabe en al (cuyo tamao es de 8 bits). Por tanto, despus de
realizar esa operacin aritmtica, la bandera 0 (esto es, el bit 11) se pone a
1.
2) Bandera C (bit 0): se la denomina bandera de acarreo. Despus de ejecutar una
operacin aritmtica C se pone a 1 si el resultado no cabe en el operando
destino supuesto que consideramos nmeros en representacin sin signo. Por
ejemplo supongamos que hacemos lo siguiente:
al <-- 0xff
al <-- al + 1
Despus de realizada la segunda operacin, en al queda 0x00, pero eso no es
correcto. El resultado correcto sera 0x100, pero eso no cabe en al. Por ello C
se pone a 1.
3) Bandera S (bit 7): se la denomina bit de signo. Se pone en 1 despus de
ejecutar una operacin aritmtica si el bit ms significativo del resultado es
1. Esto es, en el resultado se representa un nmero negativo si consideramos una
representacin con signo.
4) Bandera Z (bit 6): se la denomina bit de cero. Se pone a 1 despus de
ejecutar una operacin aritmtica si el resultado es cero.
5) Bandera A (bit 4): se la denomina bandera de acarreo auxiliar. Se pone a 1
despus de ejecutar una operacin aritmtica si hay un desbordamiento en el
"nibble" (grupo de cuatro bits) menos significativo del operando que contiene al
resultado.
6) Bandera P
ejecutar una
resultado es
bits). Si la

(bit 2): se la denomina bandera de paridad. Se pone a 1 despus de


operacin aritmtica si la paridad del byte menos significativo del
par (la paridad es el nmero de unos presentes en un grupo de
paridad es impar, se pone en 0.

- 22 -

=============================================================================
5.2 Suma.
=============================================================================
=============================================================================
5.2.1 Instrucciones ADD y ADC.
=============================================================================
Formato:
add destino, fuente
adc destino, fuente
Ambos operandos (destino y fuente) deben ser del mismo tamao.
Operacin:
add:

destino <-- destino + fuente

adc:

destino <-- destino + fuente + C (C=bandera C, 0 o 1)

A adc se la denomina "suma con acarreo", y C es el bit C del registro EFLAGS.


Utilizacin:
add
add
add
add
add

reg,
reg,
mem,
reg,
mem,

reg
mem
reg
dato inmediato
dato inmediato

Y lo mismo para adc.


Observacin: no se puede realizar directamente la suma del contenido de dos
posiciones de memoria.

=============================================================================
5.2.2 Instruccin INC.
=============================================================================
Suma uno a su operando.
Formato: inc operando
Utilizacin:
inc reg
inc mem
Afecta a las banderas de estado igual que add operando,1 excepto a la bandera C
(bit de acarreo) a la que no afecta.
=============================================================================
5.2.3 Instruccin XADD.
=============================================================================
Instruccin de intercambio y suma.

- 23 -

Formato: xadd destino, fuente.


Ambos operandos pueden ser reg o mem, pero no mem los dos a la vez, y deben ser
del mismo tamao.
La operacin de XADD podemos representarla por el siguiente algoritmo:
temp <-- destino
destino <-- destino + fuente
fuente <-- temp
Afecta a las banderas igual que ADD

=============================================================================
5.3 Instrucciones de sustraccin.
=============================================================================
=============================================================================
5.3.1 Instrucciones SUB y SBB.
=============================================================================
1) Instruccin SUB:
Formato: sub destino, fuente.
Ambos operando pueden ser reg o mem, pero no mem los dos a la vez, y deben ser
del mismo tamao.
Funcin:

destino <-- destino - fuente

Utilizacin:
sub
sub
sub
sub
sub

reg,
reg,
mem,
reg,
mem,

reg
mem
reg
dato inmediato
dato inmediato

2) Instruccin SBB:
Formato: sbb destino, fuente
Funcin: destino <-- destino - fuente - C
Todo lo dems anlogo a SUB.

=============================================================================
5.3.2 Instruccin DEC.
=============================================================================
Resta 1 a su operando.
Formato: dec operando
Utilizacin:
dec reg
dec mem
Afecta a las banderas igual que sub op,1 excepto a la bandera C (bandera de
acarreo), a la que no afecta.

- 24 -

=============================================================================
5.4 Instruccin de cambio de signo (NEG).
=============================================================================
Formato: neg operando
Cambia de signo lo almacenado en el operando, utilizando representacin en
complemento a 2.
Utilizacin:
neg reg
neg mem
Afecta a las banderas igual que sub (equivale a hacer operando <-- 0-operando).
=============================================================================
5.5 Comparacin de valores
=============================================================================
Para comparar valores enteros se utiliza la instruccin CMP. CMP es idntica a
SUB, pero no deja el resultado de la resta en ningn sitio; nicamente afecta al
contenido del registro EFLAGS. Su inters consiste en que estudiando el
contenido final de EFLAGS se puede deducir el resultado de la comparacin entre
los dos operandos (esto es, mayor que, menor que o igual).
Formato: cmp operando1, operando2

Funcin:
(ningn sitio) <-- operando1 - operando2, afectando a EFLAGS como SUB.

Utilizacin:
cmp
cmp
cmp
cmp
cmp

reg,
reg,
mem,
reg,
mem,

reg
mem
reg
inmediato
inmediato

La instruccin cmp nunca se utiliza aisladamente, sino como paso previo para
otra instruccin que tome una decisin basndose en el resultado de la
comparacin realizada por CMP. Esas instrucciones son las de puesta a 1
condicional y las de salto condicional (que comentaremos ms adelante).

=============================================================================
5.6 Instrucciones de multiplicacin de enteros.
=============================================================================
=============================================================================
5.6.1 Instruccin MUL.
=============================================================================
Instruccin de multiplicacin de nmeros enteros en representacin sin signo.
Formato: mul operando

- 25 -

Utilizacin:
mul reg
mul mem
(el operando reg o mem pueden ser de 8, 16 o 32 bits).
Funcin:
1) Operando de 8 bits:
ax <-- al * (operando de 8 bits)
2) Operando de 16 bits:
dx:ax <-- ax * (operando de 16 bits)
3) Operando de 32 bits:
edx:eax <-- eax * (operando de 32 bits)
En una operacin MUL nunca hay prdidas de informacin por desbordamiento.
Afecta al estado de las banderas de forma que no corresponde a la funcionalidad
de las mismas ("estropea" el estado de las banderas).

=============================================================================
5.6.2 Instruccin IMUL.
=============================================================================

Instruccin de multiplicacin de nmeros enteros en representacin con signo.


Soporta los mismos formatos y utilizaciones que mul, y adems los siguientes:
imul
imul
imul
imul
imul

reg,
reg,
reg,
reg,
reg,

reg, inmediato
mem, inmediato
inmediato
reg
mem

Esto es, adems de la operacin soportada por mul, imul soporta lo siguiente:
imul operando1, operando2, inmediato
imul operando1, inmediato
imul operando1, operando2
Funcionalidad, adems de la misma de mul:
1) imul operando1, operando2, inmediato:
operando1 <-- operando2 * inmediato
2) imul operando1, inmediato:
operando1 <-- operando1 * inmediato
3) imul operando1, operando2:
operando1 <-- operando1 * operando 2

- 26 -

Combinaciones de tamaos de operando soportadas por las posibilidades


especficas de imul:
1) imul operando1, operando2, inmediato:
- Los tres de 16 bits o los tres de 32 bits.
- operando1 siempre debe ser un registro.
- operando2 puede ser un registro o una posicin de memoria.
2) imul operando1, inmediato
- operando1 siempre debe ser un registro.
- Los dos operando han de ser de 16 o de 32 bits.
3) imul operando1, operando2
- Los dos operandos deben ser de 16 o de 32 bits.
- operando1 siempre debe ser un registro.
- operando2 puede ser un registro o una posicin de memoria.
Obsrvese que imul slo puede funcionar con operandos de 8 bits cuando se
utiliza en los modos que le son comunes con mul. En sus modos especficos slo
utiliza operandos de 16 o 32 bits.
El resultado de imul se recoge en un operando que tiene el mismo tamao que los
operandos iniciales. Las banderas de estado se ven afectadas de maneras no
conformes con su funcionalidad definida ("estropea" los contenidos de las
banderas). Si hay un desbordamiento, se pierden los bits ms significativos del
resultado.
=============================================================================
5.7 Instrucciones de divisin entera.
=============================================================================
Son las instrucciones:
DIV (divisin sin signo).
IDIV (divisin con signo).
Formato:
div operando
idiv operando
Utilizacin:
div reg
div mem
El operando puede ser de 8, 16 y 32 bits.
idiv se utiliza del mismo modo que div.
Funcionalidad:
Tanto div como idiv ejecutan divisiones entre operandos de los siguientes
tamaos:
- Dividendo de 64 bits entre divisor de 32 bits.
- Dividendo de 32 bits entre divisor de 16 bits.
- Dividendo de 16 bits entre divisor de 8 bits.
Y slo entre esos tamaos de operandos.

- 27 -

Los resultados se recogen de la forma siguiente, en funcin del tamao del


operando:
1) Operando de 8 bits:
Divide ax/operando. El cociente se almacena en al y el resto en ah.
2) Operando de 16 bits:
Divide dx:ax / operando. Cociente: ax. Resto: dx.
3) Operando de 32 bits:
Divide edx:eax / operando. Cociente: eax. Resto: edx.
Para dividir un valor cargado en un almacenamiento del mismo tamao que el del
divisor, es necesario extender el dividendo a un tamao del doble.
Ambas instrucciones afectan a las banderas de manera no conforme con la
definicin del significado de stas. Si se produce una divisin entera por cero,
se produce una excepcin cuyo tratamiento suele ser que el procesador detenga la
ejecucin del programa.

- 28 -

=============================================================================

TEMA 6. INSTRUCCIONES LGICAS Y DE MANIPULACIN A NIVEL DE BIT.


=============================================================================
=============================================================================
6.1 Instrucciones lgicas.
=============================================================================
Son las instrucciones AND, OR, XOR y NOT.
Formato general: instruccin destino, fuente, donde instruccin puede ser and,
or, xor y not.
Esas instrucciones realizan una operacin and, or, xor bit a bit entre los
operandos destino y fuente. not invierte los bits del operando.

- 29 -

Funcionalidad:
and destino,fuente
or destino,fuente
xor destino,fuente
not destino

destino
destino
destino
destino

<-<-<-<--

destino AND fuente


destino OR fuente
destino XOR fuente
NOT (destino)

Utilizacin:
and
and
and
and
and
(or
not
not

reg,reg
mem,reg
reg,mem
reg,inmediato
mem,inmediato
y xor lo mismo que and)
reg
mem

reg y mem deben ser los dos del mismo tamao, pero ste puede ser 8, 16 o 32
bits.

=============================================================================
6.2 Instrucciones de desplazamiento.
=============================================================================

Realizan desplazamientos a nivel de bit en los operandos. Son las siguientes


instrucciones:
shl: desplazamiento a la izquierda.
sal: desplazamiento aritmtico a la izquierda.
shr: desplazamiento a la derecha.
sar: desplazamiento aritmtico a la derecha.
shld: desplazamiento a la izquierda en doble precicisin.
shrd: desplazamiento a la derecha en doble precisin.
El formato general de todas ellas es:
shl destino,contador
sal destino,contador
shr destino,contador
sar destino,contador
shld destino,fuente,contador
shrd destino,fuente,contador
Su funcionalidad es la siguiente:
1) shl / sal: desplazan el contenido del operando destino tantas veces a la
izquierda como exprese el contador. Por la derecha van insertando ceros. El
ltimo bit que desaparece por la izquierda es copiado en C.
2) shr / sar: desplazan el contenido del operando destino tantas veces a la
derecha como exprese el contador. El ltimo bit que desaparece por la derecha es
copiado en C. La diferencia entre shr y sar consiste en lo siguiente:
- shr por la izquierda inserta ceros.
- sar por la izquierda inserta un bit que es copia del bit de mayor orden
(ms significativo) del operando inicial.

- 30 -

3) shld: tiene un funcionamiento que podemos modelar como una secuencia de


pasos.
a) Coloca el segundo operando (fuente) a la derecha del primer operando (el
destino). Con ello es como si se formara una cadena de bits en la que los bits
del operando destino ocupan la parte alta o ms significativa.
b) Desplaza esa cadena de bits tantas veces a la izquierda como exprese el
contador. El ltimo bit que desaparece por la izquierda es copiado en C.
c) Copia la parte alta de la cadena resultante sobre el primer operando (el
operando destino) y deja intacto el segundo operando (el operando fuente).
4) shrd: anlogamente a shld, se modela su funcionamiento como una secuencia de
pasos.
a) Coloca el segundo operando (fuente) a la izquierda del primer operando
(el destino). Con ello es como si se formara una cadena de bits en la que los
bits del operando destino ocupan la parte baja o menos significativa.
b) Desplaza esa cadena de bits tantas veces hacia la derecha como exprese el
contador. El ltimo bit que desaparece por la derecha es copiado en C.
c) Copia la parte baja de la cadena resultante sobre el primer operando (el
operando destino) y deja intacto el segundo operando (el operando fuente).
Utilizacin:
shl
shl
shl
shl

reg,inmediato
mem,inmediato
reg,cl
mem,cl

sal, shr y sar tiene la misma utilizacin que shl.


shld
shld
shld
shld

reg,reg,inmediato
mem,reg,inmediato
reg,reg,cl
mem,reg,cl

shrd tiene la misma utilizacin que shld.


En cuanto al tamao de los operandos, stos pueden ser de 8, 16 y 32 bits para
shl, sal, shr y sar. Para shld y shrd los operandos slo pueden ser de 16 o 32
bits (no de 8), y el operando fuente y el destino han de tener el mismo tamao.
En todas estas instrucciones, la bandera C contiene el ltimo bit expulsado en
el desplazamiento.

=============================================================================
6.3 Instrucciones de rotacin
=============================================================================
Son las siguientes:
rcl:
rcr:
rol:
ror:

rotacin
rotacin
rotacin
rotacin

a
a
a
a

la
la
la
la

izquierda a travs de la bandera C.


derecha a travs de la bandera C.
izquierda sin pasar por C.
derecha sin pasar por C.

- 31 -

Formato general:
instruccin destino,contador
(donde instruccin puede ser rcl, rcr, rol, ror).
Funcionalidad: todas ellas generan una rotacin de tantos pasos como exprese el
contador.
a) rcl: se puede modelar como si la bandera C se hubiera "pegado" a la izquierda
del operando destino y se hace rotar esa estructura tantos bits hacia la
izquierda como exprese el contador.
b) rcr: se puede modelar como si la bandera C se hubiera "pegado" a la derecha
del operando destino y se hace rotar esa estructura tantos bits hacia la derecha
como exprese el contador.
c) rol: se hace rotar el operando destino tantas veces hacia la izquierda como
exprese el contador. El ltimo bit que sale por la izquierda para volver a
entrar por la derecha queda copiado en la bandera C.
d) ror: se hace rotar el operando destino tantas veces hacia la derecha como
exprese el contador. El ltimo bit que sale por la derecha para volver a entrar
por la izquierda queda copiado en la bandera C.
Por tanto, la bandera C contiene el ltimo bit que "sale" del operando destino
debido a la rotacin (sale de ste para ir a C en rcl o rcr, o para volver a
entrar en destino por un extremo de ste).
Utilizacin:
rcl
rcl
rcl
rcl

reg,inmediato
mem,inmediato
reg,cl
mem,cl

rol, rcr y ror se utilizan lo mismo que rcl.


Soportan operandos destino de 8, 16 o 32 bits.
=============================================================================
6.4 Instrucciones de manipulacin a nivel de bit.
=============================================================================
=============================================================================
6.4.1 Instrucciones de comprobacin y modificacin.
=============================================================================
a) Instruccin TEST.
Formato: test destino,fuente
Realiza una operacin AND bit a bit entre los operandos destino y fuente, pero
sin almacenar el resultado en el operando destino. Su efecto nicamente queda
reflejado en las banderas de estado.
Utilizacin:
test
test
test
test
test

reg,reg
reg,mem
mem,reg
reg,inmediato
mem,inmediato

- 32 -

b) Instruccin BT.
Formato: bt fuente,ndice
Copia en C el bit de posicin "ndice" del operando fuente.
Utilizacin:
bt
bt
bt
bt

reg,reg
mem,reg
reg,inmediato
mem,inmediato

c) Instruccin BTR.
Es anloga a BT y adems pone a 0 el bit de la posicin "ndice" del operando
fuente.
d) Instruccin BTC.
Es anloga a BT y adems invierte el bit de la posicin "ndice" del operando
fuente.
e) Instruccin BTS.
Es anloga a BT y adems pone a 1 el bit de la posicin "ndice" del operando
fuente.
f) Instruccin BSF.
Formato: bsf destino,fuente
Busca en el operando fuente el primer bit en 1, comenzando por el bit menos
significativo (el bit 0) y terminando por el bit ms significativo. Si encuentra
un bit en 1, pone la bandera Z en cero y almacena la posicin de ese bit (un
nmero entre 0 y 31) en el operando destino. Si no lo encuentra, pone Z en uno.
Utilizacin:
bsf reg,reg
bsf reg,mem
g) Instruccin BSR.
Es anloga a la instruccin BSF pero comenzando la bsqueda por el bit ms
significativo del operando fuente.

Para todas estas instrucciones el tamao de los operandos es el siguiente: para


test 8, 16 y 32 bits; para el resto slo de 16 o 32 bits (no 8). Como siempre,
cuando hay dos operandos stos deben ser del mismo tamao.
=============================================================================
6.4.1 Instrucciones de escribr 1 si se cumple una condicin.
=============================================================================
Escriben 1 o 0 en un operando de 8 bits segn que se cumpla o no una determinada
condicin. Ese operando puede ser un registro o una direccin de memoria. Si la
condicin se cumple se escribe un 1. Si no se cumple se escribe un 0.
No modifican el estado de las banderas.

- 33 -

Formato general:
instruccin reg
instruccin mem
Clasificamos estas instrucciones segn la condicin que codifiquen. En concreto,
la condicin se puede apoyar sobre:
a) El contenido de las banderas de estado:
(se indica
setc setnc setz setnz sets setns seto setno setp setnp -

al lado de cada instruccin la condicin que se debe cumplir)


condicin: bandera C en 1.
bandera C en 0.
bandera Z en 1
bandera Z en 0
bandera S en 1
bandera S en 0
bandera O en 1
bandera O en 0
bandera P en 1
bandera P en 0

b) El resultado de una precedente instruccin de comparacin (cmp) sin signo. La


instruccin set debe ejecutarse inmediatamente despus de la instruccin cmp, de
manera que ninguna otra operacin haya modificado el contenido de las banderas
de estado.
seta
setna
setae
setnae
setb
setnb
setbe
setnbe
sete
setne

condicin: el resultado de la comparacin es "mayor que".


no mayor que.
mayor o igual que.
no mayor o igual que.
menor que.
no menor que.
menor o igual que.
no menor o igual que.
igual que.
no igual que.

c) El resultado de una comparacin (cmp) con signo. Anlogo comentario que en


b).
setg
setng
setge
setnge
setl
setnl
setle
setnle
sete
setne

mayor que.
no mayor que.
mayor o igual que.
no mayor o igual que.
menor que.
no menor que.
menor o igual que.
no menor o igual que.
igual que.
no igual que.

Nota: cuando se escribe el par de instrucciones siguiente


cmp destino,fuente
seta operando
el significado es "escribir 1 en el operando si el nmero almacenado en destino
es mayor que fuente suponiendo que tanto fuente como destino son nmeros
almacenados en representacin sin signo". Con las dems instrucciones de
comparacin se podran formar anlogas combinaciones.

- 34 -

=============================================================================

TEMA 7. INSTRUCCIONES DE SALTO.


=============================================================================

=============================================================================
7.1 Introduccin.
=============================================================================
Las instrucciones de salto sirven para continuar la ejecucin de un programa en
otra instruccin que no es la que est almacenada inmediatamente despus dentro
de la secuencia almacenada en memoria. Su funcin consiste, por lo tanto, en
modificar el registro de puntero hacia instruccin de una forma especial que
viene establecida por el destino del salto.
Las instrucciones de salto las clasificamos en tres grupos:
- la instruccin de salto incondicional,
- las instrucciones de salto condicional y
- las instrucciones de construccin de bucles.

=============================================================================
7.2 Instruccin de salto incondicional.
=============================================================================
Su formato es: jmp etiqueta

- 35 -

Hace que la ejecucin del cdigo contine en la posicin de memoria marcada como
"etiqueta". Para poder utilizarla, hay que marcar previamente con "etiqueta" la
posicin de destino del salto. Por esa razn se colocan etiquetas dentro del
cdigo del programa.

=============================================================================
7.3 Instrucciones de salto condicional.
=============================================================================
Su formato general es: instruccin etiqueta. La instruccin se escribe como
j[condicin], donde [condicin] son unos caracteres que codifican la condicin
que se debe cumplir para saltar (por ejemplo, nc para indicar que la condicin
es que C est en 0). Por ejemplo, si "sigue" es una etiqueta, una instruccin de
salto condicional podra escribirse as: jnz sigue.
Su funcin es que se contine ejecutando el cdigo en la posicin "etiqueta" si
se cumple la condicin, y si no se cumple la condicin se debe continuar en la
instruccin que sigue a j[condicin].
Se pueden considerar cuatro tipos de condiciones:
-

las basadas en banderas de estado,


las basadas en comparaciones sin signo,
las basadas en comparaciones con signo,
la basada en el contenido del registro ecx.

a) Basadas en banderas de estado:


jc
jnc
jz
jnz
js
jns
jo
jno
jp
jnp

salta
salta
salta
salta
salta
salta
salta
salta
salta
salta

si
si
si
si
si
si
si
si
si
si

C=1.
C=0.
Z=1.
Z=0.
S=1.
S=0.
O=1.
O=0.
P=1.
P=0.

b) Basadas en comparaciones sin signo: estas instrucciones deben ir colocadas


detrs de una instruccin cmp en la que se comparen dos nmeros (destino con
fuente) ambos en representacin sin signo.
ja
jna
jae
jnae
jb
jnb
jbe
jnbe
je
jne

salta
salta
salta
salta
salta
salta
salta
salta
salta
salta

si
si
si
si
si
si
si
si
si
si

la comparacin da "mayor que".


"no mayor que".
"mayor o igual que".
"no mayor o igual que".
"menor que".
"no menor que".
"menor o igual que".
"no menor o igual que".
"igual que".
"no igual que".

c) Basadas en comparaciones con signo: estas instrucciones deben ir colocadas


detrs de una instruccin cmp en la que se comparen dos nmeros (destino con
fuente) ambos en representacin con signo.
jg
jng
jge
jnge

salta
salta
salta
salta

si
si
si
si

"mayor que".
"no mayor que".
"mayor o igual que".
"no mayor o igual que".

- 36 -

jl
jnl
jle
jnle
je
jne

salta
salta
salta
salta
salta
salta

si
si
si
si
si
si

"menor que".
"no menor que".
"menor o igual que".
"no menor o igual que".
"igual que".
"no igual que".

d) Basada en el contenido del registro ecx:


jecxz - salta si ecx=0.

=============================================================================
7.4 Instrucciones de construccin de bucles.
=============================================================================
Sirven para establecer los saltos que permiten cerrar un bucle o grupo de
instrucciones que se ejecuta de manera repetitiva. Estos bucles utilizan el
registro ecx como "contador de vueltas".
Estas instrucciones son:
a) LOOP:
Formato: loop etiqueta
Funcin: en primer lugar decrementa ecx en una unidad (ecx <-- ecx-1), y despus
comprueba ecx; si ecx es distinto de cero salta a etiqueta, y si no contina en
la instruccin que venga a continuacin.
b) LOOPE (o su sinnimo LOOPZ)
Formato: loope etiqueta
Funcin: en primer lugar decrementa ecx en uno, y despus hace una comprobacin
de ecx y la bandera Z. Si ecx es distinto de cero y la bandera Z est en 1,
salta a etiqueta.
c) LOOPNE (o su sinnimo LOOPNZ)
Formato: loopne etiqueta
Funcin: en primer lugar decrementa ecx en uno, y despus hace una comprobacin
de ecx y la bandera Z. Si ecx es distinto de cero y la bandera Z est en 0,
salta a etiqueta.

- 37 -

=============================================================================

TEMA 8. INSTRUCCIONES DE LLAMADAS A SUBRUTINAS.


=============================================================================

=============================================================================
8.1 Introduccin.
=============================================================================

Una subrutina es una determinada porcin de cdigo. Se entra en ella por medio
de un salto que se ejecuta en un punto del programa al que se denomina "llamada
de la subrutina". Cuando se termina su ejecucin se debe continuar ejecutando la
instruccin que viene inmediatamente despus de la de llamada de la subrutina.
El inicio de una subrutina estar marcado dentro del cdigo por medio de una
etiqueta.
Un criterio bsico: habitualmente el estado del procesador al terminar la
ejecucin de una subrutina debe ser el mismo que cuando se llam a esa
subrutina. Por ello, cuando se entra en una subrutina es preciso almacenar el
estado del procesador, con el fin de que al salir o retornar de ella el
procesador recupere ese mismo estado.

- 38 -

La instruccin de llamada de subrutina es CALL y la instruccin que se coloca al


final de una subrutina para retornar de ella al punto del cdigo que sigue a la
llamada es RET.

=============================================================================
8.2 Instruccin CALL.
=============================================================================
Sirve para continuar la ejecucin en el comienzo de una subrutina (por tanto,
para construir una llamada de subrutina).
Formato: call etiqueta, donde etiqueta es la etiqueta que marca el comienzo de
la subrutina.
Funcin:
1) Almacena en la pila la direccin de la instruccin que est en el cdigo
inmediatamente despus de esa instruccin call. Esa direccin es el punto de
retorno, al que debe irse en cuanto se termine la ejecucin de la subrutina. Por
tanto, para hacer eso introduce 4 bytes dentro de la pila. ESP disminuye en
cuatro unidades despus de haberse ejecutado call.
2) Salta a la posicin marcada con etiqueta.

=============================================================================
8.3 Instruccin RET.
=============================================================================
Es la instruccin que se coloca al final de una subrutina.
Formato: ret
Funcin:
1) Saca de la pila 4 bytes. Interpreta que esos 4 bytes integran la direccin
del punto de retorno que una anterior llamada call introdujo en la pila, en
concreto la llamada que motiv la entrada en esa subrutina.
2) Salta a la direccin de memoria que se construye con esos 4 bytes.
Observacin: Si la subrutina maneja inadecuadamente la pila (por ejemplo, mete
algo en la pila de manera que se termina sin haberlo sacado ni haber restaurado
ESP antes de llegar a ret), ret no sacar la direccin de retorno adecuada. El
retorno ser hacia una posicin errnea, y ello producir un fallo en la
ejecucin del programa.

- 39 -

=============================================================================
TEMA 9. OTRAS INSTRUCCIONES.
=============================================================================

=============================================================================
9.1 Instrucciones de manipulacin directa de las banderas de estado.
=============================================================================

Instruccin CLC: pone la bandera C en 0.


Instruccin STC: pone la bandera C en 1.
Instruccin CMC: invierte el contenido de la bandera C.

=============================================================================
9.2 Instruccin NOP.
=============================================================================

Su ejecucin no produce ningn efecto. Simplemente se trae 1 byte de la memoria


de instrucciones (su cdigo de operacin) y se decodifica. Se contina su
procesamiento sin que ste d lugar a ningn cambio ni en el estado del
procesador ni en la memoria.
Sirve para dejar "huecos" en el cdigo del programa dirigidos a optimizar la
ejecucin del cdigo segn la estructura del procesador (por ejemplo, de acuerdo
con la estructura de un procesador segmentado en previsin de posibles
dependencias de datos, riesgos de control, etc.).

=============================================================================
9.3 Instruccin RDTSC.
=============================================================================

Almacena en el par de registros edx:eax el nmero de ciclos de reloj que han


transcurrido desde la ltima reinicializacin realizada en el procesador.

- 40 -

=============================================================================

TEMA 10. ACCESO A LOS RECURSOS DEL SISTEMA OPERATIVO.


=============================================================================
=============================================================================
10.1 Concepto y necesidad de las llamadas a recursos del S.O.
=============================================================================
El sistema operativo suministra una serie de funciones que sirven para:
1) Realizacin de diversas tareas relacionadas con la gestin de procesos:
lanzamiento de procesos, finalizacin, comprobacin de estado de ejecucin, etc.
2) Acceso al sistema de entrada/salida, en concreto:
-

Teclado
Pantalla
Dispositivos de comunicaciones
Discos, y en concreto gestin de archivos, manejo de directorios, etc.

Slo a travs de esas funciones se puede tener acceso a esos recursos en un


sistema operativo como UNIX.
Adems hay funciones que ayudan al usuario a realizar ciertas tareas, aunque no
sea forzosamente necesario que recurra a ellas para llevarlas a cabo.

- 41 -

=============================================================================
10.2 Funciones de biblioteca del S.O. y su utilizacin.
=============================================================================

Puede encontrase un listado de las mismas en los manuales de programacin de los


lenguajes de alto nivel para los compiladores de ese sistema operativo. Por
ejemplo, en los manuales de C para programacin dentro de un entorno UNIX.
Para hacer uso de esas funciones, dentro del archivo en ensamblador a la funcin
se la invoca simplemente con call, anlogamente a las subrutinas. Por ejemplo,
para llamar a printf colocaremos "call printf".
Los nombres de las funciones que van a ser utilizadas dentro del cdigo han de
ser declarados como "extern" en la cabecera del archivo en ensamblador.
Paso de parmetros a las funciones:
a) Si el parmetro es simplemente un nmero, se carga dicho parmetro en la
pila.
b) Si el parmetro es una cadena de caracteres es necesario almacenar esa
cadena a partir de una posicin de memoria, colocando un byte 0x00 en la
posicin que siga inmediatamente al ltimo de los caracteres (es el indicador de
final de cadena). Hecho eso, se introduce en la pila la direccin de comienzo de
almacenamiento de la cadena (que ser un grupo de 4 bytes).
c) En el caso de que haya varios parmetros, deben ser introducidos en la pila
en orden inverso al de su aparicin en el formato de la funcin.

Devolucin de resultados de las funciones:


a) Si el resultado es un nmero, ste suele ser devuelto en al, ax o eax segn
el tamao del resultado.
b) Si el resultado es una cadena de caracteres, lo devuelven escribindola en
la memoria a partir de una posicin determinada. La direccin de esa posicin de
inicio debe ser pasada inicialmente a la funcin como parmetro.
Despus de invocar "call funcin" hay que eliminar de la pila los parmetros
introducidos; para ello puede hacerse dos cosas:
1) Realizar tantos pop de palabras como push de palabras se hayan realizado
para introducir esos parmetros.
2) Modificar directamente el registro ESP (de puntero de cabeza de pila). En
concreto, se le hace volver al valor que tena antes de introducir los
parmetros de la funcin.

- 42 -

Ejemplo de utilizacin de una funcin de la biblioteca del S.O.:


Escribir en pantalla "Resultado = [entero]" donde [entero] es el contenido de
eax interpretado como un nmero en representacin con signo.

extern printf
section .text
push eax
push dword cadena
call printf
add esp, 8

cadena

section .data
db 'Resultado = %d',10,0

Nota: el 10 de la cadena de formato se introduce para que se salte de lnea


despus de escribir eso en pantalla.

- 43 -

=============================================================================

TEMA 11. LOS MODOS INDIRECTOS.


=============================================================================
=============================================================================
11.1 Introduccin.
=============================================================================
Concepto: una instruccin utiliza un modo indirecto si para referirse a una
determinada posicin de memoria, en lugar de expresar directamente el nmero de
dicha direccin, se refiere a ella a travs de un lugar de almacenamiento en el
que est escrito el nmero que expresa dicha direccin.
Utilizacin:
1) En instrucciones que impliquen acceso a memoria. A ello se denomina
direccionamiento indirecto.
2) En instrucciones de salto, para expresar la direccin de destino del
salto. A ello se denomina los saltos indirectos.
3) En las llamadas de subrutina (call), para indicar el punto de comienzo de
la subrutina. A ello se denomina llamadas indirectas a subrutinas.

- 44 -

=============================================================================
11.2 Direccionamiento indirecto.
=============================================================================
Para fijar ideas, en este apartado mencionaremos ejemplos con la instruccin
mov, pero anlogamente podra utilizarse todo lo que se comente aqu para
cualquier otra instruccin que acceda a alguna posicin de la memoria.
En una instruccin (por ejemplo, mov) se puede hacer referencia a una direccin
de memoria que:
1) Est cargada en un registro de 32 bits.
2) Se puede construir en base a operaciones aritmticas sobre nmeros
cargados en registros.
Hay cuatro maneras de realizar el direccionamiento indirecto:
a) Direccionamiento indirecto por registro:
Un registro de 32 bits contiene la direccin involucrada. Por ejemplo, si se
desea cargar los 32 bits que estn almacenados en la memoria a partir de la
posicin de memoria etiquetada como "a" podemos hacer lo siguiente:
lea ebx, [a]
mov eax, [ebx]
b) Direccionamiento indirecto indexado:
Se referencia una posicin de la memoria que se obtiene sumando un nmero (al
que se denomina desplazamiento) al contenido de un registro. El formato general
sera:
mov destino, [reg+desplazamiento]
donde desplazamiento es un nmero. Puede ponerse reg+desplazamiento o regdesplazamiento.
c) Direccionamiento indirecto con base ms ndice:
Se referencia a una posicin de la memoria que se obtiene en base a alguna de
las siguientes expresiones:
registro1+registro2
registro1+a*registro2 donde a puede ser 2, 4 u 8.
(Nota: no se puede poner registro1-registro2 ni registro1-a*registro2).
d) Direccionamiento indirecto con base, ndice y desplazamiento.
Se referencia una posicin por la suma del contenido de dos registros ms un
desplazamiento:
registro1+registro2+desplazamiento
registro1+a*registro2+desplazamiento (donde a puede ser 2, 4 u 8)
registro1+a*registro2-desplazamiento

- 45 -

=============================================================================
11.3 Saltos indirectos.
=============================================================================

Se establece la direccin de un salto en base al contenido de:


1) Un registro: por ejemplo, se desea saltar hacia la posicin etiquetada como
"destino"; se puede escribir para ello lo siguiente:
lea eax, [destino]
jmp eax

; se carga en eax la direccin de destino del salto

salta a la direccin expresada en el registro eax.

2) Una direccin que ha sido almacenada en memoria como una palabra doble a
partir de una determinada posicin. Por ejemplo, supongamos que el destino del
salto es la posicin de memoria etiquetada como "destino"; para saltar all
puede hacerse lo siguiente:
lea eax, [destino] ; obtenemos en eax la direccin de la etiqueta
destino
mov [a], eax

; almacenamos a partir de la posicin


; a la direccin destino

jmp [a]

; salta a la direccin que construye tomando los


; cuatro bytes almacenados a partir de
; la posicin etiquetada como a

Nota: slo pueden construirse saltos indirectos incondicionales.

=============================================================================
11.4 Llamadas indirectas a subrutinas.
=============================================================================
Se construyen anlogamente a los saltos indirectos.
Se establece la direccin de comienzo de la subrutina en base al contenido de:
1) Un registro que contiene una direccin de 32 bits: call reg32. El contenido
de ese registro es la direccin de inicio de la subrutina.
2) Una posicin de memoria a partir de la que se han almacenado 4 bytes
consecutivos, con los cuales se construye la direccin de inicio de la
subrutina: call [mem32].

- 46 -

=============================================================================

TEMA 12. LA UNIDAD ARITMTICA DE PUNTO FLOTANTE.


=============================================================================

=============================================================================
12.1 Introduccin.
=============================================================================
IA-32 tiene una serie de instrucciones para utilizar la unidad de punto flotante
o FPU. Esa unidad est dentro de la CPU y es una unidad aritmtica especializada
en realizar operaciones con nmeros representados en formato de punto flotante.
La FPU posee diversos registros internos, entre los que destacaremos los 8
registros de datos y el registro de estado.

- 47 -

=============================================================================
12.2 Tipos de datos manejados por la FPU.
=============================================================================
La FPU de IA-32 soporta tres formatos de representacin de nmeros en punto
flotante:
a) Formato de precisin simple:
- Son 32 bits.
- Bits 0 al 22: mantisa (23 bits). Es la mantisa del nmero expresado en
binario como 1.[mantisa].
- Bits 23 al 30: exponente (8 bits). Es el resultado de representar en
binario la suma del exponente ms 127.
- Bit 31: bit de signo. 0 si es positivo. 1 si es negativo.
- El nmero se obtiene as:
nmero=(signo)1.[mantisa]*2^(bits de exponente - 127)
- Rango: [ - 2^128 ... -2^(-127)]... 0 ...[2^(-127) ... 2^128].
- En la prctica, una precisin de unos 6 dgitos en base 10.
b) Formato de precisin doble:
- Son 64 bits.
- Anlogo a precisin simple, con un mayor nmero de bits.
- Bits 0 al 51: mantisa (52 bits).
- Bits 52 al 62: exponente (11 bits). Es el resultado de representar en
binario la suma del exponente ms 1023.
- Bit 63: signo.
- Rango: +/- 2^(+/- 1024).
- En la prctica, una precisin de unos 14 dgitos en base 10.
c) Formato de precisin extendida:
- Son 80 bits.
- Bits 0 al 63: mantisa (64 bits). Es la mantisa real del nmero.
- Bits 64 al 78: exponente (15 bits). Es el resultado de representar en
binario la suma del exponente ms 16383.
- Bit 79: signo.
- Rango: +/- 2 ^ (16384).
- En la prctica, una precisin de unos 19 dgitos en base 10.
Internamente la FPU siempre utiliza nmeros expresados en precisin extendida.
La IA-32 suministra instrucciones de punto flotante (FP) para manipular nmeros
representados en cualquiera de las 3 precisiones. Antes de realizar las
operaciones, la FPU convierte internamente los valores suministrados en nmeros
representados en precisin extendida.

=============================================================================
12.3 Los registros de la FPU.
=============================================================================
a) Los registros de datos.
Son ocho registros.

Cada uno tiene un tamao de 80 bits. Por tanto, cada uno puede almacenar un
nmero expresado en formato de precisin extendida.
No funcionan como los registros enteros de propsito general:

- 48 -

- Estn organizados como una pila LIFO (ltimo en entrar, primero en salir) a
la que se denomina la pila FPU.
- En ensamblador se les denomina como st0, st1, st2, ... st7.
- st0 hace referencia al valor que est en la cabeza de la pila.
- st7 hace referencia al valor que puede estar ms al fondo de la pila.
- Cuando se introduce un dato en la pila-FPU entra en st0, lo que hace que lo
que antes estaba almacenado en st0 se cargue en st1, y as sucesivamente. Cuando
se saca un dato de st0, lo que estaba en st1 sube a st0, lo de st2 a st1 y as
sucesivamente. Por ello se dice que estos registros estn organizados como una
pila LIFO.

b) El registro de estado de la FPU.


Es un registro de 16 bits.
Descripcin de algunos de sus bits: los bits 0 al 7 son las banderas de
excepcin. Los bits 8, 9, 10 y 14 se denominan bits de cdigo de condicin FPU.

=============================================================================
12.4 Instrucciones de movimiento de datos en la FPU.
=============================================================================
a) FLD
Carga en la pila FPU un nmero representado en formato de punto flotante que
puede estar almacenado en:
- La memoria, en formato de 32, 64 u 80 bits.
- Otro registro de la pila-FPU. En ese caso, lo que hace es reintroducir ese
valor en la pila-FPU.
Formato y utilizacin:
fld
fld
fld
fld

mem32
mem64
mem80
sti, donde i puede ser 0, 1, ... 7

b) FSTP
Saca el contenido de st0 y lo lleva hacia:
- La memoria, almacenndolo ocupando 32, 64 u 80 bits (segn el tipo de
representacin FP con el que se desee almacenar ese valor dentro de la memoria).
- Un registro de la pila FPU. En ese caso, copia st0 en el registro sti y
saca el valor de st0 de la pila, con lo que cada valor sti sube a st(i-1).
Formato y utilizacin:
fstp
fstp
fstp
fstp

mem32
mem64
mem80
sti, donde i puede ser 0, 1, ... 7

- 49 -

c) FST
Hace lo mismo que fstp pero sin sacar st0 de la pila.
A diferencia de fstp, slo puede almacenar valores en memoria ocupando 32 o 64
bits, pero no 80.

d) FXCH
Su formato es:
fxch sti , donde i puede ser 1, ... 7
Intercambia los contenidos de st0 y sti.

=============================================================================
12.5 Instrucciones de conversin de datos.
=============================================================================
Sirven para realizar conversiones de valores almacenados como enteros (en
representacin con signo en complemento a 2) a valores almacenados en formato de
punto flotante y viceversa.
a) FILD
Formato:
fild mem16
fild mem32
fild mem64
A partir de mem16, mem32 o mem64 se supone que hay un entero almacenado ocupando
16, 32 o 64 bits respectivamente. FILD lee ese nmero, lo convierte a
representacin de punto flotante extendida y lo introduce en st0.
b) FISTP
Formato:
fistp mem16
fistp mem32
fistp mem64
Saca el contenido de st0 y lo almacena en formato entero (haciendo redondeo de
la parte decimal si procede) de 16, 32 o 64 bits.
c) FIST
Hace lo mismo que fistp sin sacar el valor de st0. A diferencia de fistp slo
opera con representaciones en memoria de 16 o 32 bits para almacenar los enteros
(no 64 bits).
Nota: para especificar el tamao de la representacin en memoria se utilizan las
partculas word (16 bits), dword (32 bits) o qword (64 bits) delante de la
etiqueta que especifica el lugar de la memoria.

- 50 -

=============================================================================
12.6 Las instrucciones aritmticas.
=============================================================================
Sirven para llevar a cabo operaciones aritmticas entre nmeros almacenados en
formato de punto flotante.

=============================================================================
12.6.1 Suma FP.
=============================================================================
fadd mem32
fadd mem64
Suman el contenido de mem32 o mem64 a st0 y dejan el resultado en st0. mem no
puede ser algo almacenado en memoria en formato de punto flotante de precisin
extendida. Simplemente podemos expresarlo as:
fadd mem;

st0 <-- st0 + mem

(mem puede ser 32 o 64, no 80)

Utilizaremos esta forma simplificada de comentar el funcionamiento para el resto


de las instrucciones, salvo aqullas que precisen alguna aclaracin adicional.
fadd sti;

st0 <-- st0 + sti (i=0,...,7)

fadd to sti; sti <-- st0 + sti (i=0,...,7)


faddp sti;

sti <-- st0 + sti (i=0,...,7) y saca st0 de la pila.

=============================================================================
12.6.2 Sustraccin FP.
=============================================================================
fsub mem;

st0 <-- st0 - mem (mem puede ser 32 o 64, no 80)

fsub sti;

st0 <-- st0 - sti (i=0,...,7)

fsub to sti; sti <-- sti - st0 (i=0,...,7)


fsub sti,st0;

lo mismo que fsub to sti

fsubr mem;

st0 <-- mem - st0 (mem puede ser 32 o 64, no 80)

fsubr sti;

st0 <-- sti - st0 (i=0,...,7)

fsubr to sti;sti <-- st0 - sti (i=0,...,7)


fsubr sti,st0; lo mismo que fsubr to sti
fsubp sti;

sti <-- sti - st0 y saca st0 de la pila

fsubrp sti;

sti <-- st0 - sti y saca st0 de la pila

- 51 -

=============================================================================
12.6.3 Multiplicacin FP.
=============================================================================
fmul mem;

st0 <-- st0 * mem (mem puede ser 32 o 64, no 80)

fmul sti;

st0 <-- st0 * sti (i=0,...,7)

fmul to sti; sti <-- st0 * sti (i=0,...,7)


fmulp sti;

sti <-- st0 * sti

y saca st0 de la pila

=============================================================================
12.6.4 Divisin en FP.
=============================================================================
fdiv mem;

st0 <-- st0 / mem (mem puede ser 32 o 64, no 80)

fdiv sti;

st0 <-- st0 / sti

fdiv to sti; sti <-- sti / st0


fdivr mem;

st0 <-- mem / st0 (mem puede ser 32 o 64, no 80)

fdivr sti;

st0 <-- sti / st0

fdivr to sti;sti <-- st0/

sti

fdivp sti;

sti <-- sti / st0 y saca st0 de la pila

fdivrp sti;

sti <-- st0 / sti y saca st0 de la pila

=============================================================================
12.6.5 Otras instrucciones aritmticas FP.
=============================================================================
fsqrt;

st0 <-- raz cuadrada de st0

frndint; st0 <-- valor de st0 redondeado a entero


fabs;

st0 <-- valor absoluto de st0

fchs;

st0 <-- (-1)* st0 (cambia de signo el valor de st0)

=============================================================================
12.7 Instrucciones de comparacin FP
=============================================================================

a) fcomi sti (i=0,...,7)


Compara st0 con sti, y el resultado de la comparacin queda reflejado en el
estado de las banderas de EFLAGS.
b) fcomip sti (i=0,...,7)
Compara st0 con sti, el resultado de la comparacin queda reflejado en el estado
de las banderas de EFLAGS y adems saca st0 de la pila.

- 52 -

Obsrvese que fcomi y fcomip pueden utilizarse anlogamente a la instruccin cmp


con el fin de llevar a cabo la comparacin entre valores representados en punto
flotante y luego poder tomar decisiones (saltos, etc.) basadas en esa
comparacin.

=============================================================================
12.8 Predefinicin de constantes
=============================================================================
Colocan en st0 ciertos valores tiles. Obsrvese que no hay ninguna instruccin
de FP que permita la introduccin de inmediatos.
fldz;

st0 <-- 0.0

fld1;

st0 <-- 1.0

fldpi;

st0 <-- nmero pi

fld2t;

st0 <-- logaritmo en base 2 de 10

fld2e;

st0 <-- logaritmo en base 2 del nmero e

fldg2;

st0 <-- logaritmo en base 10 de 2

fldln2;

st0 <-- ln(2)

=============================================================================
12.9 Funciones trigonomtricas y logartmicas.
=============================================================================
a) Funciones trigonomtricas:
fsin;

st0 <-- sen (st0)

fcos;

st0 <-- cos (st0)

fsincos; st0 <-- cos (st0) y st1 <-- sen (st0)


fptan;

st0 <-- tg (st0)

fpatan;

saca st0 y st1 de la pila y hace st0 <-- arctg(st1/st0)

Para utilizar fsin, fcos, fsincos y fptan st0 se supone que est expresado en
radianes y dentro del rango +/- 2^63. fpatan devuelve el resultado expresado en
radianes.
b) Funciones logartmicas:
fyl2x;

saca st0 y st1 de la pila y mete despus en la pila st1*log2(st0)

(Hay otras funciones logartmicas que no comentamos).

- 53 -

=============================================================================
12.10 Operaciones con operandos enteros.
=============================================================================
Realizan las mismas operaciones que sus homnimas cuyos mnemnicos no llevan la
"i", pero considerando que el operando est almacenado en memoria como un entero
de 16 o de 32 bits. Para ello primero convierten internamente (dentro de la FPU,
sin modificar lo almacenado en la memoria) el entero de 16 o 32 bits a
representacin de punto flotante de precisin extendida, y despus realizan la
operacin.
Estas instrucciones siempre utilizan st0 como operando destino.
Para todas ellas el formato de utilizacin es: instruccin mem, donde mem puede
ser mem16 o mem32. mem representa la posicin de la memoria (etiqueta) a partir
de la que est almacenado un entero en representacin de 16 o de 32 bits.
Estas instrucciones son:
a)
b)
c)
d)

Suma:
Sustraccin:
Multiplicacin:
Divisin:

fiadd
fisub,fisubr
fimul
fidiv, fidivr

=============================================================================
12.11 Otras instrucciones FP.
=============================================================================

Hay otras muchas instrucciones FP que no hemos comentado. Simplemente comentamos


una ms, que es finit y que sirve para devolver la FPU a su estado inicial por
defecto. finit reinicializa el registro de estado de la FPU y vaca la pila-PFU.

- 54 -

=============================================================================
TEMA 13. MANIPULACIN DE CADENAS Y CONJUNTOS DE CARACTERES.
=============================================================================

=============================================================================
13.1 Introduccin.
=============================================================================

Vamos a denominar cadena a una coleccin de objetos (bytes, palabras, dobles


palabras) almacenados en posiciones contiguas de la memoria. A ese conjunto de
posiciones contiguas ocupadas por la cadena lo vamos a denominar bloque de
memoria, o sencillamente bloque.
Hay instrucciones especficas para manipulacin de cadenas, que son tiles para
realizar operaciones sobre arrays de datos y cadenas de caracteres.

=============================================================================
13.2 Caractersticas generales de las instrucciones de manipulacin de cadenas.
=============================================================================

Operan sobre bloques.


Operan en memoria. No se les suministra ningn operando explcitamente. Los
datos que controlan el funcionamiento de estas instrucciones estn almacenados
en registros de propsito general.

- 55 -

Implementan las funciones siguientes:


a)
b)
c)
d)

Copiar secuencias de bytes de una ubicacin de memoria hacia otra.


Comparar secuencias almacenadas en memoria.
Buscar un valor dentro de una secuencia.
Inicializar zonas de memoria con un determinado valor.

La operacin que implementan estas instrucciones suele ser la repeticin de una


operacin unitaria, repeticin que viene controlada por:
a) Registro ESI: contiene la direccin inicial del bloque de datos "fuente".
b) Registro EDI: contiene la direccin inicial del bloque de datos "destino".
c) Registro ECX: es el contador, y contiene el nmero de veces que se va a
repetir la operacin unitaria. Se ir modificando durante la ejecucin, y su
valor final ser lo que resulte despus de la ltima modificacin relacionada
con una operacin unitaria.
d) Bandera de direccin: es la bandera D, que es el bit 10 del registro EFLAGS.
- Si D=0, ESI y EDI se incrementan despus de cada operacin unitaria.
- Si D=1, ESI y EDI se decrementan despus de cada operacin unitaria.
- Para establecer el estado de la bandera D se utilizan las instrucciones cld
(pone D en 0) y std (pone D en 1).
e) Registro EAX: asume diversas funciones que detallaremos en cada caso.
Su formato es: [prefijo] [funcin]:
a) Trmino funcin:
Establece el tipo de operacin a realizar.
Puede ser movs, cmps, scas, lods y stos.
Pueden llevar al final las partculas b, w o d para indicar que las operaciones
unitarias se van a realizar respectivamente a nivel de byte, palabra o palabra
doble.
b) Trmino prefijo:
Especifica si va a haber repeticin de operacin unitaria y cmo se va a
realizar sta.
Pueden ser rep, repe y repne.
Cuando se ejecuta una operacin con prefijo, el registro ECX se va decrementando
en una unidad por cada operacin unitaria realizada. Siempre se decrementa en
una sola unidad. Sin embargo, ESI y EDI irn variando de 1 en 1, de 2 en 2 o de
4 en 4, segn que la partcula final de la funcin sea b, w o d respectivamente.
Y adems, la variacin de ESI y de EDI puede ser de incremento o de decremento
segn que D sea 0 o 1, respectivamente, mientras que ECX siempre se decrementa.
Una operacin con prefijo se para necesariamente cuando ECX alcanza el valor
cero, aunque puede pararse antes por otras razones.
Cuando se ejecuta una operacin sin prefijo, se realiza la operacin unitaria
independientemente del valor que tenga ECX, y ste no se ve modificado. S se
ven modificados los registros ESI y EDI.

- 56 -

=============================================================================
13.3 Instruccin movs.
=============================================================================
Copian los valores de un bloque de memoria sobre otro bloque de memoria.
Formatos de utilizacin:
rep movsb;

La copia se realiza byte a byte

rep movsw;

La copia se realiza palabra a palabra

rep movsd;

La copia se realiza palabra doble a palabra doble.

Si no se coloca el prefijo rep, se realiza una sola operacin unitaria de copia.

=============================================================================
13.4 Instruccin cmps.
=============================================================================
Compara dos cadenas, la que comienza en la posicin de memoria indicada por el
registro ESI con la que comienza en la indicada por EDI.
En cada operacin unitaria hace lo siguiente:
1) Se compara el valor de la posicin ESI con el de la posicin EDI.
2) Se actualizan las banderas segn el resultado.
3) ESI y EDI se incrementan/decrementan en 1, 2 o 4 segn que el sufijo de cmps
sea b, w o d respectivamente.

Si se coloca prefijo, ste puede ser repe o repne, y en ese caso ecx debe
contener la longitud de las cadenas comparadas. El significado de los prefijos
es el siguiente:
- repe: la operacin de comparacin se repite mientras en la operacin
unitaria anterior se haya detectado igualdad entre los elementos comparados.
- repne: la operacin de comparacin se repite mientras no se detecte igualdad
en la operacin unitaria anterior.
Esta instruccin puede ser til para comparar cadenas con el fin de ordenarlas
alfabticamente.

=============================================================================
13.5 Instruccin scas.
=============================================================================
Sirve para identificar un determinado elemento (byte, palabra, palabra doble)
dentro de una cadena.
La cadena dentro de la que se busca est depositada en memoria a partir de la
direccin almacenada en EDI.

- 57 -

El funcionamiento es el siguiente:
a) scasb:

compara al con [edi] e incrementa/decrementa edi.

b) scasw:

compara ax con [edi] idem.

c) scasd:

compara eax con [edi] idem.

Despus de cada comparacin unitaria se activan las banderas segn el resultado.


Si hay igualdad en la comparacin, Z se pone en 1.
Los prefijos significan:
- repe: se repite la comparacin mientras haya igualdad.
- repne: se repite la comparacin mientras no haya igualdad.

El nmero de veces que se va a repetir la comparacin unitaria se establece en


ECX.

=============================================================================
13.6 Instruccin stos.
=============================================================================

Almacena en la posicin [edi] el valor especificado en al (con stosb), en ax


(con stosw) o eax (con stosd) e ir incrementando/decrementando edi segn el bit
D en lo que corresponda (1 con stosb, 2 con stosw o 4 con stosd).
Con prefijo rep se repite esa operacin unitaria el nmero de veces especificado
en ECX.
Es til para inicializar cadenas con un valor constante (por ejemplo, poner a
cero el contenido de todas las posiciones de un bloque de la memoria).

=============================================================================
13.7 Instruccin lods.
=============================================================================
Copia el valor contenido en [edi] sobre al (si utilizamos lodsb), sobre ax (si
utilizamos lodsw) o sobre eax (si utilizamos lodsd) y va incrementando o
decrementando EDI segn establezca D y en el valor que corresponda segn la
partcula b, w o d.

- 58 -

=============================================================================

TEMA 14. DESARROLLO DE APLICACIONES.


=============================================================================

=============================================================================
14.1 Introduccin.
=============================================================================
En este tema vamos a estudiar algunos ejemplos de cmo podra expresarse en
ensamblador el contenido de programas desarrollados en C. Se trata de ver cmo
se podra traducir un lenguaje de alto nivel a algo que el computador pueda
ejecutar directamente.
Para poder hacer esto, en primer lugar debemos fijar el tamao de almacenamiento
de las variables que vamos a utilizar en C:
a) char: 8 bits (1 byte). Se supone que el valor almacenado en ella tiene
signo. Por tanto, sern valores comprendidos entre -127 y +127.
b) unsigned char: 8 bits (1 byte). Se supone que almacena un valor sin signo.
Por tanto, comprendido entre 0 y 255.

- 59 -

c) short: 16 bits (2 bytes). Valor con signo.


d) unsigned short: 16 bits (2 bytes). Valor sin signo.
e) int: 32 bits (4 bytes). Valor con signo.
f) unsigned int: 32 bits (4 bytes). Valor sin signo.
g) float: valor representado en formato de punto flotante de precisin simple,
por tanto, 32 bits. Ocupan 4 bytes.
h) double: valor representado en formato de punto flotante de precisin doble,
por tanto, 64 bits. Ocupan 8 bytes.
i) long double: valor representado en formato de punto flotante de precisin
extendida, por tanto, 80 bits. En la prctica una variable tipo long double se
almacena ocupando 12 bytes, en lugar de 10, aunque 2 de esos 12 bytes no se
utilizan para nada.
Para establecer el espacio de memoria utilizado para el almacenamiento del valor
de una variable, etiquetaremos la primera direccin de ese espacio con el nombre
de la variable. No estableceremos otra etiqueta dentro del espacio que se va a
utilizar para esa variable.
Se tendr en cuenta que el etiquetado de las variables sin asignacin de valor
inicial se establecer en la seccin de variables no inicializadas (section
.bss), y el de las variables a las que se asigna un valor en su declaracin se
establecer en la seccin de datos inicializados (section .data). Si hay que
establecer alguna constante o aportar algn dato para el programa, la etiqueta
correspondiente para acceder a l se colocar en la seccin de datos
inicializados (section .data).

- 60 -

=============================================================================
14.2 Ejemplo 1.
=============================================================================
Cdigo en C:
main()
{
int a, b, c;
a=27;
b=541;
c=a+b;
b=a;
printf("Suma = %d\n",c);
}
Traduccin a ensamblador IA-32:

bits 32
global main
extern printf
extern exit

; ===============
;
; Encabezamiento
;
;
; ===============

section .text
main

main() {

mov dword [a], 27

a=27;

mov dword [b], 541

b=541;

mov eax, [a]


add eax, [b]
mov [c], eax

; ===============
;
; c=a+b;
;
; ===============

mov eax, [a]


mov [b], eax

; ===============
;
b=a;
;
; ===============

push dword [c]


push dword cadena
call printf
add esp,8

; ===============
;
; printf("Suma = %d\n",c);
;
;
; ===============

call exit

} fin main

section .data
cadena
db 'Suma = %d',10,0 ; cadena de formato de printf
section .bss
a
b
c

resd 1
resd 1
resd 1

; ===============
;
; int a,b,c;
;
; ===============

- 61 -

=============================================================================
14.3 Ejemplo 2.
=============================================================================
Cdigo en C:
main()
{
int a,b,c;
a=27;
b=541;
c=32;
a=(a+b)/c;
printf("Resultado = %d\n",a);
}

Traduccin a ensamblador IA-32:


; =============
;
; Encabezamiento
;
;
; =============

bits 32
global main
extern exit
extern printf

section .text
main

;
mov dword [a], 27

main() {

; a=27;

mov dword [b], 541 ; b=541;


mov dword [c], 32

; c=32;

mov eax, [a]


add eax, [b]
cdq
idiv dword [c]
mov [a], eax

; =============
;
; a=(a+b)/c;
;
;
;
; =============

push dword [a]


push dword cadena
call printf
add esp,8

; =============
;
; printf("Resultado = %d\n",a);
;
;
; =============

call exit

} fin main()

section .data
cadena

a
b
c

db 'Resultado = %d',10,0 ; cadena de formato de printf

section .bss
;
resd 1
;
resd 1
;
resd 1
;
;

==============
int a,b,c;
==============

- 62 -

=============================================================================
14.4 Ejemplo 3.
=============================================================================

Cdigo C:
main()
{
int a,i;
a=0;
for(i=0;i<10;i++)
{
a=a+1;
printf("Contador = %d\n",a);
}
}

Traduccin a ensamblador IA-32:

bits 32
global main
extern printf
extern exit

; ===============
;
; Encabezamiento
;
;
; ===============

section .text
main

; main() {
mov dword [a], 0

mov dword [i], 0


lazo
cmp dword [i],10
jnl fin_lazo

; a=0;
; ===============
;
; for(i=0;i<10; -> (1)
;
;
; ===============

inc dword [a]

; { a=a+1;

push dword [a]


push dword cadena
call printf
add esp,8

; ===============
;
; printf("Contador = %d\n",a); }
;
;
; ===============

inc dword [i]


jmp lazo
fin_lazo

call exit

; ===============
;
; (1) -> i++)
;
; ===============
;

} fin main

section .data

- 63 -

cadena

db 'Contador = %d',10,0

; cadena de formato de printf

section .bss

a
i

resd 1
resd 1

;
;
;
;

====================
int a,i;
====================

- 64 -

=============================================================================
14.5 Ejemplo 4.
=============================================================================

Cdigo en C:
main()
{
float a,c;
int b;
a=-1.23e-3;
b=7;
c=a*b;
printf(" Producto de a*b = %f\n",c);
printf(" Producto de a*b = %e\n",c);
}

Traduccin a ensamblador IA-32:

bits 32
global main
extern exit
extern printf

; =============
;
; Encabezamiento
;
;
; =============

main
mov eax, [dato]
mov [a], eax

; main() {
; ===============
; a= -1.23e-3
;
; ===============

mov dword [b], 7

b=7;

fld dword [a]


fild dword [b]
fmul st1
fstp dword [c]

; ===============
;
; c=a*b;
;
;
; ===============

; ===============
; c se pasa a prec. doble en aux
;
; printf("Producto de a*b
;
= %f\n",c);
;
;
;
;================
;================
push dword [aux+4] ;
push dword [aux]
; printf("Producto de a*b
push dword cadena2 ;
= %f\n",c);
call printf
;
add esp,12
;
;================
fld dword [c]
fstp qword [aux]
push dword [aux+4]
push dword [aux]
push dword cadena1
call printf
add esp,12

- 65 -

call exit

; } fin del main

section .data
dato
cadena1
cadena2

dd -1.23e-3
; dato -1.23e-3
db ' Producto de a*b = %f',10,0 ; cadena de formato printf 1
db ' Producto de a*b = %e',10,0 ; cadena de formato printf 2

section .bss
a
b
c
aux

resd
resd
resd
resq

1
1
1
1

;
;
;
;

float a;
int b;
float c;
zona auxiliar para conversiones de datos FP

- 66 -

=============================================================================
14.6 Ejemplo 5.
=============================================================================

Cdigo en C:
main()
{
float a[20]={...}; array que contiene los 20 nmeros a promediar
float media; variable que almacena la media
int n; nmero de valores a promediar
int i;
media=0;
n=20;
for(i=0;i<n;i++) media=media+a[i];
media=media/n;
printf("Media = %f", media);
}

Traduccin a ensamblador IA-32:

bits 32
global main
extern printf
extern exit

; ====================
;
;
Encabezamiento
;
;
; ====================

section .text
main
fldz
fstp dword [media]
mov dword [n], 20
mov dword [i], 0
for_i
mov eax, [n]
cmp [i], eax
jnl fin_for_i

;
;
;
;
;
;
;
;
;
;
;
;
;

main(){
===================
media=0;
===================
n=20;
===================
for(i=0;i<n; -> (1)

===================

; ===================
fld dword [media]
; { media=media+a[i]; }
lea eax, [a]
;
mov ebx, [i]
;
fadd dword [eax+4*ebx];
fstp dword [media]
;
; ===================

inc dword [i]


jmp for_i
fin_for_i

; ===================
;
; (1)-> i++) fin lazo for
;

- 67 -

; ===================

fld dword [media]


fidiv dword [n]
fstp dword [media]

; ===================
; media=media/n;
;
;
; ===================

fld dword [media]


fstp qword [aux]
push dword [aux+4]
push dword [aux]
push dword formato_printf
call printf
add esp, 12

; ==================
;
; printf("Media = %f", media);
;
;
;
;
;
; ==================

call exit

; } fin main

section .data
a

dd
dd
dd
dd

1.2, 3.45, -2.67, 4.56, -3.1


3.6, 1.87, 4.31, 3.21, 5.36
-1.98, 2.34, 0.21, 3.77, 2.98
2.39, 3.12, -2.11, -0.23, 0.01

formato_printf db ' Media = %f',10,0

; ================
; float a[20]={1.2, 3.45, ... };
;
;
; ================

cadena de formato de printf

section .bss
media
i
n
aux

resd
resd
resd
resq

1
1
1
1

;
;
;
;

float media;
int i;
int n;
espacio auxiliar para conversin variables FP

- 68 -

=============================================================================
14.7 Ejemplo 6.
=============================================================================

Cdigo en C:;
(Obtener la traspuesta de una matriz de enteros)
main()
{
int a[5][5]={...};
int b[5][5];

/* array de elementos de la matriz */

int i;
int j;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
b[i][j]=a[j][i];
for(i=0;i<5;i++)
for(j=0;j<5;j++)
printf(" %d",b[i][j]);
}

Traduccin a ensamblador de IA-32:

bits 32
global main
extern exit
extern printf

; ================
;
; Encabezamiento
;
;
; ================

section .text
main

; main() {

mov dword [i],0


for_i

; ================
;
; for(i=0;i<5; -> (1)

cmp dword [i], 5 ;


jnl fin_for_i
;
; ================
; ================
;
; for(j=0;j<5; -> (2)
cmp dword [j], 5 ;
jnl fin_for_j
;
; ================
mov dword [j],0
for_j

;
;
;
;

Nota: ubicacin
b+20*i+4*j =
Nota: ubicacin
a+20*j+4*i =

en memoria de
b + 4*(5*i+j)
en memoria de
a + 4*(5*j+i)

b[i][j]:
= b+desplaz.(b)
a[j][i]:
= a+desplaz.(a)

- 69 -

; ================
mov ebx, [i]
;
imul ebx, 5
;
add ebx, dword [j] ;
imul ebx, 4
; b[i][j]=a[j][i];

mov edx, [j]


imul edx, 5
add edx, [i]
imul edx, 4

;
;
;
;

lea
mov
lea
mov

;
;
;
;
; ==================

eax, [a]
ecx, [eax+edx]
eax, [b]
[eax+ebx], ecx

inc dword [j]


jmp for_j
fin_for_j

; ==================
;
; (2) -> j++) fin lazo for_j
;
; ==================

inc dword [i]


jmp for_i
fin_for_i

; ==================
;
; (1) -> i++) fin lazo for_i
;
; ==================

mov dword [i],0


for_i_printf
cmp dword [i], 5
jnl fin_for_i_printf

; ==================
;
; for(i=0;i<5; -> (3)
;
;
; ==================

mov dword [j],0


for_j_printf
cmp dword [j], 5
jnl fin_for_j_printf

; ==================
;
; for(j=0;j<5; -> (4)
;
;
; ==================

mov ebx, [i]


imul ebx, 5
add ebx, [j]
imul ebx, 4

; ===================
;
;
;
; printf("%d",b[i][j]);

lea eax, [b]


mov ecx, [eax+ebx]
push ecx

;
;
;

push dword formato_printf


call printf
add esp, 8

;
;
;
; ==================

- 70 -

inc dword [j]


jmp for_j_printf
fin_for_j_printf

; =================
;
; (4) -> j++) fin for_j_printf
;
; =================

inc dword [i]


jmp for_i_printf
fin_for_i_printf

; =================
;
; (5) -> i++) fin for_i_printf
;
; =================

call exit

; } fin de main()

section .data

dd
dd
dd
dd
dd

1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25

; ================
;
; int a[5][5]={1,2,3,4,... };
;
;
;
; ================

formato_printf db ' %d ',10,0


section .bss
b
i
j

resd 25
resd 1
resd 1

; int b[5][5];
; int i;
; int j;

- 71 -

=============================================================================
14.8 Ejemplo 7.
=============================================================================

Cdigo en C:
(Ordenar una lista de enteros de menor a mayor)

main()
{
int lista[20]={2,3,5,8,1,27,9,7,22,13,375,172,34,21,456,132,25,17,97,23};
int k;
int i;
int temp;
k=1;
while (k==1)
{
k=0;
for(i=0;i<19;i++)
{
if (lista[i]>lista[i+1])
{
temp=lista[i];
lista[i]=lista[i+1];
lista[i+1]=temp;
k=1;
}
}
}
for(i=0;i<20;i++) printf("lista(%d)=%d\n",i,lista[i]);
}

Traduccin a ensamblador de IA-32:

bits 32
global main
extern exit
extern printf

; ===============
;
; Encabezamiento
;
;
; ===============

section .text
main

main() {

mov dword [k],1

lazo_while
cmp dword [k], 1
jne fin_lazo_while

mov dword [k],0

mov dword [i],0

k=1;

; ===============
;
; while(k==1) {
;
; ===============
;

k=0;
; ===============
;

- 72 -

lazo_for_1
cmp dword [i],19
jnl fin_lazo_for_1

inicio_if
lea
mov
mov
mov
cmp
jle

; for(i=0;i<19; ->(1)
;
;
; ===============

ebx, [lista]
ecx, [i]
eax, [ebx+4*ecx]
edx, [ebx+4*ecx+4]
eax, edx
fin_if

mov [temp],eax
mov [ebx+4*ecx],edx
mov [ebx+4*ecx+4],eax

; ================
;
;
; if(lista[i]>lista[i+1])
;
{
;
;
;
; ================
;
;
;
;

================
temp=lista[i];
lista[i]=lista[i+1];
lista[i+1]=temp;

; ================
mov dword [k], 1

;
;
;
;
;
;
;
;
;

fin_if

inc dword [i]


jmp lazo_for_1
fin_lazo_for_1

k=1;

fin del if
================
(1) -> i++) fin lazo for_1
================

jmp lazo_while
fin_lazo_while

; ================
;
} fin lazo while
;
; ================

mov dword [i],0


lazo_for_2
cmp dword [i],20
jnl fin_lazo_for_2

; ================
; for(i=0;i<20; -> (2)
;
;
;
; ================

lea ebx, [lista]


mov eax, [i]
push dword [ebx+4*eax]
push eax
push dword cadena
call printf
add esp, 12

; ================
;
; (2)-> i++) fin lazo for_2
;
; ================

inc dword [i]


jmp lazo_for_2
fin_lazo_for_2

call exit

; ================
;
; printf("lista(%d)=%d\n",i,
;
lista[i]);
;
;
;
;
; ================

; }

fin de main()

- 73 -

section .data

lista

cadena

; =================
dd 2,3,5,8,1,27,9,7,22 ;
dd 13,375,172,34,21,456 ; int lista[20]={2,3,...};
dd 132,25,17,97,23
;
; =================
db 'lista(%d)=%d',10,0

; cadena de formato de printf

section .bss
k
i
temp

resd 1
resd 1
resd 1

; int k;
; int i;
; int temp;

- 74 -

=============================================================================
14.9 Ejemplo 8.
=============================================================================

Cdigo en C:
main()
{
int a,b,c,d,e;
a=15;
b=128;
c=suma(a,b);
d=suma(b,c);
e=suma(d,d);
}
int suma(int x, int y)
{
return x+y;
}

Traduccin a ensamblador de IA-32:

bits 32
global main
extern exit

; ==============
;
; Encabezamiento
;
; ==============

section .text
main

; main() {
mov dword [a], 15

; a=15;

mov dword [b], 128

; b=128;

mov ecx, [a]


mov [x], ecx
mov ecx, [b]
mov [y], ecx
call suma
mov ecx, [r_suma]
mov [c],ecx

; ==============
;
; c=suma(a,b);
;
;
;
;
;
; ==============

mov ecx, [b]


mov [x], ecx
mov ecx, [c]
mov [y], ecx
call suma
mov ecx, [r_suma]
mov [d],ecx

; ==============
;
;
; d=suma(b,c);
;
;
;
;
; ==============

- 75 -

mov ecx, [d]


mov [x], ecx
mov ecx, [d]
mov [y], ecx
call suma
mov ecx, [r_suma]
mov [e],ecx

; ==============
;
;
; e=suma(d,d);
;
;
;
;
; ==============

call exit

; } fin de main

suma
pushad
pushfd
mov eax, [x]
add eax, [y]
mov [r_suma], eax
popfd
popad
ret

a
b
c
d
e

x
y
r_suma

; ==============
;
;
; int suma(int x, int y)
;
;
;
;
;
;
; ==============

section .bss
; ==============
resd 1
;
resd 1
; int a,b,c,d,e;
resd 1
;
resd 1
;
resd 1
;
; ==============

resd 1
resd 1
resd 1

;
;
;
;
;

==============
int x, argumento de suma
int y, argumento de suma
int suma, resultado de suma
==============

- 76 -

=============================================================================
14.10 Ejemplo 9.
=============================================================================
Cdigo en C:
main()
{
char cadena[20], salida[20];
int longitud, i;
for(i=0;i<20;i++)
{
cadena[i]=0;
salida[i]=0;
}
scanf("%s",cadena);
longitud=strlen(cadena);
for(i=0;i<longitud;i++) salida[i]=cadena[longitud-1-i];
printf(" %s",salida);
}
Nota: para escribir strlen(cadena) desarrolle strlen como una subrutina
que recibe la direccin inicial de almacenamiento de 'cadena' a travs
de una palabra doble almacenada a partir de la posicin de memoria
etiquetada como 'entrada' y que devuelve la longitud de la cadena como
un valor entero de 32 bits almacenado a partir de 'resultado'

Traduccin a ensamblador de IA-32:

bits 32
global main
extern exit
extern scanf
extern printf

; ===============
;
; Encabezamiento
;
;
;
; ===============

section .text
main

; main() {
; ==============
;
; for(i=0;i<20; ->(1)
cmp dword [i], 20 ;
jnl fin_for_1
;
; ==============
mov dword [i],0

for_1

lea eax, [cadena]


mov ebx, [i]
mov byte [eax+ebx], 0

; =============
;
; cadena[i]=0;
;
; =============

lea eax, [salida]


mov ebx, [i]
mov byte [eax+ebx], 0

; =============
;
; salida[i]=0;
;
; =============

; ================

- 77 -

inc dword [i]


jmp for_1
fin_for_1

;
; (1)-> i++) fin for_1
;
; ================

push dword cadena


push dword formato1
call scanf
add esp,8

; =================
;
; scanf("%s",cadena);
;
;
; =================

lea eax, [cadena]


mov [entrada], eax
call strlen
mov eax, [resultado]
mov [longitud], eax

; =================
;
;
; longitud=strlen(cadena);
;
;
; ==================

mov dword [i],0


for_2
mov eax, [longitud]
cmp dword [i], eax
jnl fin_for_2

mov ebx, [longitud]


dec ebx
sub ebx, [i]
lea eax, [cadena]
mov bl, [eax+ebx]
lea eax, [salida]
add eax, [i]
mov [eax], bl

; ==================
;
;
; salida[i] =
; cadena[longitud-i-1];
;
;
;
;
;
;
; ==================
; ==================
;
; (2)-> i++) fin for_2
;
; ==================

inc dword [i]


jmp for_2
fin_for_2

push dword salida


push dword formato2
call printf
add esp,8

call exit

; ==================
;
; for(i=0;i<longitud; (2) ->
;
;
;
; ==================

; ==================
;
; printf(" %s",salida);
;
;
; ==================

; } fin de main

- 78 -

strlen

lazo

pushad
pushfd
mov ecx, -1
mov ebx, [entrada]
inc ecx
cmp dword [ebx+ecx],0
jne lazo
mov [resultado], ecx
popfd
popad
ret

; ==================
;
;
;
; funcin strlen
;
;
;
;
;
;
;
;
; ===================

section .data
formato1 db '%s',0
formato2 db ' %s',0

; cadena de formato de scanf


; cadena de formato de printf

section .bss
cadena resb 20
salida resb 20
longitud resd 1
i
resd 1

;
;
;
;

char cadena[20];
char salida[20];
int longitud;
int i;

entrada resd 1
resultado resd 1

; ================
; argumento de entrada de strlen
; salida de strlen
; ================

- 79 -

=============================================================================
14.11 Ejemplo 10.
=============================================================================

Cdigo en C:
main()
{
float hip, alfa, catop, catcon;
hip=187.95;
alfa=0.6477;
catop=hip*sin(alfa);
catcon=hip*cos(alfa);
printf("Hipotenusa=%f alfa=%f cat.opuesto=%f
cat.contiguo=%f\n",hip,alfa,catop,catcon);
}

Traduccin a ensamblador de IA-32:

bits 32
global main
extern printf
extern exit

; ===============
;
; Encabezamiento
;
;
; ===============

section .text
main

; main() {

mov eax, [dato1]


mov [hip], eax

; ==============
;
; hip=187.95;
; ==============

mov eax, [dato2]


mov [alfa], eax

; ==============
;
; alfa=0.6477;
; ==============

; ==============
fld dword [hip]
;
fld dword [alfa] ;
fsin
; catop=hip*sin(alfa)
fmul st1
;
fstp dword [catop];
; ==============

fld dword [alfa]


fcos
fmul st1
fstp dword [catcon]

; ==============
;
; catcon=hip*cos(alfa)
;
;
; ==============

- 80 -

; ==================
;
;
;
;
;
; printf("Hipotenusa=%f alfa=%f
;
cat.opuesto=%f cat.contiguo=%f\n",
;
hip,alfa,catop,catcon);
;
push dword [aux_catcon+4];
push dword [aux_catcon] ;
push dword [aux_catop+4] ;
push dword [aux_catop]
;
push dword [aux_alfa+4] ;
push dword [aux_alfa]
;
push dword [aux_hip+4]
;
push dword [aux_hip]
;
push dword formato_printf;
call printf
;
add esp, 36
;
; =================
fld dword [hip]
fstp qword [aux_hip]
fld dword [alfa]
fstp qword [aux_alfa]
fld dword [catop]
fstp qword [aux_catop]
fld dword [catcon]
fstp qword [aux_catcon]

dato1
dato2

call exit

} fin de main

section .data
dd 187.95
dd 0.6477

; dato 187.95
; dato 0.6477

; ===============
formato_printf db 'Hipotenusa=%f alfa=%f '
; formato de printf
db 'cat.opuesto=%f cat.contiguo=%f',10,0 ;
; ===============
section .bss

alfa
hip
catop
catcon

resd
resd
resd
resd

1
1
1
1

; ===============
;
; float hip,alfa,catop,catcon;
;
;
; ===============

aux_alfa resq 1
aux_hip resq 1
aux_catcon resq 1
aux_catop resq 1

;
;
;
;
;
;

================
zonas auxiliares de almacenamiento
para las conversiones de formatos de FP
================

- 81 -

Das könnte Ihnen auch gefallen