You are on page 1of 14

www.monografias.

com

Assembly language for PC (intel)


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.

Conceptos bsicos
Registros de la CPU
Modos de Direccionamiento
Los Assemblers ms comunes
Instrucciones en Assembly
Multiplicacin y divisin, MUL y DIV:
Ejercicios (1)
Instruccin de salto incondicional, JMP
FLAGS
Intrucciones de comparacin, CMP y TEST
La Pila
Llamados a subrutinas, CALL
Respuestas de los ejercicios
Bibliografa

Este material es un trabajo prctico que se realiz en base a lo dictado en la materia Arquitectura de las
Computadoras II, que pertence a la carrera Analista Universitario en Sistemas, del Instituo Politcnico
Superior Gral. San Martn (Universidad Nacional de Rosario, Argentina).
Conceptos bsicos
Antes de comenzar, conviene aclarar que el lenguaje se denomina Assembly y no Assembler como
normalmente se lo conoce. Cuando se escribe un programa en Assembly, hay otro programa ensamblador
que se encarga de traducir lo diseado por el programador al cdigo de mquina. Esta clase de programa
se llama traductor. Los compiladores e intrpretes son traductores que pasan a cdigo mquina los
programas escritos en los distintos lenguajes. Assembler es el programa traductor de Assembly a cdigo de
mquina, y que es propio de cada modelo de procesador. Cada microprocesador tiene su propio Assembler
con su particular set de instrucciones y sus varios modos de direccionamiento que dependen de la
arquitectura propia del sistema, y cada nuevo modelo de procesador que saca al mercado un fabricante,
puede que agregue algunas instrucciones a su set de instrucciones para mejorar el rendimiento del mismo y
hasta agregar algn nuevo registro (o extender la capacidad de bits de los existentes), pero siempre
conservan las instrucciones y registros de los modelos anteriores por razones de compatibilidad.
Dado que las mayora de las PC usan procesadores Intel o sus clones, desarrollaremos ejercicios para esta
arquitectura de procesadores.
Registros de la CPU:
Los primeros procesadores como el 8088 y el 8086 nos provean de los registros de 16 bits AX, BX, CX, DX,
SI, DI, BP, SP, CS, DS, SS, ES, IP, y FLAGS. El procesador soportaba hasta 1Mb de memoria y solo poda
operar en modo Real. En este modo el programa poda acceder a cualquier direccin de memoria, incluso a
direcciones utilizadas por otros programas. Esto haca muy difcil la depuracin del programa (debugging), y
por lo tanto tampoco era muy seguro. Los datos de los programas se alojaban en memoria todo el tiempo y
eran divididos en segmentos de hasta 64Kb.
Sus cuatro registros principales, AX, BX, CX, y DX estn divididos en dos registros de 8 bits cada uno. Por
ejemplo, el registro AX posee una parte que contiene los primeros 8 bits denominada AH (high) y una parte
que contiene los ltimos 8 bits denominada AL (low), y as sucesivamente con cada uno de los registros
mencionados.
16 bits
AX
BX
CX
DX

8 bits
AH
BH
CH
DH

8 bits
AL
BL
CL
DL

Este tipo de registros se usa especialmente en operaciones aritmticas, ya que nos permite manejarnos con
comodidad cuando trabajamos con datos que no superan un byte, pero se debe tener cuidado ya que AH y

Assembly Language for PC (Intel) Conceptos bsicos y prctica

AL no son independientes de AX, o sea que si hacemos algn movimiento de datos referenciando a AX,
tambin estamos cambiando los valores de AH y AL.
Los registros SI y DI son utilizados generalmente como punteros.
Los registros BP y SP se conocen como los punteros de pila. Se utilizan para moverse dentro de la pila.
CS, DS, SS, y ES son los segments registers. Son los encargados de direccionar las distintas partes de
cada programa:
CS para el code segment, donde se guardan los datos del cdigo de mquina de las instrucciones
que constituyen el programa.
DS para el data segment, que guarda los datos que el programa debe operar y los resultados de la
ejecucin del mismo.
SS para el stack segment, Almacena datos y direcciones necesarias durante la ejecucin de cada
parte del programa y que es localizada dentro del segmento mediante el registro SP (stack pointer).
ES para el extra segment, utilizado para guardar datos tipo strings, tambin como prolongacin del
DS (data segment), y como registro temporal. Cada dato es apuntado dentro del segmento por el
registro puntero DI.
Estos registros cumplan una importante funcin en el direccionamiento a memoria ya que el 8086 poda
manejar solo hasta 1Mb de memoria (2 20 bytes). El rango vlido de direcciones de memoria era de 0x0000
a 0xFFFFF. Este rango de direcciones requera de un nmero de 20 bits, pero el 8086 tena registros de 16
bits. Intel resolvi el problema usando dos segment registers de 16 bits para determinar la direccin. A los
primeros 16 bits se los denominaba selector y a los segundos offset. La direccin fsica real referenciada por
el par de 32 bits formado por el N selector:offset estaba dada por la frmula:
16* selector + offset
Ejemplo:
Queremos calcular la direccin fsica referenciada por el par 047C:0048.
Primero debemos multiplicar a 047C * 16. Cuando multiplicamos por 16 en hexa, agregamos un cero a la
derecha y listo (=047C0),
luego hacemos la suma,
047C0
+0048
04808
y obtenemos que la direccin en memoria es la 0x04808 (que es un n de 20 bits.)
El registro IP (instruction pointer) es utilizado para mantener una pista de la direccin de la prxima
instruccin a ejecutarse por el procesador. Normalmente cuando se ejecuta una instruccin, IP se adelanta
a apuntar a la prxima instruccin en memoria.
El FLAGS es un registro de 16 bits que se divide en 16 partes de 1 bit. Cada uno de estos bits guarda
informacin importante sobre el resultado de la instruccin anterior. Este resultado se guarda con un solo un
bit que puede ser 1 0. Por ejemplo, el bit Z es 1 si el resultado de la instruccin anterior fue 0, y es 0 si el
resultado fue 1. El bit C ser 1 si la ltima operacin produjo acarreo, y 0 si no lo hizo.
El primer procesador para PCs de clase AT fue el 80286. Este incorporaba nuevas instrucciones a su set de
instrucciones y presentaba su nueva forma de procesar en modo Protegido de 16 bits. En este modo el
procesador poda acceder hasta a 16Mb de memoria y proteger a los programas entre s en los accesos a la
memoria. La configuracin de sus registros era la misma que la de su antecesor, y los programas seguan
estando divididos en segmentos de 64Kb. Pero estos segmentos ya no estaban en la memoria todo el
tiempo, solo se mantena a los que necesitaba el programa en el momento de ejecucin. El resto de los
datos y cdigo era alojado en forma temporal en el disco hasta ser necesitados por el programa. Esta
tcnica se la conoce con el nombre de memoria virtual, y es la que se utiliza en la mayora de los sistemas
actuales. A cada segmento se le asigna un index dentro de una tabla descriptora (descriptor table), este
index contiene toda la informacin que el sistema necesita conocer sobre el segmento, incluyendo si est
corriendo actualmente en memoria, si est en memoria, si est en el disco, los permisos de acceso
(lectura/escritura), etc. Este index identificador del segmento es un valor que se guarda en los segment
registers.
Con la aparicin del 80386 se produce un gran salto en el diseo. Primero y principal se extiende la mayora
de sus registros a 32 bits (renombrndolos como EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP) y se
agregan dos registros nuevos de 16 bits (FS, y GS). Para guardar compatibilidad con los diseos anteriores
se conviene de que al hacer referencia a AX, se hace referencia a los ltimos 16 bits de EAX (lo mismo que
era AL de AX); pero no se puede tener acceso directo a los primeros 16 bits de EAX.

