domingo, 10 de marzo de 2019

Saltos condicionales y ciclos condicionales

Programas con saltos condicionales

JMP – Salto incondicional. No depende de ninguna bandera del registro de banderas para
llevarse a cabo, puede ser de tres tipos:
- corto
- cercano
- lejano
El salto corto ocupa 2 bytes así lo que permite transferir el programa a localidades entre +127 y –
128 bytes desde la localidad donde esta la instrucción.
El salto lejano es una instrucción de 3 bytes así que permite cambiar el flujo hasta de -/+32
Kbytes desde donde se localiza la instrucción.
El salto lejano es una instrucción de 5 bytes permitiendo brincar a cualquier localidad de
memoria dentro de la maquina. En μP 386 y 486 el brinco corto esta entre +/- 2 Gbytes si se
trabaja en el modo protegido y de 4 Gbytes si es lejano.

Saltos condicionales

Las instrucciones de salto condicional prueban las banderas de signo cero o acarreo
o paridad o sobreflujo y si la condición es verdadera se ejecuta la transferencia.

Ejemplos:

En este primer ejemplo establecemos dos valores: 25 y 10 para ser comparados, utilizando el salto condicional "je" que salta si se cumple la condición de que los valores sean iguales .




En este ejemplo se muestra el uso de tres tipos de saltos el "je" que condiciona si los valores son iguales, jc que evalúa los bit d estados, si cf=0, entonces sera mayor el  segundo valor, y para cuando zf=1, sera mayor el primer valor y usamos el salto "jnz".



En este ejemplo se hace una suma, colocamos un valor en ax y bx en este caso sera 3 y 4, salta al procedimiento de cal y ahí hace la suma


Aquí podemos observar como se coloca el 3 en ax y el 4 en cx
Se hace la suma y se coloca el resultado en ax.



Bucles

Las instrucciones de bucle se usan para realizar estructuras repetitivas, y utilizan el registro CX
como contador.
LOOP – Es realmente un decremento de cx y un brinco condicionado, esta instrucción decrementa cx y si este no es igual a cero brinca a la dirección especificada.

LOOPE – Es un loop condicional (similar al “rep”) “repite mientras sea igual”, el ciclo se
mantiene mientras la condición sea igual o cx no sea cero y sale del ciclo si la condición no es
igual o cx es cero.

LOOPNE – Similar al anterior pero ahora el salto se da si la condición no es igual o cx ≠ 0 y si ZF=0.

Ejemplo  usando LOOPNE

En este ejemplo damos un valor a cx de 9, este se ira decrementando cada vez que se repita el ciclo de imprimir el mensaje "letrero"


Ejemplo con LOOP

E un ejemplo parecido al anterior, pero esta vez, el ciclo se repetirá 50 veces


Ejemplo usando jcxz

En este ejemplo se muestra el uso de jcxz el cual hace el salto siempre que cx sea igual a cero, de no ser si el ciclo no se realiza.
como se muestra en la imagen cx tiene un valor de 10 entonces el ciclo solo ocurrirá una vez y se saldrá porque cx no es igual 0.



Comparación de dos cadenas

En este ejemplo tenemos dos cadena a comparar: "tecnologico" y la subcadena "tecno"
si "tecno" es parte de de la cadena entonces se imprimira el mensaje de "Si se encuentra" pero si la subcadena llega a tener algún cambio por ejemplo si ponemos "teno", entonces se mostrara un mensaje de "no se encuentra".

Codigo

org 100h
include 'emu8086.inc'
mov si, 0    ;ponemos si en 0
 
 
comienzo:
mov al, msg2[0]   ;copiar la primera letra de la palabra A al

cmp msg[si],"$"   ;si es el fin de la cadena mandar a final
 jz final      ; brinca si es igual

cmp msg[si], al   ;comparar si encuentra la primera letra de la cadena
 jne seguir    ;brica si es diferente


mov di, 1         ;poner en 1 di

comprobar:

 mov al, msg2[di]
 mov bx, di
 cmp msg[si+bx], al     ;posicion de la letra coincidente + di, comparar con la cadena
 jne seguir             ;si no coincide mandar a seguir


 inc di                 ;incrementar di para seguir recorriendo cadena

 cmp msg2[di],"$"       ;si es el fin de la cadena y el programa llego
 jz resultado           ;aca quiere decir que la cadena es parte de la palabra


