Está en la página 1de 9

2.6 CICLOS CONDICIONALES.

En general es posible anidar tantos ciclos como sean necesarios. Esto es muy
semejante a lo que ocurra cuando definamos una instrucción que usaba otra
instrucción definida antes.

Un ciclo, conocido también como iteración, es la repetición de un proceso un cierto


número de veces hasta que alguna condición se cumpla. En estos ciclos se utilizan los
brincos "condicionales" basados en el estado de las banderas.

LOOP: Tiene un tamaño de 8 bits abarca de 00 hasta FF y tiene signo .

Ejecutar un BUCLE consiste en repetir “n” veces una serie de instrucciones de una
sección del programa.

Esta instrucción, en el momento que se ejecuta, realiza los siguientes pasos:


1°Decrementa a CX en un uno.(CX=CX-1)

2°Checa el valor de CX, y


-SI CX es diferente de cero, realiza el salto correspondiente de acuerdo al valor del
desplazamiento.
-Si CX es igual a cero, continua con la siguiente instrucción debajo de ella.
2.7 INCREMENTO Y DECREMENTO.

Instrucciones de conteo, se utilizan para decrementar o incrementar el contenido de los


contadores.

INC: Consiste en sumar uno al contenido de un registro que se especifica en la


instrucción.

Su esquema es: R ← R+1


Donde "R" representa un registro cualquiera de 8 a 16 bits. Si se trata de un registro
doble (de 16 bits) se incrementa el registro de orden bajo (por ejemplo, en el "BC" se
incrementa "C"), y si ello hace que este pase a valer "0", se incrementa también el de
orden alto.

Propósito: Incrementar el operando.

Sintaxis: INC destino

La instrucción suma 1 al operando destino y guarda el resultado en el mismo operando


destino.

DEC: Es la inversa de la anterior, consiste en restar uno al contenido de un registro.

Su esquema es: R ← R-1

Si se trata de un registro doble, se decrementa el de orden bajo y, si esto hace que


pase a valer 255 (FFh), se decrementa también el de orden alto.

Propósito: Decrementar el operando

Sintaxis: DEC destino

Esta operación resta 1 al operando destino y almacena el nuevo valor en el mismo


operando.
2.9 INSTRUCCIONES ARITMÉTICAS.

Este tipo de instrucciones realizan operaciones aritméticas con los operandos. Y


son: ADD, ADC, DAA, AAA, SUB, SBB, DAS, AAS, NEG, MUL, IMUL, AAM, DIV, IDIV,
AAD, CBW, CWB, INC, DEC.

ADD y ADC realizan la suma y la suma con acarreo (bit CF del registro de estado) de
dos operandos, respectivamente, y guardan el resultado en el primero de ellos.
Admiten todos los tipos de direccionamiento (excepto que ambos operando estén en
memoria).

ADD/ADC reg, reg


ADD/ADC mem, reg
ADD/ADC reg, mem
ADD/ADC reg, inmediato
ADD/ADC mem, inmediato
Ejemplo:

; J = 34+f
MOV AX, F
ADD AX, 34
MOV J, AX
SUB y SBB realizan la resta y la resta con acarreo, respectivamente, de dos operandos
y guardan el resultado en el primero de ellos. Admiten todos los modos de
direccionamiento, excepto dos operando en memoria.

SUB/SBB reg, reg


SUB/SBB mem, reg
SUB/SBB reg, mem
SUB/SBB reg, inmediato
SUB/SBB mem, inmediato
Ejemplo:

; J = F-34
MOV AX, F
SUB AX, 34
MOV J, AX
Estas instrucciones afectan a los bits OF, SF, ZF, AF, PF, CF del registro de estado.
DAS realizan la corrección BCD empaquetado del resultado de una resta en AL. Actúan
de manera similar a la instrucción de ajuste de la suma.
NEG realiza la operación aritmética de negado de un operando y guarda el
resultado en el mismo operando. Admite todos los tipos de direccionamiento, excepto
inmediato.
NEG reg
NEG mem
La operación que realiza es: 0 – operando.
Estas instrucciones afectan a los bits OF, SF, ZF, AF, PF, CF del registro de estado.
DAA realizan la corrección BCD empaquetado del resultado de una suma en AL.