Arquitectura de las Computadoras II

Pgina 2 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

Segundo, el procesador presenta su nuevo modo de trabajo denominado modo protegido de 32 bits. Este
modo presenta dos grandes diferencias con el modo protegido de 16 bits:
1. Se puede acceder hasta a 4Gb de memoria. Los programas se seguan dividiendo en segmentos,
pero ahora cada segmento poda tener hasta 4Gb de tamao.
2. Los segmentos se pueden subdividir en pequeas unidades de 4Kb de tamao llamadas pginas.
La memoria virtual trabaja ahora con pginas en lugar de segmentos. De esta manera, solo una
parte del segmento puede estar en cualquier momento. En el modo protegido de 16 bits, solo se
puede mover el segmento entero a la memoria, esto no hubiera sido muy prctico si consideramos
los largos segmentos de 32 bits del 80386.
Modos de Direccionamiento:
Existen cuatro modos principales para manejar los datos entre los registros, las direcciones de memoria, y
las constantes. NUNCA podemos pasar un dato constante a una direccin de memoria directamente,
siempre deberemos llevar el dato a un registro, y luego de este a la memoria.
Para ello debemos primero conocer que toda instruccin en Assembly, esta construida de la siguiente forma
<instruccin> <destino>,<fuente>.
Estos modos se denominan:
Modo directo: Se denomina as cuando en una instruccin se da directamente la direccin de
memoria del dato a procesar. Ej.: MOV EAX,[5000] ,al estar el nro. 5000 entre [], le estamos
indicando al procesador que mueva el dato que est en la direccin de memoria 0x5000 al registro
EAX.
Modo registro: Cuando el dato que necesitamos procesar ya se encuentra en un registro.
Ej.: MOV EAX,EBX ,aqu estamos indicando que lleve una copia del dato que est en EBX a EAX.
Modo inmediato: Se denomina as cuando ordenamos pasar una constante a un registro.
Ej.: MOV EAX,3000 ,estamos pasando el nro. 3000 al registro EAX.
Modo indirecto por registro: Cuando queremos pasar a un registro, el contenido del contenido de
otro, es decir. EJ.: MOV EAX,[EBX], el contenido de la direccin de memoria almacenada
actualmente en EBX, se cargar en EAX.
Los Assemblers ms comunes:
Netwide Assembler (NASM).
Microsoft Assembler (MASN).
Borland Assembler (TASM).
Como existen algunas diferencias de sintaxis entre el MASM, TASM, y el NASM, hemos elegido a este
ltimo para el desarrollo de algunos de nuestros ejercicios de 32 bits. El mismo se puede obtener en forma
gratuita de http://sourceforge.net/projects/nasm.
Para los ejercicios basados en 16 bits, usaremos el DEBUG de DOS. Simplemente salimos desde cualquier
versin de Windows al MS-DOS Prompt (o smbolo de sistema en la versiones 2000 y XP), y tipeamos
DEBUG. Una vez que entramos al programa, elegimos una direccin de memoria inicial para cargar las
instucciones (Ej.: A100), al finalizar con este proceso ingresamos ENTER y luego tipeamos la t para ver el
estado de los registros en cada una de las instrucciones. Para salir tipeamos q.
Instrucciones en Assembly:
Por fin vamos a empezar con instrucciones en Assembly. Y comenzaremos con la ms sencilla, pero
curiosamente la ms utilizada en este lenguaje:
La instruccin MOV:
La funcin de la instruccin MOV, es como su nombre da a entender, "mover" un valor. Pongamos un
ejemplo:
MOV AX,BX
Esta instruccin copia el contenido de BX en AX, conservando el valor de BX.
Veamos algunos ejemplos ms:
MOV AX,2000
MOV [a100],AX
En este caso introducimos el valor 2000 en AX, y luego lo llevamos a la direccin de memoria A100.
En resumen, con la instruccin MOV podemos hacer las siguientes operaciones:
Tipo de operacin
MOV registro,registro
MOV memoria,registro
Arquitectura de las Computadoras II

Ejemplo
MOV AX,BX
MOV [2000],AX
Pgina 3 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

MOV registro,memoria
MOV registro,constante

MOV BX,[1500]
MOV AX,1000