loop comprobar         ;bucle para recorrer cadena
                                                 
                                                 
seguir:
 
 mov di,1
 inc si       ;para seguir recorriendo la palabra

loop comienzo   ;bucle principal para recorrer palabra

resultado:

  mov dx, offset msg3    ;copiar msg3 a dx
  mov ah, 9              ;preparar ah con 9 para la interrupcion 21h
  int 21h                ;mostrar contenido en dx
  jmp termina
 
final: 
lea dx,msg4
mov ah,9
int 21h

termina:
ret 

msg db "tecnologico$"
msg2 db "tecno$"
msg4 db "No se encuentra$"
msg3 db "Si se encuentra$"




Uso de LOOPZ

En esta instrucción la condición adicional es ZF = 1.

Este programa lee un carácter ingresado, y si el carácter  es igual a "S" entonces nos volverá a pedir que ingresemos un  carácter, si este nuevo carácter sigue siendo igual a "S" entonces se repite el ciclo así 10 veces ya que es el valor de cx.
Si se ingresa algún carácter diferente, entonces el ciclo termina.
org 100h
.stack 64
.data
.code
inicio:
mov cx,10 ;cantidad de veces que repetira
mov al,'>' ;caracter inicial

Lee_car:
    mov ah,0eh ;Funcion para imprimir caracter
    int 10h   ;llama a al bios
   
    mov ah,00 ;funcion de espera de un caracter del teclado
    int 16h ;llama al bios
    cmp al,'S' ;compara el caracter con 'S'
    loope Lee_car  ;si es igual salta a otro
   
    mov ah,0eh ;funcion para imprimir caracter
    int 10h ;llamada al bios
   
    ;colocar el fin de la linea para que baje una linea y lo imprima
    mov ah,0eh ;funcion del bios para imprimir caracter
    mov al,10
    int 10h
   
    ;colocar el retorno de carro para ir al inicio
    mov al,13
    int 10h
    ;prepara la salida del programa
    mov ax,4c00h
    int 21h
end inicio

El programa termina por el caracter diferente a "S"

El carácter es aceptado, el ciclo sigue y ZF esta en 1.



PROGRAMA QUE MULTIPLICA DOS NÚMEROS


Código

.model small ;Modelo de memoria mas utilizado
.stack

.data        ;definicion de datos(variables), donde se almacenara informacion
.code
   chr1  db ? ;primer digito
   chr2  db ? ;segundo digito
   chr3  db ? ;multiplo
   chr4  db ?
   r1    db ? ;resultado 1
   r2    db ? ;resultado 2
   r3    db ?
   r4    db ?
   ac    db 0 ;acarreo
   ac1   db 0 
 