La mayoría de las computadoras son grandiosas para las matemáticas, esto viene a
sorprender que el lenguaje ensamblador solo tiene unos operadores matemáticos
relativamente primitivos. No hay símbolos de exponenciación, no hay punto flotante, no
hay raíz cuadradas, y no existen funciones SENO y COSENO dentro del grupo de
instrucciones del 8086. Las instrucciones Matemáticas en lenguaje ensamblador están
restringidas a sumar, multiplicar, dividir y restar valores enteros con signo o sin signo.
Instrucciones Generales

Mnemónico/Operando Descripción

Instrucciones de Adición

aaa Ajuste ASCII para adición

adc destino, fuente Suma con acarreo

add destino, fuente Suma bytes o palabras

daa Ajuste decimal para adición

inc destino Incremento

Instrucciones de Substracción

aas Ajuste ASCII para substracción

cmp destino, fuente Compara

das Ajuste decimal para substracción

dec destino Decrementa byte o palabra

neg destino Negar (complemento a dos)

sbb destino, fuente Substrae

sub destino, fuente Substrae

Instrucciones de Multiplicación

aam Ajuste ASCII para multiplicación

imul fuente Multiplicación con enteros


mul fuente Multiplicar

Instrucciones de División

aad Ajuste ASCII para división

cbw Convierte bytes a palabras

cwd Convierte palabras a dobles palabras

div fuente Divide

idiv fuente División de Enteros

Existen dos formas de incrementar el poder matemático del lenguaje ensamblador.


Primero, se puede comprar) o escribir) un paquete de funciones matemáticas con
rutinas que implementan las funciones matemáticas de alto nivel que se necesitan. Otra
solución es comprar un chip coprocesador matemático, aunque esto puede ser muy
caro. Como una tercera opción, y probablemente la mejor, es utilizar un lenguaje de
alto nivel como Pascal o C para codificar las expresiones de punto flotante. Estos
lenguajes vienen con un detector automático de presencia de coprocesador
matemático o cambiar a un software emulador para sistemas que carezcan del chip
opcional. Después de escribir el programa, se puede combinar el código compilado de
alto nivel, con nuestro programa en lenguaje ensamblador. Ya que el coprocesador
matemático tiene requerimientos estrictos acerca de los datos y formatos de
instrucciones, la mayoría de los compiladores generan código máquina optimizado, y
hay poca ventaja en escribir expresiones de punto flotante directamente en lenguaje
ensamblador.

Pero no tome esto como una pronunciada negativa en matemáticas del lenguaje
ensamblador. Aún sin una librería matemática o coprocesador, se pueden utilizar
plenamente instrucciones de enteros.
2.10 MANIPULACIÓN DE LA PILA.

Uso del Stack


El Stack es un segmento especial de memoria que opera en conjunción con varias
instrucciones del 8086. Como con todos los segmentos, la localización del stack y su
tamaño (hasta 64K) dependen del programador determinarlo. En los programas de
lenguaje ensamblador, la forma más fácil de crear un stack es usar la directiva STACK.
Un stack tiene tres propósitos principales:

 Preservar valores de los registros temporalmente.


 Almacenar direcciones a las cuales las rutinas regresaran.
 Almacenar variables dinámicas.

El último de éstos viene a jugar más frecuentemente en los lenguajes de


programación de alto nivel, donde las variables son pasadas vía stack hacia y desde,
funciones y procedimientos. Similarmente, variables temporales pueden se
almacenadas en el stack. Estos usos son raros en la programación pura en lenguaje
ensamblador, aunque se puede almacenar variables de memoria de ésta manera si se
desea.

Como opera el Stack


Conceptualmente, un stack es como una torre de platos en una cocina de un
restaurante. El plato de encima de la pila está fácilmente disponible. Pero para tomar
los platos de abajo, otros platos de encima primeramente deben ser removidos.
Colocar un nuevo plato en la pila es llamado push, Remover un plato de la parte
superior de la pila, es llamado pop. Ya que de la manera en que el último plato
colocado en el stack es el primer plato disponible a ser removido, éste tipo de stack es
llamado stack LIFO o UEPS, por "Last-In-First-Out".

No como los platos, los valores en la computadora no pueden moverse físicamente


hacia arriba y hacia abajo. Por lo tanto, para simular la acción de un movimiento de los
valores del stack, requiere de utilizar registros para localizar la dirección base del Stack
y la dirección OFFSET del plato superior - que es, la localidad donde el valor superior
de la pila es almacenado. En programación 8086, el registro segmento ss direcciona al
segmento de stack base. El registro sp direcciona el desplazamiento OFFSET tope del
Stack en dicho segmento.