Las instrucciones INC y DEC:


Son las ms bsicas a la hora de hacer operaciones con registros:
INC, incrementa el valor de un registro (o de cualquier posicin de memoria ) en una unidad.
DEC, lo decrementa en el mismo valor. Ejemplos:
INC AX
DEC AX
Incrementa en una unidad el valor de AX y lo decrementa, por lo que no ha cambiado su valor.
Estas dos instrucciones nos van a servir mucho en el uso de contadores en los bucles. Son equivalentes a +
+ y -- del lenguaje C.
Las instrucciones ADD y SUB:
Se trata de dos operadores que contienen todos los lenguajes de programacin: la suma y la resta. Tienen
dos operandos, uno de destino y otro fuente.
Para la suma, se suman los dos operandos y se almacena el resultado en el primero (destino).
Para la resta, se le resta al primero el segundo, y se almacena el resultado en el primero (destino).
Ejemplos:
ADD AX,BX
;Suma a AX con BX, y lo guarda en AX. (AX+BX) -> AX
ADD AX,[SI]
;Se suman AX y el contenido de lo que esta apuntado por SI
;y se almacena en AX. (AX+[SI]) -> AX
ADD AX,3
;Suma 3 a AX y lo almacena en AX. (AX+3) -> AX
SUB AX,AX
;Resta AX de AX. Se utiliza para poner a AX en 0.
;(AX-AX=0) -> AX
SUB CX,DX
;Se resta el valor de CX con DX y se almacena en CX.
;(CX-DX) -> CX
SUB CX,20
;Se resta de CX el valor 20, y queda en CX el resultado.
;(CX-20) -> CX
(Introducimos el uso de la ; para hacer comentarios. Es lo mismo que usar en lenguaje C la // /*.......*/)
Estas operaciones pueden modificar los FLAGS de estado si se producen acarreos en las sumas o nmeros
negativos en las restas.
Estos casos los trataremos ms adelante.
Multiplicacin y divisin, MUL y DIV:
Estas operaciones multiplican o dividen al acumulador (AX) por el operando indicado. Si el operando es de 8
bits (1 byte ), el acumulador es AL. Si el operando es de 16 bits, el acumulador es AX. En el caso de
procesadores de 32 bits, si el operando tiene 8 16 bits el acumulador ser AX. El resultado se almacena
en AX, en el par DX, AX respectivamente, si el operando es de 8 bits 16 bits.
En el caso de la divisin, si hubiera resto se guardar en DX.
Ejemplos:
Multiplicacin de dos nmeros de 8 bits:
MOV CL,20
;Cargo en CL un nmero de 8 bits (0x20)
MOV AL,30
;Cargo en AL un nmero de 8 bits (0x30)
MUL CL
;Multiplico CL por AL, y guardo el resultado en AX
;(AL*CL) -> AX
Multiplicacin de dos nmeros de 16 bits:
MOV BX,1000
;Cargo en CX un nmero de 16 bits (0x2000)
MOX AX,1200
;Cargo en AX un nmero de 16 bits (0x1200)
MUL BX
;Multiplico BX por AX, y guardo el resultado en DX (mitad
;superior y en AX (mitad inferior). (AX*BX) -> (DX y AX)
Divisin de dos nmeros de 8 bits:
MOV AX,30
;Cargo en AX un nmero de 8 bits (0x30)
MOV BX,12
;Cargo en BX un nmero de 8 bits (0x10)
DIV BX
;Divido AX/BX, y guardo el resultado en AX. El resto de la
;divisin se guardar en DX
Arquitectura de las Computadoras II

Pgina 4 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

Divisin de un nmero de 32 bits por uno de 16 bits:


MOV AX,5000
;Cargo en AX los 16 bits inferiores de un nmero de 32
;bits (0x65005000)
MOV DX,6500
;Cargo en DX los 16 bits superiores del nmero
;anterior (0x65005000)
MOV CX,2500
;Cargo en CX un nmero de 16 bits que ser el divisor
;(0x2500)
DIV CX
;Divido (DX,AX)/CX y guardo el resultado en AX. El
;resto de la divisin se guardar en DX
Pero el procesador puede diferenciar entre operaciones con nmeros con signo y sin signo. Cuando
utilicemos nmeros que involucran las operaciones multiplicacin y divisin de nmeros con signo,
utilizaremos las instrucciones IMUL y IDIV respectivamente.
Ejercicios (1):
Son algunos ejercicios de operaciones aritmticas y modos de direccionamiento:
1) Indique que realizan las siguientes instrucciones, aclarando en cada caso los modos de direccionamiento
utilizados:
MOV AX,10
MOV BX,[100]
ADD CX,[AX]
ADD BX,2
DEC CX
2) Realice un programa que haga la siguiente operacin A=B+B-C. El dato B se encuentra en la direccin
5000, el C en 5006, y el resultado A hay que alojarlo en 5010.
3) Realice un programa que haga la siguiente operacin A=((B+C)*B)/C. Utilice los mismos datos del
ejercicio anterior, haciendo que el resto de la divisin se aloje en la direccin 2000.
Operaciones lgicas NEG, NOT, AND, OR, XOR:
NEG, pone el registro o el contenido de una direccin de memoria en negativo segn la aritmtica de
complemento a dos (NEG AX, NEG [2000]).
NOT, ordena invertir cada bit del operando. Supongamos que AX = 0x1000, al hacer NOT AX, el contenido
de AX cambiar a 0xEFFF.
AND, realiza la operacin lgica entre dos valores y guarda el resultado en el valor destino.
OR, realiza la operacin lgica entre dos valores y guarda el resultado en el valor destino.
XOR, realiza la operacin lgica entre dos valores y guarda el resultado en el valor destino.
Instruccin de salto incondicional, JMP:
Se puede cambiar el control a cualquier punto del programa sin condiciones.
Se utiliza de la siguiente forma:
JMP 03424h
Donde 03424h, es la direccin a la cual queremos saltar.
Pero como hacemos para calcular la direccin de donde va a estar la instruccin a la cual queremos
avanzar?
Para ello utilizaremos etiquetas y saltaremos directamente al nombre de la etiqueta.
Ejemplo: (entre parntesis se muestra el orden de ejecucin de estas instrucciones)
(1)
MOV AX,1000
;Cargo en AX el nmero 0x1000
(2)
MOV CL,22
;Cargo en CL el nmero 0x22
(3)
JMP AVANZA
;Llamo a la instruccin etiquetada como AVANZA
(6)
VUELVE: ADD BX,AX
;Sumo a BX el valor de AX (BX=0x2000)
(7)
JMP FIN
;Llamo a la instruccin etiquetada como FIN
(4)
AVANZA: MOV BX,AX
;Cargo en BX el valor de AX (BX=0x1000)
(5)
JMP VUELVE
;Llamada a la etiqueta VUELVE
(8)
FIN: SUB CX,BX
;Sumo a CX el valor de BX (CX=0x2022)
Las etiquetas tienen que estar continuadas por dos puntos ':', y pueden ser llamadas desde cualquier lugar
del programa. Tambin podremos hacer un MOV AX,[AVANZA], como hacamos antes con un MOV AX,[BX],
pero asignando a AX el valor que haya en la direccin de memoria en la que est "AVANZA".
Arquitectura de las Computadoras II