.startup
   ;cls
   mov ah,00h     ;Function(Set video mode)
   mov al,03      ;Mode 80x25 8x8 16
   int 10h        ;Interruption Video

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;ajustamos valores
   mov chr1,al    ;[chr1].chr2 * chr3 = ac.r1.r2

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;Ajustamos valores
   mov chr2,al    ;chr1.[chr2] * chr3 = ac.r1.r2

   mov ah,02h     ;Function(character to send to standard output)
   mov dl,'*'     ;Character to show
   int 21h

   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr3,al    ;chr1.chr2 * [chr3] = ac.r1.r2

   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr4,al    ;chr1.chr2 * [chr3] = ac.r1.r2

   mov ah,02h     ;Character to send to standar output
   mov dl,'='     ;
   int 21h        ;Interruption DOS functions

   ;Realizamos operaci?n 

   mov al,chr4  ;unidad del segundo numero
   mov bl,chr2  ;unidad del primer numero
   mul bl       ;multiplicar
   mov ah,0     ;limpiamos ah0
   aam          ;separamos de hex a dec
   mov ac1,ah   ;decenas del primera multiplicacion
   mov r4,al    ;unidades del primera multiplicacion
         
   mov al,chr4  ;unidades del segundo numero
   mov bl,chr1  ;decentas del primer numero
   mul bl       ;multiplicar
   mov r3,al    ;movemos el resultado de la operacion a r3
   mov bl,ac1   ;movemos el acarreo a bl
   add r3,bl    ;sumamos resultado mas acarreo
   mov ah,00h   ;limpiamos ah por residuos
   mov al,r3    ;movemos el resultado de la suma a al
   aam          ;separamos  de hex a dec
   mov r3,al    ;guardamos unidades en r3
   mov ac1,ah   ;guardamos decenas en ac1

   

   mov al,chr3    ;al = chr3
   mov bl,chr2    ;bl = chr2
   mul bl         ;AL = chr3*chr2 (BL*AL)
   mov Ah,0h      ;
   AAM            ;ASCII Adjusment
   mov ac,AH      ;ac = AH (Acarreo)
   mov r2,AL      ;r2 = AL       (Unidad del resultado)

   mov al,chr3    ;AL = chr3
   mov bl,chr1    ;BL = chr1
   mul bl         ;AL = chr1*chr3 (BL*AL)
   mov r1,al      ;r1 = AL       (Decena del resultado)
   mov bl,ac      ;BL = Acarreo anterior
   add r1,bl      ;r1 = r1+ac (r1 + Acarreo)
   mov ah,00h     ;
   mov al,r1      ;AL = r1 (Asignaci?n para el ajust)
   AAM            ;ASCII Adjustment
   mov r1,al      ;r1 = AL
   mov ac,ah      ;ac = AH (Acarreo para la Centena del resultado)


   ;suma final
   ;R4 resulta ser las unidades de mul y no se toma en cuenta ya que se pasa entero


   mov ax,0000h   ;limpiamos ax

   mov al,r3      ;movemos el segundo resultado de la primera mult a al
   mov bl,r2      ;movemos primer resultado de la segunda mult a bl
   add al,bl      ;sumamos
   mov ah,00h     ;limpiamos ah
   aam            ;separamos hex a dec
   mov r3,al      ;r3 guarda las decenas del resultado final
   mov r2,ah      ;r2 se utiliza como nuevo acarreo

   mov ax,0000h   ;''''

   mov al,ac1     ;movemos el acarreo de la primera mult a al
   mov bl,r1      ;movemos segundo resultado de la segunda mult a bl
   add al,r2      ;sumamos el nuevo  acarreo de la suma anterior  a al
   add al,bl      ;sumamos al a bl
   mov ah,00h     ;limpiamos el registro ah
   aam            ;separamos de hex a dec
   mov r1,al      ;r1 guarda las centenas
   mov r2,ah      ;ah se sigue utilizando como acarreo

   mov al,r2      ;movemos el acarreo a al
   mov bl,ac      ;movemos ac a bl
   add al,bl      ;sumamos al a bl
   ;aam            ;separamos hex a dec
   mov ac,al      ;mov al a ac como nuestro acarreo final



   ;Mostramos resultado
   mov ah,02h
   mov dl,ac
   add dl,30h
   int 21h        ;Mostramos ac (millar)

   mov ah,02H
   mov dl,r1
   add dl,30h
   int 21h        ;Mostramos r1 (centena)

               

   mov ah,02H
   mov dl,r3
   add dl,30h
   int 21h        ;Mostramos r3 (decena)

   mov ah,02H
   mov dl,r4
   add dl,30h
   int 21h        ;unidad

.exit

end 



Programa de multiplicación de dos cifras usando la librería "emu8086.inc"

name "Multiplica dos numeros"
include "emu8086.inc"
org 100h

.model small ;Modelo de memoria mas utilizado
.stack

.data        ;definicion de datos(variables), donde se almacenara información
.code

   chr1  db ? ;primer digito
   chr2  db ? ;segundo digito
   chr3  db ? ;multiplo
   chr4  db ?
   r1    db ? ;resultado 1
   r2    db ? ;resultado 2
   r3    db ?
   r4    db ?
   ac    db 0 ;acarreo
   ac1   db 0
.startup
   ;cls
   mov ah,00h     ;Function(Set video mode)
   mov al,03      ;Mode 80x25
   int 10h        ;Interruption Video
;lea SI, msg1
;CALL   print_string 
printn 'Ingresa los numeros a multiplicar '

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;ajustamos valores
   mov chr1,al    ;[chr1].chr2 * chr3 = ac.r1.r2

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;Ajustamos valores
   mov chr2,al    ;chr1.[chr2] * chr3 = ac.r1.r2

   mov ah,02h     ;Function(character to send to standard output)
   mov dl,'*'     ;Character to show
   int 21h

   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr3,al    ;chr1.chr2 * [chr3] = ac.r1.r2

   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr4,al    ;chr1.chr2 * [chr3] = ac.r1.r2

   mov ah,02h     ;Character to send to standar output
   mov dl,'='     ;
   int 21h        ;Interruption DOS functions

   ;Realizamos operacion 

   mov al,chr4  ;unidad del segundo numero
   mov bl,chr2  ;unidad del primer numero
   mul bl       ;multiplicar
   mov ah,0     ;limpiamos ah0
   aam          ;separamos de hex a dec
   mov ac1,ah   ;decenas del primera multiplicacion
   mov r4,al    ;unidades del primera multiplicacion
         
   mov al,chr4  ;unidades del segundo numero
   mov bl,chr1  ;decentas del primer numero
   mul bl       ;multiplicar
   mov r3,al    ;movemos el resultado de la operacion a r3
   mov bl,ac1   ;movemos el acarreo a bl
   add r3,bl    ;sumamos resultado mas acarreo
   mov ah,00h   ;limpiamos ah por residuos
   mov al,r3    ;movemos el resultado de la suma a al
   aam          ;separamos  de hex a dec
   mov r3,al    ;guardamos unidades en r3
   mov ac1,ah   ;guardamos decenas en ac1

   

   mov al,chr3    ;al = chr3
   mov bl,chr2    ;bl = chr2
   mul bl         ;AL = chr3*chr2 (BL*AL)
   mov Ah,0h      ;
   AAM            ;ASCII Adjusment
   mov ac,AH      ;ac = AH (Acarreo)
   mov r2,AL      ;r2 = AL       (Unidad del resultado)

   mov al,chr3    ;AL = chr3
   mov bl,chr1    ;BL = chr1
   mul bl         ;AL = chr1*chr3 (BL*AL)
   mov r1,al      ;r1 = AL       (Decena del resultado)
   mov bl,ac      ;BL = Acarreo anterior
   add r1,bl      ;r1 = r1+ac (r1 + Acarreo)
   mov ah,00h     ;
   mov al,r1      ;AL = r1 (Asignaci?n para el ajust)
   AAM            ;ASCII Adjustment
   mov r1,al      ;r1 = AL
   mov ac,ah      ;ac = AH (Acarreo para la Centena del resultado)


   ;suma final
   ;R4 resulta ser las unidades de mul y no se toma en cuenta ya que se pasa entero


   mov ax,0000h   ;limpiamos ax

   mov al,r3      ;movemos el segundo resultado de la primera mult a al
   mov bl,r2      ;movemos primer resultado de la segunda mult a bl
   add al,bl      ;sumamos
   mov ah,00h     ;limpiamos ah
   aam            ;separamos hex a dec
   mov r3,al      ;r3 guarda las decenas del resultado final
   mov r2,ah      ;r2 se utiliza como nuevo acarreo

   mov ax,0000h   ;''''

   mov al,ac1     ;movemos el acarreo de la primera mult a al
   mov bl,r1      ;movemos segundo resultado de la segunda mult a bl
   add al,r2      ;sumamos el nuevo  acarreo de la suma anterior  a al
   add al,bl      ;sumamos al a bl
   mov ah,00h     ;limpiamos el registro ah
   aam            ;separamos de hex a dec
   mov r1,al      ;r1 guarda las centenas
   mov r2,ah      ;ah se sigue utilizando como acarreo

   mov al,r2      ;movemos el acarreo a al
   mov bl,ac      ;movemos ac a bl
   add al,bl      ;sumamos al a bl
   ;aam            ;separamos hex a dec
   mov ac,al      ;mov al a ac como nuestro acarreo final


   ;Mostramos resultado

   mov ah,02h
   mov dl,ac
   add dl,30h
   int 21h        ;Mostramos ac (millar)

   mov ah,02H
   mov dl,r1
   add dl,30h
   int 21h        ;Mostramos r1 (centena)
       

   mov ah,02H
   mov dl,r3
   add dl,30h
   int 21h        ;Mostramos r3 (decena)

   mov ah,02H
   mov dl,r4
   add dl,30h
   int 21h        ;unidad 