La siguiente figura Ilustra como aparece un stack de 12 bytes en memoria. EL registro


ss direcciona la base del stack en el segmento direccionado en 0F00. El registro sp
direcciona el desplazamiento (OFFSET) desde esta dirección inicial, en un rango desde
0000 hasta 000A. El ultimo byte del stack esta en desplazamiento 000B. Los elementos
en el stack ocupan palabras de 2 Bytes. El programa que prepara éste stack puede
declarar STACK 12 y dejar que el ensamblador, enlazador, y DOS calculen
exactamente donde estará almacenado el Stack en memoria. No hay que inicializar ss
y sp. DOS lo realiza por nosotros cuando carga el programa para ejecutarlo. En la
figura, sp1 muestra donde apunta sp cuando el programa comienza a correr. Nótese
que la dirección lógica en ss:sp apunta al byte por debajo del ultimo byte en el stack.

Memoria Baja
0000
0002 0F00:
0004
0006
0008 200
000A 100 ss:sp3
000C ss:sp2
ss:sp1

Fin del segmento Stack


En referencia a la figura anterior. Varias acciones ocurren si se ejecutan las siguientes
instrucciones:

mov ax,100
push ax ; sp2
mov bx, 200
push bx ; sp3

La instrucción push realiza dos pasos:


1. Substrae 2 de sp
2. El valor del registro especificado es copiado a [ss:sp].

El orden de estos pasos es importante. Un push primero substrae 2 (no 1) de sp. La


primer colocación push, deja a sp en sp2, donde el valor del registro ax es
almacenado. Nótese que esta acción deja al puntero del stack direccionado al valor
palabra recientemente colocado- pushed- en el stack.

Manipulación del Stack


El punto principal de la manipulación del stack es simple: Para cada push en un
programa, debe haber su correspondiente pop. Igualando pops y pushes mantiene el
stack en forma correcta- en otras palabras, en sincronización con la habilidad del
programa para almacenar y recuperar el valor que necesita.

Considere lo que sucede si se falla en ejecutar un correspondiente pop para cada


push. En éste caso, pushes futuros causarán que el stack crezca mas y más largo,
eventualmente rebasando el espacio segmento permitido para el programa. Este grave
error normalmente termina en un crash sobre escribiendo otras áreas de memoria por
el puntero del stack. Un error similar ocurre si se ejecutan más pops que pushes,
causando un bajoflujo y también resultar en un crash.
Una forma de prevenir éstos problemas es escribir los programas en pequeños
módulos, o subrutinas. En cada módulo, realizar un push con todos los registros que
se utilizarán. Entonces, justo antes de que ésta sección de código termine, realizar un
pop a los mismos registros retirándolos pero en orden inverso.

push ax
push bx
push cx
; ------ Programa objetivo
pop cx
pop bx
pop ax
En éste ejemplo, los registros ax, bx y cx, son posiblemente utilizados; por lo
tanto, éstos registros son almacenados en el stack para preservar los valores de los
registros. Por último, los valores son retirados (pop) del stack en orden inverso,
restaurando los valores originales de los registros y manteniendo el stack en sincronía.

PUSH y POP realizan las operaciones de apilado y desapilado en la pila del


procesador respectivamente, admiten todos los tipos de direccionamiento (excepto
inmediato). Los operandos deben ser siempre de 16 bits.

PUSH reg
PUSH mem
PUSH seg-reg
POP reg
POP mem
POP seg-reg
Ejemplos:
PUSH AX ;envía a la pila AX
POP DS ;carga el primer elemento de la pila en DS
BIBLIOGRAFÍA:

http://jsanchezvalles.blogspot.mx/2010/04/instrucciones-de-lenguaje-ensamblador.html

http://expo.itch.edu.mx/view.php?f=asm_25

http://www.iuma.ulpgc.es/~armas/asignaturas/calculadoras/contenido/slides_introsoft.p
df

http://www.itescam.edu.mx/principal/webalumnos/sylabus/asignatura.php?clave_asig=S
CC-1014&carrera=ISIC-2010-224&id_d=170

http://www.youtube.com/watch?v=j1HpGAOOfbo

http://danimtzc.blogspot.mx/2012/03/saltos-ciclos-operadores-logicos-y-mas.html