Pgina 5 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

FLAGS:
La explicacin de los "flags" est relacionada con el uso de los saltos condicionales. Utilizaremos algunos
de estos flags para instrucciones donde haya que tomar decisiones (del tipo IF-THEN-ELSE, WHILE, FOR
en otros lenguajes).
Como se explic en la introduccin de este apunte, los flags (banderas) los agrupa un solo registro de 16
bits (denominado registro de estados S). Aunque este no est utilizado por completo, ya que cada flag
ocupa un solo bit, cada uno de estos pueden valer 1 0 y dependiendo de su valor indican varias cosas. El
registro de flags es el siguiente:
Nmero de bit
0
1

Nombre
C
--

3
4
5

-A
--

10

11

12
13
14
15

-----

Utilizacin
Carry. Se pone en 1 si se produjo acarreo en la ltima operacin realizada.
No utilizado.
Paridad. Se utiliza especialmente en la transmisin de datos para la
comprobacin de errores, ya que comprueba si el resultado de la ltima
operacin aritmtica lgica realizada tiene un nmero par o impar de bits
puestos a uno. Se pondr en 1 cuando haya un nmero par de bits, y a 0
cuando sea impar.
No utilizado.
Auxiliar Carry. Se utiliza como verificador auxiliar de acarreos.
No utilizado.
Zero. Es el que ms interviene en las operaciones con bucles. Simplemente
se activa a 1 cuando el resultado de una operacin aritmtica lgica es
cero o devuelve verdadero. Por ejemplo, si tenemos dos valores iguales en
CX y AX y hacemos SUB CX,AX el flag Z se pondr en 1. Lo mismo pasa
con una operacin lgica, si esta es verdadera, Z se pondra en 1.
Sign (o signo). Indica cuando tras una operacin aritmtica lgica el
resultado es un nmero en complemento a dos, por lo tanto, cuando vale 1
es que el nmero es negativo y si vale 0 es positivo.
Trap. Trampa, si est activado ejecuta una interrupcin INT 1h cada vez que
quiera ejecutarse otra instruccin.
Interruption. Es el flag de interrupcin, cuando est activado evita la
posibilidad de interrupciones en secciones crticas de cdigo,
Flag de rumbo direccin y sentido. Determina si se han de autoincrementar
autodecrementar los punteros SI y DI.
Overflow (o desbordamiento). Es bastante parecido al de acarreo pero acta
con nmeros en complemento a dos, y se activa cuando se pasa del mayor
nmero positivo (127 en un solo byte), al menor negativo (-128 en un solo
byte). Este flag, al contrario que el de acarreo, s es afectado por las
instrucciones de incremento y decremento.
No utilizado.
No utilizado.
No utilizado.
No utilizado.

Intrucciones de comparacin, CMP y TEST:


CMP compara dos registros, o un registro y una direccin de memoria. Tiene el mismo formato que el SUB
(por ejemplo CMP AX,BX), tan solo que ninguno de los registros es alterado. Si por ejemplo son iguales, el
flag de cero Z se pondr en 1. Funciona como un SUB del que no se almacena el resultado.
TEST realiza una comprobacin, trabaja igual que AND, pero no guarda el resultado en ningn lado, aunque
s se modifican los flags.
Saltos condicionales:
Los saltos condicionales dependen exclusivamente de los Flags, son condicionados al estado 1 0 del Flag
que verifican, y son los siguientes:
(Aclaracin: todos los saltos se preceden de la comparacin que desea verificar una condicin, dichas
comparaciones se expresan comparando al primer miembro con el segundo)
JO:
JNO:
JC:
JNAE:

Jump if Overflow. Salta si el flag de desbordamiento est en 1.


Jump if Not Overflow. Salta si el flag de desbordamiento esta en 0.
Jump if Carry. Salta si el flag de acarreo es 1.
Jump if Not Above or Equal. Salta si no es mayor o igual.

Arquitectura de las Computadoras II

Pgina 6 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

JB:
JNC:
JAE:
JNB:
JZ:
JE:
JNZ:
JNE:
JBE:
JNA:
JA:
JNBE:
JS:
JNS:
JP:
JPE:
JNP:
JPO:
JL:
JNGE:
JGE:
JNL:
JLE:
JNG:
JG:
JNLE:

Jump if Below. Salta si es menor.