exit:
    printn " "
    printn " "
    print "Presiona enter para salir... "
    mov ah, 0
    int 16h

ret 

.exit
end 



miércoles, 6 de marzo de 2019

Unidad 2 Programación básica


2.1 Ensamblador (y ligador) a utilizar

Aunque todos los ensambladores realizan básicamente las mismas tareas, podemos clasificarlos de acuerdo a características.

Ensambladores Cruzados (Cross-Assembler)

Se denominan así los ensambladores que se utilizan en una computadora que posee un procesador diferente al que tendrán las computadoras donde va a ejecutarse el programa objeto producido.

Ensambladores Residentes

Son aquellos que permanecen en la memoria principal de la computadora y cargan, para su ejecución, al programa objeto producido. Este tipo de ensamblador tiene la ventaja de que se puede comprobar inmediatamente el programa sin necesidad de transportarlo de un lugar a otro, como se hacía en cross-assembler, y sin necesidad de programas simuladores.
Sin embargo, puede presentar problemas de espacio de memoria, ya que el traductor ocupa espacio que no puede ser utilizado por el programador. Asimismo, también ocupará memoria el programa fuente y el programa objeto.
La ventaja de estos ensambladores es que permiten ejecutar inmediatamente el programa; la desventaja es que deben mantenerse en la memoria principal tanto el ensamblador como el programa fuente y el programa objeto.

Macroensambladores

Son ensambladores que permiten el uso de macroinstrucciones (macros). Debido a su potencia, normalmente son programas robustos que no permanecen en memoria una vez generado el programa objeto. Puede variar la complejidad de los mismos, dependiendo de las posibilidades de definición y manipulación de las macroinstrucciones, pero normalmente son programas bastantes complejos, por lo que suelen ser ensambladores residentes.

Microensambladores

Generalmente, los procesadores utilizados en las computadoras tienen un repertorio fijo de instrucciones, es decir, que el intérprete de las mismas interpretaba de igual forma un determinado código de operación.

Ensambladores de una fase.

Estos ensambladores leen una línea del programa fuente y la traducen directamente para producir una instrucción en lenguaje máquina o la ejecuta si se trata de una pseudoinstrucción. También va construyendo la tabla de símbolos a medida que van apareciendo las definiciones de variables, etiquetas, etc. Debido a su forma de traducción, estos ensambladores obligan a definir los símbolos antes de ser empleados para que, cuando aparezca una referencia a un determinado símbolo en una instrucción, se conozca la dirección de dicho símbolo y se pueda traducir de forma correcta. Estos ensambladores son sencillos, baratos y ocupan poco espacio, pero tiene el inconveniente indicado.

Ensambladores de dos fases

Los ensambladores de dos fases se denominan así debido a que realizan la traducción en dos etapas. En la primera fase, leen el programa fuente y construyen una tabla de símbolos; de esta manera, en la segunda fase, vuelven a leer el programa fuente y pueden ir traduciendo totalmente, puesto que conocen la totalidad de los símbolos utilizados y las posiciones que se les ha asignado.

2.3 Captura básica de cadenas

2.4 Comparación y prueba

La instrucción CMP pro lo común es utilizada para comparar dos campos de datos, uno de los cuales están contenidos en un registro. El formato general para CMP es:| [etiqueta:] | CMP | {registro/memoria}, {registro/memoria/inmediato} |
Observe que la operación compara el primer operando con el segundo; por ejemplo, el valor del primer operando es mayor que, igual o menor que el valor del segundo operando.
La instrucción CMPS compara el contenido de una localidad de memoria (direccionada por DS:SI). Dependiendo de la bandera de dirección, CMPS incrementa o disminuye también los registros SI y DI en 1 para bytes, en 2 para palabras y en 4 para palabras dobles. La operación establece las banderas AF, CF, OF, PF, SF y ZF.
Cuando se combinan con un prefijo REP y una longitud en el CX, de manera sucesiva CMPS puede comparar cadenas de cualquier longitud.
CMPS proporciona una comparación alfanumérica, esto es, una comparación de acuerdo a con los valores ASCII. Considere la comparación de dos cadenas que contienen JEAN y JOAN
Algunas derivaciones de CMPS son las siguientes:
· CMPSB. Compara bytes
· CMPSD. Compara palabras dobles
· CMPSW. Compara palabras