Jump if Not Carry. Salta si el flag de acarreo es 0.
Jump if Above or Equal. Salta si es mayor o igual.
Jump if Not Below. Salta si no es menor.
Jump if Zero. Salta si el flag de cero Z es 1.
Jump if Equal. Salta si dos instrucciones comparadas son iguales (CMP 0,0)
Jump if Not Zero. Salta si el flag de cero Z es 0.
Jump if Not Equal. Salta si dos instrucciones comparadas son distintas (CMP 3,4)
Jump if Below or Equal. Salta si es menor o igual.
Jump if Not Above. Salta si no es mayor.
Jump if Above. Salta si es mayor.
Jump if Not Below or Equal. Salta si no es menor o igual.
Jump if Sign. Salta si el flag de signo S es 1.
Jump if Not Sign. Salta si el flag de signo S es 0.
Jump if Parity. Salta si el flag de paridad P es 1.
Jump if Parity Even. Idem anterior.
Jump if Not Parity. Salta si el flag de paridad P es 0.
Jump if Parity Odd. Idem anterior.
Jump if Less. Salta si es menor. (para nmeros con signo)
Jump if Not Greater or Equal. Salta si no es mayor o igual. (para nmeros con signo)
Jump if Greater or Equal. Salta si es mayor o igual. (para nmeros con signo)
Jump if Not Less. Salta si no es menor. (para nmeros con signo)
Jump if Lower or Equal. Salta si es menor o igual. (para nmeros con signo)
Jump if Not Greater. Salta si no es mayor. (para nmeros con signo)
Jump if Greater. Salta si es mayor. (para nmeros con signo)
Jump if Not Lower or Equal. Salta si no es menor o igual. (para nmeros con signo)

Veamos algunos ejemplos de los ms utilizados:


MOV AX,1111
;Cargo 0x1111 en AX
MOV BX,1112
;Cargo 0x1112 en BX
CMP AX,BX
;Comparo AX con BX (en este caso AX es menor que BX)
JB AVANZA
;Saltar a AVANZA (si AX<BX)
AVANZA: DEC BX
;Ahora BX vale 0x1111
CMP AX,BX
;Comparo AX con BX (ahora valen lo mismo)
JNE FIN
;Saltar a FIN (si AX!=BX, como son iguales no salta)
JE CONT
;Saltar a CONT (si AX=BX, como son iguales salta)
CONT: DEC BX
;Ahora BX vale 0x1110
CMP AX,BX
;Comparo AX con BX (ahora AX es mayor que BX)
JE FIN
;Saltar a FIN (si AX=BX, como no son iguales no salta)
JB FIN
;Saltar a FIN (si AX<BX, como no es menor, no salta)
JG FIN
;Saltar a FIN (si AX>BX, Es mayor, ahora si salta)
FIN: SUB AX,AX
;Pone en cero AX
XOR BX,BX
;Hace XOR de BX con BX (otra manera de poner en cero)
La Pila:
La pila es una especie de "almacn de variables" que se encuentra en una direccin determinada de
memoria (direccin que viene indicada por SS:SP).
Entonces nos encontramos con dos rdenes bsicas respecto al manejo de la pila, que son PUSH y POP.
La orden PUSH empuja una variable a la pila, y la orden POP la saca.
Sin embargo, no podemos sacar el que queramos, debemos cuidar el orden natural de la estructura de una
pila. Esta se denomina LIFO (siglas en ingls que indican Last In First Out). Esto significa que al hacer un
POP, se saca el ltimo valor introducido en la pila.
Veamos un par de ejemplos:
PUSH DX
;Mete en la pila el contenido de DX.
PUSH CX
;Mete en la pila el contenido de CX.
POP AX
;Saca de la pila su ltimo valor (CX), y lo coloca en AX
POP BP
;Saca de la pila su ltimo valor (DX), y se lo asigna a BP.
MOV DX,300

;Cargo en DX el nmero 0x0300.

Arquitectura de las Computadoras II

Pgina 7 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

PUSH DX
;Empuja DX a la pila (0x0300).
MOV CX,200 ;Cargo en CX el nmero 0x0200.
PUSH CX
;Meto en la pila el contenido de CX (0x0200).
POP AX
;Saco de la pila el nmero 0x0200 y lo cargo en AX.
POP BX
;Saco de la pila el nmero 0x0300 y lo cargo en BX.
ADD AX,BX ;Sumo BX en AX. AX vale 0x0500.
La pila se puede operar con los registros AX, BX, CX, DX, SI, DI, BP, SP, CS, DS y ES, sin embargo no se
puede hacer un POP CS, solamente empujarlo a la pila.
Como ltima recomendacin, hay que tener bastante cuidado con los PUSH y POP, sacar tantos valores de
la pila como se metan, y estar pendiente de que lo que se saca es lo que se tiene que sacar. La pila bien
aprovechada es fundamental para hacer programas bien optimizados.
Y finalmente, hay otras dos rdenes interesantes respecto a la pila, PUSHF y POPF, que empujan el registro
de estado de 16 bits (flags) a la pila, y lo saca respectivamente.
Llamados a subrutinas, CALL:
Se trata de una orden que se utiliza para llamar a subrutinas, y est relacionada con el uso de la pila,
La sintxis del CALL es casi la de un JMP, pudindose tambin utilizar etiquetas, direcciones inmediatas o
registros.
Su forma de trabajo es sencilla. Empuja a la pila los valores de CS e IP (o sea, los del punto en el que estn
en ese momento del programa) aunque IP aumentado en el tamao del call para apuntar a la siguiente
instruccin, y hace un salto a la direccin indicada. Cuando encuentre una instruccin RET, sacar CS e IP
de la pila, y as retornar al lugar de origen. Veamos un ejemplo:
SUB AX,AX
;Ax vale ahora 0
CALL CHAU
;Mete CS e IP a la pila y salta a CHAU
INT 20
;Finaliza
CHAU: MOV AX,30 ;Carga un nmero en AX
RET
;Saca a CS e IP de la pila y vuelve a la instruccin
;siguiente al punto de llamada, o sea, a "INT 20"
Ejercicios (2):
Luego de la introduccin de todos estos conceptos, vamos a hacer unos ejercicios.
1) Realice un programa que calcule al producto de dos nmeros, como una suma. M*N=(M+M+M+......M) (N
veces). (M est en 3000, N en 2000, y el resultado guardarlo en AX)
2) Dada una lista de nmeros de un byte que empieza en la direccin 2000, y su longitud total esta
guardada en la direccin 1500, encuentre el nmero mayor de toda la lista y gurdelo en la direccin 3000.
3) Se tiene una lista de nmeros que comienzan en la direccin 2000, y su longitud est en 1500. Contar
cuantos nmeros negativos y positivos hay y separarlos en dos listas que empiecen en 3000 y 4000
respectivamente. El total de negativos guardarlo en 1600, y el de positivos en 1700.
4) Se tiene una lista de nmeros enteros de un byte cada uno que empieza en la direccin 2000, y su
longitud est en 1500. Pasar los nmeros a otra lista donde cada nmero ocupe 16 bits, de modo que a los
nmeros con bit de signo 0 se le agreguen 8 ceros a la izquierda, y a los nmeros con bit de signo 1 se le
agreguen 8 unos a la izquierda.
5) Realice el clculo del determinante de una matriz de 2x2.
6) Realice el clculo del determinante de un matriz NxN. Ayuda: Intente comparar los pasos que va
realizando, con los hechos en otro lenguaje de ms alto nivel (tipo C, C++)
Respuestas de los ejercicios
Ejercicios seccin (1):
1)
1) Cargo en AX el valor 0x10 en modo inmediato.
2) Cargo en BX el valor que est almacenado en la direccin de memoria 0x0100 en modo directo.
3) Sumo a CX el valor que est en la direccin de memoria 0x0010, ya que por el 1er. paso AX tiene el dato
0x10. Este modo se denomina indirecto por registro.
4) Sumo 2 a BX.
5) Resto uno a CX.
2)
MOV AX,[5000]
;Cargo en AX el dato B que est en 5000 y 5001 de memoria
Arquitectura de las Computadoras II