2.5 Saltos

Estas instrucciones permiten saltar a otras partes del código. Todas cambian el registro IP (contador de programa) y el registro CS (segmento de código) si es un salto lejano. Un salto es lejano cuando la dirección a la que se salta no está en el mismo segmento de código.
Existen dos tipos de saltos: los absolutos; en lo que se especifica la dirección absoluta a la que se salta; y los relativos; que son saltos hacia delante o hacia atrás desde el valor de IP.
JMP realiza un salto incondicional a la dirección especificada. La siguiente tabla relaciona los tipos de saltos y los argumentos que puede tomar esta instrucción.

Saltos condicionales

Estas instrucciones realizan el salto a la dirección especificada en función de si se cumple o no una condición. Para evaluar la condición se considera el registro de estado, esto quiere decir que la condición depende directamente de la instrucción anterior.

Instrucciones en función del tipo de operandos y la condición que se quiere evaluar


Instrucciones en función del tipo de operandos y la condición que se quiere evaluar


2.6 Ciclos condicionales

Las instrucciones de bucle se usan para realizar estructuras repetitivas, y utilizan el registro CX como contador.
LOOP esta instrucción hace que el programa salte a la dirección especificada (salto dentro del segmento), mientras que CX sea distinto de 0 y decrementa CX en 1 cada vez.
LOOP salto
Ejemplo:
MOV CX, 100
COMIENZO: …
LOOP COMIENZO; este bucle se repite 100

LOOPNE/LOOPNZ esta instrucción salta a la dirección especificada mientras que CX sea distinto de 0 y si ZF = 0.
LOOPNE/LOOPNZ salto
Esta instrucción proporciona una ruptura del bucle adicional.

LOOPE/LOOPZ esta instrucción actúa como la anterior pero la condición adicional es ZF = 1.
LOOPE/LOOPZ salto

JCXZ esta instrucción realiza un salto si CX = 0.
JCXZ salto
Ninguna de estas instrucciones afecta al registro de estado.


lunes, 4 de marzo de 2019

Unidad 1. Introduccion al lenguaje ensamblador


1.1 IMPORTANCIA DE LA PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR

El lenguaje ensamblador como cualquier lenguaje de programación es un conjunto de palabras que le indican al ordenador lo que tiene que hacer. Sin embargo la diferencia fundamental es que cada instrucción escrita en lenguaje ensamblador tiene una correspondencia exacta con una operación en el procesador. Por lo que son operaciones muy sencillas tales como: “Cargar 32 en el registro BX” o “Transferir el contenido del registro CL al CH”. Así pues, las palabras del lenguaje ensamblador son nemotécnicas que representan el código máquina, lenguaje que entiende el procesador.
En el 8086/88 se definen los siguientes tamaños de datos:
4 bits - nibble
8 bits - byte
16 bits - word
32 bits – dword

1.2 EL PROCESADOR Y SUS REGISTROS