Pgina 8 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

ADD AX,[5000]
SUB AX,[5006]
MOV [5010],AX
3)
MOV AX,[5000]
ADD AX,[5006]
MOV CX,[5000]
IMUL CX
MOV CX,[5006]
IDIV CX
MOV [5010],AX
MOV [2000],DX

;Sumo en AX el dato B que est en 5000 y 5001 de memoria


;Resto a AX el dato C que est en 5006 y 5007 de memoria
;Cargo en 5010 y 5011 de memoria, el contenido de AX

;Cargo en AX el dato B que est en 5000 y 5001 de memoria


;Sumo a AX el dato C que est en 5006 y 5007 de memoria
;Cargo en CX el dato B
;Hace la operacin CX*AX y guarda el resultado en (DX,AX)
;Cargo en CX el dato C que est en 5006 y 5007 de memoria
;Realizo la divisin (DX,AX)/CX
;Llevo a la direccin 5010 el resultado que est en AX
;Llevo a la direccin 2000 el resto de la divisin que
;est en DX.

Ejercicios de la seccin (2):


1)
MOV CX,[2000]
;Llevo a CX el valor de N
MOV BX,[3000]
;Llevo a BX el valor de M
SUB AX,AX
;Pongo en cero a AX
RUTINA: ADD AX,BX ;Sumo M a AX
DEC CX ;Resto uno a CX (cuando CX sea 0, Z=1)
JNZ RUTINA
;Si luego de la instruccin anterior Z=0, saltar a
;RUTINA
INT 20
;Fin
2)
MOV CL,[1500]
;Cargo en CL la longitud de la lista
MOV SI,2000
;Apunto SI al comienzo de la lista de datos
MOV AL,[SI]
;Llevo el primer elemento de la lista a AL
INC SI
;Incremento el puntero para buscar el segundo dato
DEC CL
;Decremento el contador de elementos de la lista
VOLVER: CMP AL,[SI] ;Comparo al nmero que est en AL con el que est
;siendo apuntado por SI
JA RUTINA ;Si AL>[SI] ir a RUTINA
MOV AL,[SI] ;Carga en AL el nuevo nmero que apunta SI
RUTINA: INC SI
;Incrementa SI para buscar el prximo elemento
DEC CL
;Decrementa el contador de elementos de la lista
JNZ VOLVER ;Mientras Z=0, volver a VOLVER
MOV [3000],AL ;Guarda en 3000 el resultado (el nmero mayor)
INT 20
;Finaliza
3)
MOV CL,[1500]
;Cargo la longitud de la lista en el contador
MOV SI,2000
;El registro SI apunta al comienzo de la lista
MOV DI,3000
;DI apunta al comienzo de la lista que guardar
;los negativos
MOV BX,4000
;BX apunta al comienzo de la lista que guardar
;los positivos
SUB DX,DX
;Llevo DX a cero
SUB_1: MOV AX,[SI] ;Cargo en AX el primer dato apuntado por SI
CMP AX,0
;Comparo este dato con el 0
JL SUB_2
;Si AX<0, saltar a SUB_2
JG SUB_3
;Si AX>0, saltar a SUB_3
Arquitectura de las Computadoras II

Pgina 9 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

SUB_4: ADD SI,2


;Suma 2 bytes a SI para buscar el prximo elemento
DEC CL
;Decrementa el contador
JNZ SUB_1
;Si Z=0, volver a SUB_1
MOV [1600],DL
;Guarda el negativo en 1600
MOV [1700],DH
;Guarda el positivo en 1700
INT 20
;Fin
SUB_2: INC DL
;Incrementa a DL
MOV [DI],AX ;Guarda el negativo en la lista apuntada por DI
ADD DI,2
;Suma 2 bytes a DI
JMP SUB_4 ;Saltar a SUB_4
SUB_3: INC DH
;Incrementa a DH
MOV [BX],AX ;Guarda el positivo en la lista apuntada por BX
ADD BX,2
;Suma 2 bytes a BX
JMP SUB_4 ;Saltar a SUB_4
4)
MOV CL,[1500]
MOV SI,2000
MOV DI,3000

;Cargo en CX la longitud de la lista


;Apunto a SI al comienzo de los datos
;Apunto DI al comienzo de la lista resultados

CARGA: MOV AL,[SI] ;Carga en AL el primer elemento de la lista


CMP AL,0
;Compara AL contra 0
JGE SUB_1 ;Si AL>=0, saltar a SUB_1
JL SUB_2
;Si AL<0, saltar a SUB_2
REFRESH: INC SI
;Incremento SI para buscar el prximo elemento
ADD DI,2
;Sumo 2 a DI (los resultados ocupan 2 bytes)
DEC CL
;Decremento en uno el contador (CL=0 -> Z=1)
JNZ CARGA ;Si Z=0, saltar a CARGA
INT 20
;Fin

SUB_1: MOV AH,00 ;Carga 8 ceros en AH


MOV [DI],AX ;Carga el nmero resultante en la lista que
;apunta DI (nmero de 16 bits)
JMP REFRESH ;Saltar a REFRESH
SUB_2: MOV AH,FF ;Carga 8 unos en AH
MOV [DI],AX ;Carga el nmero resultante en la lista que
;apunta DI (nmero de 16 bits)
JMP REFRESH ;Saltar a REFRESH
5)
;NASM-IDE ASM Assistant Assembler Project File
BITS 16
;Set code generation to 16 bit mode
ORG 0x0100
;Set code start address to 0100h
SEGMENT .data
;Initialised data segment
matriz1 dw 1,2,3,4
;matriz inicializada con datos 1,2,3,4
inicioFila dw 0
;por donde comienzo a multiplicar
SEGMENT .bss
matriz2 resw 4
resul resw 1
contador resw 1

;Uninitialised data segment


;reservo espacio para la matriz resultado

Arquitectura de las Computadoras II

Pgina 10 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

SEGMENT .text

;Main code segment

mov si,matriz1
mov di,matriz2
call CALCULAR
mov word [inicioFila],4 ;siempre debo especificar el tipo cuando son cte
call CALCULAR
mov ax, $4C00
;Prepare to exit
int 20
;Terminate program
CALCULAR:
xor cx,cx

;inicializo contador

BUCLE:
mov [contador],cx
;guardo contador ya que voy a usar cx
mov bx,[inicioFila]
;por que fila examino la matriz1
mov cx,[si+bx]
;valor en la posicin examinada
mov bx,[contador]
;por que columna examino matriz1
mov ax,[si+bx]
;valor
imul cx
;multiplico
mov [resul],ax
;guardo resultado parcial
mov bx,[inicioFila]
;restauro bx
mov cx,[si+bx+2]
;por que fila examino la matriz1
mov bx,[contador]
;por que columna examino matriz1
mov ax,[si+bx+4]
;valor
imul cx
;multiplico
add [resul],ax
;obtengo resultado final Aij
mov bx,[inicioFila]
;fila
add bx,[contador]
;adiciono a fila, la columna
mov ax,[resul]
;coloco el resultado final en ax
mov [di+bx],ax
;guardo resultado en matriz2
mov cx,[contador]
;restauro valor contador
add word cx,2
;incremento en 1 word el contador (2 bytes)
cmp cx,6
;si contador != 6
jne BUCLE
;volver a BUCLE
ret
;si no, regresar
6) Antes de resolver este ejercicio, es bueno estudiar un poco el proceso de clculo en un lenguaje de
mayor nivel, ya que son muchos los llamados a subrutinas y va a resultar un poco engorroso entederlo
directamente. Este ejemplo esta realizado en C++.
int det(int *M,int N){
if(N==2){
return((M[0]*M[3])(M[1]*M[2]));
}
else{
int new_dimension=(N-1);
int tdet =0;
int *temp =new int[(N-1)*(N-1)];
for(int ref_ele=0;ref_ele<N;ref_ele++){
int counter=0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if((j!= ref_ele)&&(i!=0)){
temp[counter]=M[(N*i + j)];
counter++;
}
}
}
int t = det(temp, new_dimension);
if((ref_ele % 2)!= 0)
Arquitectura de las Computadoras II

Pgina 11 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

t =(-1)*t;
tdet += M[ref_ele]*t;
}
return tdet;
}
}
El algoritmo trabaja haciendo llamados recursivos de sub-clculos si N>2 hasta que sea N=2 para hacer el
clculo en forma directa de filas por columnas. Para cada matriz M(i,j), se necesita determinar la sub-matriz
que queda formada de no contener a la fila y columna del dato que queremos calcular
SEGMENT .bss
M resw 153
;Reservo espacio para las matrices temporales
;(25+(5*16)+(4*9)+(4*3))
N resw 1
;Reservo espacio para el N de la matriz
SEGMENT .text
MOV [N],3
;cargo el orden de la matriz en N (Ej. 3)
MOV SI,M
;inicio de la matriz
MOV AX,[N]
;cargo el N de la matriz en ax (3)
PUSH SI
;coloco en la pila a si
PUSH AX
;coloco en la pila a ax (N)
CALL det
;Llamo a det
ADD SP,4
;renuevo parametros de la pila
INT 20
;Fin
det:
PUSH BP
;guardo el estado del puntero base
MOV BP,SP
;apunto bp al tope de la pila
CMP [BP+4],2
;comparo si N=2
JNE else
;si no es igual, ir a else
MOV SI,[BP+6] ;si es igual, comienza el calculo empezando por apuntar
;a SI al comienzo de la matriz de 2x2 (elemento a00)
MOV AX,[SI]
;cargo en ax el primer elemento de la matriz (el a00)
MOV BX,[SI+6] ;cargo en bx el ultimo elemento de la matriz (el a11)
IMUL BX
;multiplico bx*ax (a00 * a11)
MOV CX,AX
;guardo el resultado de la primera multiplicacion en cx
MOV AX,[SI+2] ;cargo en ax el ultimo elemento de la fila 0 (el a01)
MOV BX,[SI+4] ;cargo en bx el primer elemento de la fila 1 (el a10)
IMUL BX
;multiplico bx*ax (a01 * a10)
SUB CX,AX
;resto el resultado de ambas multiplicaciones
MOV AX,CX
;devuelvo el resultado final en ax
MOV SP,BP
;restauro el tope de la pila con el valor anterior de
;la funcion
POP BP
;restauro el puntero base con el valor anterior de la
;funcion
RET
;Retorno
else:
SUB SP,16
;guardo espacio para 8 variables que voy a utilizar
MOV AX,[BP+4] ;guardo en ax el valor N de la matriz original
DEC AX
;decremento AX
MOV [BP-2],AX ;bp-2 es una nueva variable (newdim) que contiene la
;nueva dimension de la matriz (N-1)
MOV [BP-4],0
;bp-4 es una nueva variable =0 (dettemp) que usare como
;determinante temporal
MOV SI,[BP+6] ;apunto si al comienzo de la matriz (*M)
MOV AX,[BP+4] ;guardo el orden de la matriz
IMUL AX
;opero N * N (en este ejemplo = 9)
MOV BX,2
;cargo 2 en bx
Arquitectura de las Computadoras II