La Unidad Central de Proceso (CPU, por sus siglas en inglés) tiene 14 registros internos cada uno de 16 bits. Los primeros cuatro, AX, BX, CX y DX, son de uso general y se pueden usar también como registros de 8 bits. Es decir, AX se puede dividir en AH y AL (AH es el byte alto, high, y AL es el byte bajo, low) Lo mismo es aplicable a los otros tres (BX en BH y BL, CX en CH y CL y DX en DH y DL)
Estos son los únicos registros que pueden usarse de modo dual (en 8 o 16 bits)
Los registros de la CPU son conocidos por sus nombres propios, que son:
AX (acumulador)
BX (registro base)
CX (registro contador)
DX (registro de datos)
DS (registro del segmento de datos)
ES (registro del segmento extra)
SS (registro del segmento de pila)
CS (registro del segmento de código)
BP (registro de apuntadores base)
SI (registro índice fuente)
DI (registro índice destino)
SP (registro del apuntador de pila)
IP (registro del apuntador de siguiente instrucción)
F (registro de banderas)
El registro AX se usa para almacenar resultados, lectura o escritura desde o hacia los puertos.
El BX sirve como apuntador base o índice.
El CX se utiliza en operaciones de iteración, como un contador que automáticamente se incrementa o decrementa de acuerdo con el tipo de instrucción usada.
El DX se usa como puente para el acceso de datos.
El DS es un registro de segmento cuya función es actuar como policía donde se encuentran los datos. Cualquier dato, ya sea una variable inicializada o no, debe estar dentro de este segmento. La única excepción es cuando tenemos programas del tipo *.com, ya que en éstos sólo puede existir un segmento. El registro ES tiene el propósito general de permitir operaciones sobre cadenas, pero también puede ser una extensión del DS
Ejemplo de código usando AX, DS y DX:
.MODEL SMALL
.STACK
.DATA                
CADENA1 DB "HOLAMUNDO"."$"
.CODE
PROGRAMA:
 MOV AX,@DATA
 MOV DS, AX
 MOV DX, OFFSET CADENA1
 MOV AH, 9
 INT 21H
END PROGRAMA

1.3 LA MEMORIA PRINCIPAL (RAM)

Este tipo de memoria puede ser borrada y grabada las veces que deseemos. La única desventaja es que la información grabada en ella solo puede ser utilizada mientras tenga energía. En cuanto se corte la alimentación, los datos que se grabaron se borrarán instantáneamente. Se usan solo como almacenamiento temporal.

1.4 EL CONCEPTO DE INTERRUPCIONES

Una interrupción es una situación especial que suspende la ejecución de un programa de modo que el sistema pueda realizar una acción para tratarla. Tal situación se da, por ejemplo, cuando un periférico requiere la atención del procesador para realizar una operación de E/S.
Las interrupciones constituyen quizá el mecanismo más importante para la conexión del microcontrolador con el mundo exterior, sincronizando la ejecución de programas con acontecimientos externos.
Ejemplos de interrupciones
int 01h-->un solo paso
int 02h-->Interrupción no enmascarable
int 03h--> Punto de interrupción
int 04h-->Desbordamiento
int 05h-->Impresión de pantalla
int 08h-->Cronometro
int 15h-->Servicios del sistema
int 16h-->Funciones de entrada del teclado
int 18h-->Entrada con el Basic de Rom
int 19h-->Cargador de arranque
int 20h-->Invoca al servicio de terminación de programa del DOS
int 21h-->Invoca a todos los servicios de llamada a función DOS
int 1Ah-->Leer y establecer la hora
int 1Bh-->Obtener el control con una interrupción de teclado.
int 2oh-->Terminar un programa
int 33h-->Funciones del Ratón

1.5 LLAMADAS AL SERVICIO DE SISTEMAS

Una llamada al sistema es un método o función que puede invocar un proceso para solicitar un cierto servicio al sistema operativo. Dado que el acceso a ciertos recursos del sistema requiere la ejecución de código en modo privilegiado, el sistema operativo ofrece un conjunto de métodos o funciones que el programa puede emplear para acceder a dichos recursos. En otras palabras, el sistema operativo actúa como intermediario, ofreciendo una interfaz de programación (API) que el programa puede usar en cualquier momento para solicitar recursos gestionados por el sistema operativo.

1.6 MODOS DE DIRECCIONAMIENTO

Los modos de direccionamiento indican la manera de obtener los operandos y son:
Direccionamiento de registro
Direccionamiento inmediato
Direccionamiento directo
Direccionamiento indirecto mediante registro
Direccionamiento indirecto por registro base
Direccionamiento indexado
Direccionamiento indexado respecto a una base
El tipo de direccionamiento se determina en función de los operandos de la instrucción.
La instrucción MOV realiza transferencia de datos desde un operando origen a un operando Su formato es el siguiente:
MOV destino, origen

1.7 PROCESO DE ENSAMBLADO Y LIGADO

1. El programa utiliza un editor de texto para crear un archivo de texto ASCII, conocido como archivo de código fuente.
2. El ensamblador lee el archivo de código fuete y produce un archivo de código objeto, una traducción del programa a lenguaje máquina. De manera opcional, produce un archivo de listado. Si ocurre un error, el programador debe regresar al paso 1 y corregir el programa.
3. El enlazador lee el archivo de código objeto y verifica si el programa contiene alguna llamada a los procedimientos en una biblioteca de enlace. El enlazador copia cualquier procedimiento requerido de la biblioteca de enlace, lo combina con el archivo de código objeto y produce el archivo ejecutable. De manera opcional, el enlazador puede producir un archivo de mapa.

4. La herramienta cargador (loader) del sistema operativo lee el archivo ejecutable y lo carga en memoria, y bifurca la CPU hacia la dirección inicial del programa, para que éste empiece a ejecutarse.

1.8 DESPLEGADO DE MENSAJES DEL MONITOR

Todos los gráficos y el texto que se muestran en el monitor se escriben en la RAM de visualización de video, para después enviarlos al monitor mediante el controlador de video. El controlador de video es en sí un microprocesador de propósito especial, que libera a la CPU principal del trabajo de controlar el hardware de video.

INSTRUCCIONES DE TRANSFERENCIA DE DATOS

Las instrucciones de transferencia de datos copian datos de un sitio a otro y son: MOV, XCHG,
XLAT, LEA, LDS, LES, LAHF, SAHF, PUSH, PUSHF, POP, POPF.
MOV realiza la transferencia de datos del operando de origen al destino, MOV admite todos los tipos de direccionamiento.
Ambos operandos deben ser del mismo tamaño y no pueden estar ambos en memoria.
MOV reg, reg ; reg es cualquier registro.
MOV mem, reg ; mem indica una posición de memoria
MOV reg, mem
MOV mem, dato ; dato es una constante
MOV reg, dato
MOV seg-reg, mem ;seg-reg es un registro de segmento
MOV seg-reg, reg
MOV mem, seg-reg
MOV reg, seg-reg
XCHG realiza el intercambio entre los valores de los operandos. Puede tener operando en registros y en memoria:
XCHG reg, mem
XCHG reg, reg
XCHG mem, reg
LEA carga en un registro especificado la dirección efectiva especificada como en el operando origen:
LEA reg, mem
Ejemplos:
LEA AX, [BX] ; carga en AX la dirección apuntada por BX.
LEA AX, 3[BP+SI] ; carga en AX la dirección resultado de multiplicar por 3 la suma de los contenido de BP y SI.
Ejemplo de codigo usando LEA
CODE SEGMENT
ASSUME CS:CODE, DS:CODE. SSCODE, ES:CODE
ORG 100h
principio:
 mov ah, 0Fh
 mov ah, 0
 int 10h
 lea dx, mensaje_a_mostrar
 mov ah, 9h
 int 21h
 int 20h
mensaje_a_mostrar db "hola mundo!!$",0
CODE ENDS
end principio


INSTRUCCIONES DE PRUEBA, COMPARACIÓN Y SALTOS.
Este grupo es una continuación del anterior, incluye las siguientes instrucciones:
EST verifica
CMP compara
JMP salta
JE, JZ salta si es igual a cero
JNE, JNZ salta si no igual a cero
JS salta si signo negativo
JNS salta si signo no negativo
JP, JPE salta si paridad par
JNP, JOP salta si paridad impar
JO salta si hay capacidad excedida
JNO salta si no hay capacidad excedida
JB, JNAE salta si por abajo (no encima o igual)
JNB, JAE salta si no está por abajo (encima o igual)
JBE, JNA salta si por abajo o igual (no encima)
JNBE, JA salta si no por abajo o igual (encima)
JL, JNGE salta si menor que (no mayor o igual)
JNL, JGE salta si no menor que (mayor o igual)
JLE, JNG salta si menor que o igual (no mayor)
JNLE, JG salta si no menor que o igual (mayor)

EJEMPLO
cmp al,  18
    jge mayor
    jmp menor
   
            
mayor:
mov ah, 09 
lea dx, msg1
int 21h
jmp fin
           
menor:
mov ah, 09
lea dx, msg2
int 21h
jmp fin



Unidad 3 -Unidad 4

Unidad 3 Modularizacion Programación modular Los avances en la programación de computadoras han permitido crear hermosas y grandes aplic...