Pgina 12 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

IMUL BX

;multiplico ax*2 (=18, bytes que utilizare para


;reservar en memoria)
ADD SI,AX
;apunto si al comienzo de la nueva matriz temporal
;(+ 18 bytes)
MOV [BP-6],SI ;bp-6 es una nueva variable (*temp) que contiene la
;direccin de la nueva matriz temporal (o adjunta)
MOV [BP-8],0
;bp-8 es una nueva variable (que llamare ref_ele)
for1:
MOV CX,[BP+4] ;cargo N en cx
CMP [BP-8],CX ;comparo si ref_ele es < N
JNL endfor1
;Saltar si [BP-8] no es menor que CX
MOV [BP-10],0 ;bp-10 es una nueva variable =0 (contador)
MOV [BP-12],0 ;bp-12 es una nueva variable =0 (i)
for2:
CMP [BP-12],CX ;comparo a i con N
JNL endfor2
;saltar si [BP-12] no es menor que CX
MOV [BP-14],0 ;bp-14 es una nueva variable =0 (j)
for3:
CMP [BP-14],CX ;comparo a j con N
JNL endfor3
;saltar si [BP-14] no es menor que CX
MOV AX,[BP-14] ;en ax cargue j
if1:
CMP AX,[BP-8] ;comparo si j es != ref_ele
JE endif1
;Saltar si AX=[BP-8]
CMP [BP-12),0 ;comparo si i!=0
JE endif1
;saltar si [BP-12]=0
MOV AX,[BP-12] ;cargo i en ax
IMUL CX
;N*i
ADD AX,[BP-14] ; N * i + j (formula para recorrer matrices)
MOV BX,2
;cargo 2 en BX
IMUL BX
;multiplico a ax por 2 ya que recorro la matriz de a 2
;bytes
MOV BX,AX
;guardo el desplazamiento de N*i+j en bx
MOV SI,[BP+6] ;apunto si a M (primer elemento)
MOV DX,[SI+BX] ;coloco en dx M[(N*i+j)]
MOV BX,[BP-10] ;coloco en bx a contador
MOV SI,[BP-6] ;apunto si a la matriz temporal
MOV [SI+BX],DX ;temp[contador]=M[(N*i+j)]
ADD [BP-10],2 ;actualizo a contador (+2 bytes)
endif1:
ADD [BP-14],2
JMP for3

;j++

endfor3:
ADD [BP-12],2
JMP for2

;i++

endfor2:
MOV BX,[BP-6] ;inicio de matriz
MOV AX,[BP-2] ;orden matriz
PUSH BX
;coloco este parametro en pila
PUSH AX
;coloco este parametro en pila
CALL det
;Llamo a det
ADD SP,4
;renuevo la pila con los parametros anteriores
MOV [BP-16],AX ;devuelvo el resultado de la funcion en ax
Arquitectura de las Computadoras II

Pgina 13 de 14

Assembly Language for PC (Intel) Conceptos bsicos y prctica

if2:
MOV AX,[BP-8] ;ax=ref_ele
MOV BX,2
;cargo 2 en bx
IDIV BX
;relizo divisin
CMP DX,0
;(ref_ele%2)!=0
JE endif2
;saltar si DX=0
MOV AX,[BP-16] ;ax=t
MOV BX,-1
;cargar 1 en BX
IMUL BX
;t=(-1)*t
endif2:
MOV BX,[BP-8] ;cargo a bx con ref_ele
MOV SI, [BP+6] ;apunto a M
MOV AX,[SI+BX] ;M[ref_ele]
IMUL [BP-16]
;M[ref_ele]*3
ADD [BP-4],AX ;tdet+=M[ref_ele]*3
ADD [BP-6],2
;incremento a ref_ele (2 bytes)
JMP for1
endfor1:
MOV AX,[BP-4] ;en ax devuelvo el det
MOV SP,BP
;restauro la cima de la pila
POP BP
;restauro el puntero base
RET
Bibliografa:
Este trabajo se realiz con muy poca bibliografa. Se bas principalmente en las clases y consultas a
profesores, papers correspondientes a la arquitectura de los procesadores Intel, y prcticas desarrolladas a
modo de prueba y error en PC.
Los nicos libros consultados son:
Organizacin y Arquitectura de Computadores William Stallings (4ta. Edicin).
Principios de la Arquitectura de Computadoras Miles Murdocca & Vincent Heuring (1999).
Agradecimientos:
A todos los docentes que me ayudaron para poder recopilar toda la informacin aqu contenida.
Intel Corporation, que me facilit los papers de los procesadores que ya no fabrica hace muchos
aos.
AT&T, que tamben me facilit algunos papers sobre el funcionamiento de algunos algoritmos que
aqu se utilizan.
Diego Bellini
Rosario Repblica Argentina
djmakana@datafull.com
Simplemente espero que les sea de mucha utilidad.

Arquitectura de las Computadoras II

Pgina 14 de 14

You might also like