Descargar

Programación en ensamblador para procesadores 80×86 (página 3)


Partes: 1, 2, 3

Descripción: Este programa ilustra el uso de las instrucciones DIV e IDIV.

*

.MODEL TINY

.DATA

NUM1 db 3

NUM2 db -5

.CODE

INICIO: ;INICIO DEL PROGRAMA MOV AX,100 ;AX=100

MOV BH,10 ;BH=10

DIV BH ;DIVISION DE 8 BITS SIN SIGNO MOV AX,100 ;AX=100

DIV NUM1 ;DIVISION DE 8 BITS SIN SIGNO CON VARIABLES

MOV AL,-10 ;AX=-10

CBW ;EXTENSIÓN DE SIGNO A 16 BITS IDIV num2 ;DIVISION DE 8 BITS CON SIGNO MOV AX,4c00h ;FIN DEL PROGRAMA

INT 21h ; END INICIO END

Instrucciones para la manipulación de banderas

El registro de banderas tiene diferentes funciones en cada uno de sus bits, algunos

de estos bits (banderas) pueden ser controlados por instrucciones directas de bajo nivel; sin embargo, se debe tener en cuenta que estas banderas están íntimamente ligadas con funciones internas del microprocesador, por ejemplo la línea INTR (interrupción por hardware), acarreos, etc., y que al manipularlas incorrectamente podemos llegar al extremo de bloquear la computadora. Es por esto que se recomienda que sólo programadores experimentados modifiquen dichas banderas.

En esta sección se explicarán algunas de las instrucciones más comunes y sus aplicaciones, pero no se desarrollarán programas por razones de seguridad.

Control de interrupción

La terminal INTR del microprocesador puede ser activada o desactivada directamente por los programas por medio de las instrucciones STI y CLI. STI carga un 1 en IF, con lo cual INTR queda habilitada; por otro lado, CLI carga un cero en IF, con lo cual las interrupciones externas o por hardware quedan deshabilitadas.

Control de la bandera de acarreo

La bandera de acarreo, CF, es la encargada de indicar cuando ha ocurrido un acarreo o préstamo en operaciones de suma o resta, también indica errores en la ejecución de procedimientos. Existen tres instrucciones básicas para su manipulación: STC (activar acarreo), CLC (desactivar acarreo) y CMC (Complementar acarreo).

Control de la bandera de dirección

La bandera de dirección, DF, es utilizada para establecer el sentido en el que las cadenas de datos serán procesadas por los programas. Un cero en DF indica procesamiento de izquierda a derecha, mientras que un uno indica procesamiento de derecha a izquierda.

Para controlar esta bandera, existen dos instrucciones, CLD (limpiar bandera) y

STD (establecer bandera). STD coloca un uno y CLD coloca un cero.

Estas instrucciones serán aplicadas más adelante en el capítulo 3, en el cual se desarrollan varios programas para mostrar su uso.

Instrucciones de comparación y prueba

Existen dos instrucciones especiales en el microprocesador 8086: CMP y TEST.

CMP (Comparar) compara si dos valores son iguales o diferentes. Su funcionamiento es similar al de la instrucción SUB (restar), sólo que no modifica el operando de destino, solamente modifica las banderas de signo (SF), de cero (ZF) y de acarreo (CF).

Por ejemplo: CMP AX,1235

Esta instrucción compara si el valor almacenado en el registro AX es igual que el valor 1235 en decimal.

Por otro lado, la instrucción TEST realiza la operación AND de los operandos especificados sin que el resultado se almacene en algún registro, modificando únicamente ciertas banderas. Su aplicación más común es la de probar si algún bit es cero.

Ejemplo: Test AL,1

Esta instrucción prueba si el bit menos significativo de AL es 1 y

Test AL,128

prueba si el bit más significativo de AL es 1.

Por lo general estas instrucciones van seguidas de alguna de las instrucciones de salto, las cuales se estudian en otra sección.

Instrucciones de salto

En los lenguajes de alto nivel como Pascal y C, los programadores pueden controlar el flujo de los programas por medio de instrucciones condicionales compuestas; por ejemplo, en Pascal el siguiente conjunto de instrucciones permite tomar una decisión sobre el flujo del programa:

IF A=5 then write("Error…"); else

A:=A+1;

En contraste, el lenguaje ensamblador no proporciona tales mecanismos. Este tipo de decisiones se realizan por medio de una serie de instrucciones que van teniendo un significado consecutivo; es decir, el efecto de la instrucción siguiente depende del resultado anterior.

El lenguaje ensamblador proporciona un conjunto de instrucciones conocidas como instrucciones de salto. Estas instrucciones son utilizadas en conjunto con instrucciones de comparación y prueba para determinar el flujo del programa.

Existen dos tipos de instrucciones de salto: las instrucciones de salto condicional y las de salto incondicional.

Las instrucciones de salto condicional, revisan si ha ocurrido alguna situación para poder transferir el control del programa a otra sección, por ejemplo:

CMP AX,0

JE otro

………..

………. otro:

……….

………. End

En este ejemplo, la instrucción JE (Salta si es igual) revisa si la prueba implícita en la instrucción anterior resultó positiva, es decir, si la comparación de AX con 0 fue cierta. En caso de que AX sea igual a 0, JE transfiere el control del programa a las instrucciones que se encuentran después de la etiqueta "otro". En caso contrario ejecuta las instrucciones siguientes a JE.

Por otro lado, las instrucciones de salto incondicional (sólo existe una) permiten cambiar el flujo del programa sin verificar si se cumplió alguna condición.

Ejemplo: Mov AX,10

Jmp otro

……..

…….. otro:

……..

……..

En este ejemplo, inmediatamente después de cargar el registro AX con el valor de

10, se transfiere el control del programa a la instrucción que sigue después de la etiqueta

"otro".

La siguiente es una lista de las instrucciones de salto condicional y su descripción:

JA o JNBE: Salta si está arriba o salta si no está por debajo o si no es igual (jump if above or jump if not below or equal). El salto se efectúa si la bandera de CF=0 o si la bandera ZF=0.

JAE o JNB: Salta si está arriba o es igual o salta si no está por debajo (jump if above or equal or jump if not below). El salto se efectúa si CF=0.

JB o JNAE: Salta si está por debajo o salta si no está por arriba o es igual (jump if below or jump if not above or equal). El salto se efectúa si CF=1.

JBE o JNA: Salta si está por debajo o es igual o salta si no está por arriba (jump if below or equal or jump if not above). El salto se efectúa si CF=1 o ZF=1.

JE o JZ: Salta si es igual o salta si es cero (jump if equal or jump if zero). El salto se efectúa si ZF=1.

JNE o JNZ: Salta si no es igual o salta si no es cero (jump if not equal or jump if not zero). El salto se efectúa si ZF=0.

JG o JNLE: Salta si es mayor o salta si no es menor o igual (jump if greater or jump if not less or equal). El salto se efectúa si ZF=0 u OF=SF.

JGE o JNL: Salta si es mayor o igual o salta si no es menor (jump if greater or equal or jump if not less). El salto se efectúa si SF=OF.

JL o JNGE: Salta si es menor o salta si no es mayor o igual (jump if less or jump if not greater or equal). El salto se efectúa si SF<>OF

JLE o JNG: Salta si es menor o igual o salta si no es mayor (jump if less or equal or jump if not greater). El salto se efectúa si ZF=1 o SF<>OF.

JC: Salta si hay acarreo (jump if carry). El salto se efectúa si CF=1.

JNC: Salta si no hay acarreo (jump if no carry). El salto se efectúa si CF=0.

JNO: Salta si no hay desbordamiento (jump if no overflow). El salto se efectúa si OF=0.

JNP o JPO : Salta si no hay paridad o salta si la paridad es non (Jump if no parity or jump if parity odd). El salto se efectúa si PF=0.

JNS: Salta si no hay signo (jump if not sign). El salto se efectúa si SF=0.

JO: Salta si hay sobreflujo (jump if overflow). El salto se efectúa si OF=1.

JP o JPE: Salta si hay paridad o salta si la paridad es par (jump if parity or jump if parity even). El salto se efectúa si PF=1.

JS: Salta si hay signo (jump if sign). El salto se efectúa si SF=1.

El siguiente programa muestra la forma de utilizar instrucciones de saltos condicionales:

.COMMENT

*

Programa: Jumps1.Asm

Descripción: Este programa ilustra el uso de las instrucciones de salto condicional e

incondicional

*

.MODEL TINY

.DATA

cad1 db 'Las cantidades son iguales…',13,10,'$' cad2 db 'Las cantidades no son iguales…',13,10,'$'

.CODE

INICIO: ;Punto de entrada al programa

Mov ax,10 ;AX=10

Mov bx,10 ;BX=10

Cmp ax,bx ;Es AX=BX?

Je igual ;S¡, entonces saltar a la etiqueta igual

Lea dx,cad2 ;No, entonces imprimir Cad2

Mov ah,09h ; Int 21h ;

Jmp salir ;saltar a la etiqueta salir igual:

Lea dx,cad1 ;imprimir el mensaje en cad1

Mov ah,09h ; Int 21h ; salir:

Mov ax,4c00h ;Salir

Int 21h ; END INICIO END

Este programa ilustra de forma básica la utilización de las instrucciones de salto, tanto condicionales como incondicionales.

Primeramente, el programa inicializa los registros AX y BX con el valor 10 en decimal; después utiliza la instrucción CMP para comparar el contenido de ambos registros; la instrucción JE (Salta si es igual) verifica la bandera de cero ZF, si ZF=1 significa que los contenidos son iguales y por lo tanto efectúa el salto hacia la etiqueta "Igual", en caso de que ZF=0 el programa continúa su flujo normal hasta encontrar la instrucción JMP; en este caso la instrucción JMP se utiliza para evitar llegar a la etiqueta "Igual" en el caso de que los datos sean diferentes.

El formato para utilizar las instrucciones de salto es idéntico al mostrado en este programa, solamente hay que identificar cual es la condición que queremos probar, para de esta forma seleccionar adecuadamente la instrucción de salto.

Instrucciones para ciclos

El lenguaje ensamblador cuenta con una instrucción muy poderosa que permite la programación de ciclos finitos, la instrucción LOOP.

Esta instrucción trabaja en forma conjunta con el registro contador CX. El formato general de esta instrucción es:

Mov CX,No_Veces

Etiqueta:

——-

Loop Etiqueta

La instrucción LOOP ejecuta las instrucciones que se encuentran entre la Etiqueta:

y Loop Etiqueta el numero de veces que indique el campo No_Veces.

Por ejemplo, el siguiente grupo de instrucciones incrementa en 1 el registro AX, esto lo repite 10 veces.

Mov CX,10 ;10 veces

Otro:

Inc AX ; AX=AX+1

Loop Otro

La instrucción Loop decrementa el registro CX en cada iteración y se detiene cuando CX es igual a cero.

El siguiente programa da un ejemplo más ilustrativo:

.COMMENT

*

Programa: Loop.ASM

Descripción: Este programa calcula la sucesión de Fibonacci para los 10 primeros términos de la serie, utilizando para ello un ciclo controlado por la instrucción Loop.

La sucesión está formada por números, de modo tal que cada número es la suma de los dos anteriores-

Ejemplo:

1,1,2,3,5,8,13,21,34,55….

*

.MODEL tiny

.CODE

Inicio: ;Punto de entrada al programa

Mov AX,0 ;AX=0

Mov BX,1 ;BX=1 Estos son los dos primeros elementos 0+1=1

Mov CX,10 ;Repetir 10 veces

Repite:

Mov DX,AX ;DX=AX

Add DX,BX ;DX=AX+BX Mov AX,BX ;Avanzar AX Mov BX,DX ;Avanzar BX

Loop Repite ;siguiente número

Mov AX,4C00h ;Terminar programa y salir al DOS

Int 21h ; END Inicio END

Instrucciones lógicas

El microprocesador 8086 cuenta con un grupo de instrucciones lógicas que operan

a nivel de bit, estas instrucciones son: AND, OR, XOR y NOT.

A continuación se muestran las tablas de verdad de estas instrucciones:

Las instrucciones que se enlistan antes requieren dos operandos, a excepción de la operación NOT que sólo requiere uno.

En la figura se puede observar que para la operación AND, si los dos operandos son 1, el resultado será 1, en cualquier otra situación será 0.

La operación OR establece el resultado a 1 si cualquiera de los dos operandos es 1, de lo contrario el resultado será 0.

La instrucción XOR coloca en 0 el resultado si los operandos son iguales, de lo contrario establece 1.

Finalmente, la instrucción NOT cambia de estado todos los bits del operando, los unos por ceros y los ceros por unos.

La principal aplicación de estas instrucciones es el enmascaramiento de información. La operación AND nos permite poner a cero cualquier bit de un dato; la

operación OR nos permite poner a uno cualquier bit de un dato y la operación XOR permite borrar el contenido de algún registro o localidad de memoria, así como para negar algún bit.

El siguiente programa muestra la forma de utilizar estas instrucciones:

.COMMENT

*

Programa: AndOr.ASM

Descripción: Este programa ilustra el uso de las instrucciones

AND, OR, XOR y NOT.

*.MODEL TINY

.DATA

Mascara1 db 11111110b

Mascara2 db 00000001b Dato1 db 11111111b Dato2 db 00000000b

.CADE INICIO:

Mov cx,0000h ;CX=0;

Mov al,dato1 ;al=dato1

And al,mascara1 ;al=al and mascara1

Mov ah,dato2 ;ah=dato2

Or ah,mascara2 ;ah=ah or mascara2

Xor bx,bx ;bx=0

Not cx ;cx=not cx

Mov ax,4c00h

Int 21h

END INICIO

END

El programa del listado 8 declara cuatro variables de tipo byte: Mascara1, Mascara2, Dato1 y Dato2; después inicializa CX=00h, Al=FFh, Ah=00h; al aplicar una operación and de FFh y FEh, el resultado es FEh, en otras palabras, se apagó el bit menos significativo de al; la siguiente operación es un OR entre 00 y 01, lo cual da como resultado que se encienda el bit menos significativo del Ah, el resultado es 01. La siguiente operación es XOR BX,BX, la cual al ser aplicada sobre el mismo operando da como resultado que dicho operando sea borrado. Por ultimo, la operación NOT CX cambia todos los bits de 0 a 1 y viceversa, por lo cual CX=11h.

Instrucciones de rotación y desplazamiento

El microprocesador cuenta con un conjunto de instrucciones que permiten la

manipulación de las posiciones individuales de los bits dentro de un registro o localidad de memoria, estas instrucciones se encuentran divididas en dos grupos: instrucciones de rotación e instrucciones de desplazamiento (también conocidas como instrucciones para corrimientos).

Las instrucciones para rotación son cuatro y nos permiten mover de forma cíclica los bits que forman parte de un registro o localidad de memoria, estas instrucciones son ROL, ROR, RCL , RCR.

ROL y ROR funcionan de forma muy semejante; al ejecutar una instrucción ROL, el bit más significativo del dato es desplazado hacia la bandera de acarreo y también hacia la posición del bit memos significativo, por lo cual todos los bits restantes son rotados o

movidos hacia la izquierda. La instrucción ROR funciona igual, sólo que ésta trabaja hacia la derecha.

Las instrucciones RCL y RCR permiten la rotación de los bits de una localidad de memoria o registro, considerando también el contenido de la bandera de acarreo. En el caso de RCL, el bit más significativo pasa hacia la bandera de acarreo, el bit que se encontraba en la bandera de acarreo pasa al bit menos significativo y finalmente los bits restantes son rotados hacia la izquierda. La instrucción RCR funciona igual, pero aplica su rotación hacia la derecha.

Para ilustrar el uso de estas instrucciones, tomaremos como ejemplo la instrucción

ROL (Rotación a la izquierda).

Las instrucciones de rotación y desplazamiento tienen diferentes formas de utilizarse dependiendo del modelo del microprocesador, los siguientes ejemplos muestran estas formas:

En el microprocesador 8086 existen dos formas, con contador implícito y con contador explícito.

La forma con contador implícito se utiliza para realizar una sola rotación a la vez y tiene el siguiente formato:

ROL AX,1 ;Rotar AX un bit

La forma con contador explícito se utiliza para realizar rotaciones n veces sobre un registro o localidad de memoria:

MOV CL,3 ;Número de rotaciones

ROL AX,CL ; Rotar AX 3 veces

En el microprocesador 80386 y superiores existe una variante de contador implícito, la cual nos permite establecer el contador directamente como un operando, su forma es la siguiente:

ROL AX,3 ; Rotar AX 3 veces, sólo en 80386 y posteriores

En el caso de las instrucciones de desplazamiento, también existen cuatro: SHL, SHR, SAL, SAR.

SHL y SHR se utilizan para desplazar los bits de un registro o localidad de memoria, sin considerar el signo de su contenido.

SAL y SAR se utilizan para desplazar los bits de un registro o localidad de memoria, considerando su contenido como una cantidad con signo.

Las instrucciones SHL y SHR funcionan de forma idéntica, sólo que en sentidos opuestos. La instrucción SHL inserta un 0 en la posición del bit menos significativo y desplaza todos los demás bits una posición hacia la izquierda, colocando el bit más significativo en la bandera de acarreo.

La instrucción SHR inserta un 0 en la posición más significativa, desplaza todos los bit una posición hacia la derecha y finalmente coloca el bit menos significativo en la bandera de acarreo.

Algunos ejemplos de su uso son los siguientes:

SHL AX,1 ; Desplaza el contenido de AX una posición a la izquierda

MOV CX,3 ; Número de veces

SHR AX,CL ; Desplaza AX 3 veces hacia la derecha

SHL BX,4 ; Desplaza BX 4 veces hacia la izquierda, sólo en 386 y posteriores

Las dos instrucciones restantes SAL y SAR son muy parecidas a las instrucciones SHL y SHR, sólo que estas dos instrucciones consideran el contenido de los registros como cantidades con signo, por lo cual el bit en la posición más significativa del dato (bit de signo) se conserva sin cambio.

El siguiente ejemplo muestra el uso de las instrucciones de rotación y desplazamiento, revise el código sólo con fines ilustrativos.

COMMENT

*

Programa: Rota.ASM

Descripción: Este programa ilustra el uso de las instrucciones de rotación y

desplazamiento.

.MODEL TINY

.DATA

dato1 dw 10 ; variable de tipo entero

.CODE

INICIO: ; Punto de entrada al programa

mov ax,1 ; AX=1 mov bx,10 ; BX=10 shl ax,1 ; ax=ax*2

mov cx,3 ; contador igual a 3 shl ax,cl ; ax=ax*8

shr bx,1 ; bx=bx/2

mov cx,2 ;

shr bx,cl ; bx=bx/4

shl dato1,1 ; dato1=dato1*2

mov ax,1 ; ax=1

rol ax,1 ; rotar ax 1 vez mov bx,-10 ; bx=-10

sal bx,1 ; bx=bx*2

mov ax,4c00h ; Terminar int 21h ; Salir al dos END INICIO

END

Instrucciones para la pila

La pila es un grupo de localidades de memoria que se reservan con la finalidad de proporcionar un espacio para el almacenamiento temporal de información.

La pila de los programas es del tipo LIFO (Last In First Out, Ultimo en entrar, Primero en salir).

Para controlar la pila el microprocesador cuenta con dos instrucciones básicas:

Push (Meter) y Pop (sacar).

El formato de estas instrucciones es el siguiente: Push operando

Pop operando

Cuando se ejecuta la instrucción Push, el contenido del operando se almacena en la ultima posición de la pila.

Por ejemplo, si AX se carga previamente con el valor 5, una instrucción Push AX

almacenaría el valor 5 en la ultima posición de la pila.

Por otro lado la instrucción Pop saca el último dato almacenado en la pila y lo coloca en el operando.

Siguiendo el ejemplo anterior, la instrucción Pop BX obtendría el número 5 y lo almacenaría en el registro BX.

El siguiente ejemplo muestra como implementar la instrucción XCHG por medio de las instrucciones Push y Pop. Recuerde que la instrucción XCHG intercambia el contenido de sus dos operandos.

.COMMENT

Programa: PushPop.ASM

Descripción: Este programa demuestra el uso de las instrucciones para el manejo de la

pila, implementando la instrucción XCHG con Push y Pop

*

.MODEL tiny

.CODE

Inicio: ;Punto de entrada al programa

Mov AX,5 ;AX=5

Mov BX,10 ;BX=10

Push AX ;Pila=5

Mov AX,BX ;AX=10

Pop BX ;BX=5

Mov AX,4C00h ;Terminar programa y salir al DOS Int 21h ;

END Inicio

END

Manipulación de cadenas (Strings) Definición de string

En el lenguaje ensamblador el tipo de dato cadena (string) no está definido, pero

para fines de programación, una cadena es definida como un conjunto de localidades de memoria consecutivas que se reservan bajo el nombre de una variable.

Almacenamiento en memoria

De acuerdo con la definición anterior, las siguientes líneas en ensamblador declaran cadenas:

.DATA

Cadena_ASCII db "Cadena",13,10,"$"

Cadena_Enteros dw 5 Dup (0)

Las dos líneas anteriores están declarando variables de tipo cadena. En el primer caso, Cadena_ASCII reserva un total de 9 bytes de memoria (1 byte = 1 Carácter ASCII) incluyendo el carácter "$" que indica fin de cadena. En el segundo caso, Cadena_Enteros reserva espacio para almacenar 3 cantidades enteras o lo que es lo mismo 6 bytes de memoria (1 entero = 2 bytes), todas inicializadas con cero.

La diferencia en los casos anteriores radica en el tamaño del dato que compone la cadena, 1 byte para cadenas de caracteres y 2 o más bytes para cadenas de datos numéricos.

El almacenamiento en memoria se vería de la siguiente forma:

Instrucciones para el manejo de strings

El lenguaje ensamblador cuenta con cinco instrucciones para el manejo de cadenas:

MOVS: Mueve un byte o palabra desde una localidad de memoria a otra. LODS : Carga desde la memoria un byte en AL o una palabra en AX. STOS : Almacena el contenido del registro AL o AX en la memoria.

CMPS : Compara localidades de memoria de un byte o palabra.

SCAS : Compara el contenido de AL o AX con el contenido de alguna localidad de memoria.

Las instrucciones para cadenas trabajan en conjunto con la instrucción CLD, la cual permite establecer que el sentido en el que las cadenas serán procesadas será de izquierda a derecha.

Otra instrucción importante es el prefijo de repetición REP, el cual permite que una instrucción para manejo de cadenas pueda ser repetida un número determinado de veces.

Los registros índice juegan un papel importante en el procesamiento de cadenas de datos, el par de registros CS:SI indican la dirección de la cadena original que será procesada, y el par ES:DI contienen la dirección donde las cadenas pueden ser almacenadas.

Para comprender realmente como funcionan las instrucciones para cadenas analizaremos varios programas que fueron escritos para este fin. Recuerde que las cadenas en ensamblador no se refieren únicamente a cadenas de caracteres ASCII, sino a cualquier tipo de dato.

.COMMENT Programa: Cad1.ASM

Descripción: Este programa ilustra la forma de utilizar la instrucción MOVS para copiar el contenido de una cadena dentro de otra.

.MODEL tiny

.DATA

cad1 db 'Esta es la cadena1','$'

cad2 db 'Esta es la cadena2','$'

.CODE

inicio: ;Punto de entrada al programa

cld ;Procesamiento de cadenas de izq->der. mov cx,18 ;longitud de la cadena original

lea di,cad2 ;ES:DI contienen la dirección de Cad2

lea si,cad1 ;DS:SI contienen la dirección de Cad1 rep movsb ;DS:SI->ES:DI, SI=SI+1, DI=DI+1

lea dx,cad1 ;Imprimir Cad1 en pantalla

mov ah,09h ;

int 21h ;

lea dx,cad2 ;Imprimir Cad2 en pantalla

mov ah,09h ;

int 21h ;

mov ax,4c00h ;Terminal programa y regresar al DOS

int 21h ; END inicio END

.COMMENT Programa: Cad2.ASM

Descripción: Este programa demuestra la diferencia entre el uso de MOVSB y MOVSW.

El programa debe copiar Cad3 dentro de Cad1 usando 18 repeticiones con MOVSB, después realiza lo mismo con Cad4 y Cad2 pero usando solo nueve repeticiones de la instrucción MOVSW.

El resultado es el mismo en ambos casos

.MODEL tiny

.DATA

cad1 db 'Cadena de prueba1 ','$' cad2 db 'Cadena de prueba2 ','$' cad3 db 18 dup (' ')

cad4 db 18 dup (' ')

.CODE

inicio: ;Punto de entrada al programa

cld ;procesamiento de izq->der. mov cx,18 ;Longitud de la cadena lea si,cad3 ;DS:SI->Cad3

lea di,cad1 ;ES:DI->Cad1 rep movsb ;Cad3->Cad1

mov cx,9 ;Longitud de la cadena por pares de bytes

lea si,cad4 ;DS:SI->Cad4 lea di,cad2 ;ES:DI->Cad2 rep movsw ;Cad4->Cad2 lea dx,cad1 ;

mov ah,09h ;Imprimir Cad1 int 21h ;

lea dx,cad2 ;

mov ah,09h ;Imprimir Cad2 int 21h ;

mov ax,4c00h ;Terminar programa y regresar al DOS

int 21h ; END inicio END

.COMMENT

Programa: Cad3.ASM

Descripción: Este programa muestra el uso de la instrucción LODSB.

El programa invierte el orden de los elementos de una cadena y los almacena en otra cadena que originalmente esta inicializada con espacios. Al final se imprimen las dos cadenas.

.MODEL tiny

.DATA

cad1 db 'Cadena de prueba','$'

cad2 db 16 dup (' '),'$'

.CODE

inicio: ;Punto de entrada al programa

cld ;Procesamiento de izq->der. mov cx,16 ;Longitud de la cadena lea si,cad1 ;DS:SI->Cad1

lea di,cad2+15 ;ES:DI apuntan al final del área reservada para otro: ;almacenar la cadena invertida

lodsb ;Obtener el primer carácter de Cad1

mov [di],al ;almacenarlo en la posición actual de DI

dec di ;Disminuir DI

loop otro ;Obtener siguiente carácter de Cad1

lea dx,cad1 ;

mov ah,09h ;Imprimir cadena original int 21h ;

lea dx,cad2 ;

mov ah,09h ;Imprimir cadena invertida int 21h ;

mov ax,4c00h ;Terminar programa y regresar al DOS

int 21h ; END inicio END

COMMENT Programa: Cad4.ASM

Descripción: Este programa utiliza la instrucción STOSB para rellenar un rea de memoria con el contenido del registro AL.

En este caso, el área de memoria reservado para la variable Cad1 es rellenada con el carácter

ASCII '*'.

.MODEL tiny

.DATA

cad1 db 'Cadena de prueba',13,10,'$'

CODE

inicio:

lea dx,cad1 ;Imprimir Cad1 antes de que sea borrada

mov ah,09h ;

int 21h ;

cld ;Procesamiento de izq->der

mov al,'*' ;Inicializar AL con '*'

mov cx,16 ;Longitud de la cadena que se va a rellenar lea di,cad1 ;ES:DI->Cad1

rep stosb ;Rellenar 16 bytes de memoria con '*' lea dx,cad1 ;

mov ah,09h ;Imprimir Cad1 después de ser borrada

int 21h ;

mov ax,4c00h ;Terminar programa y regresar al DOS

int 21h ;

END inicio

END

Programación de E/S

Definición de interrupción

Una interrupción es un estado en el cual el microprocesador detiene la ejecución

de un programa para atender una petición especial solicitada por el propio programa o por un dispositivo físico conectado al microprocesador externamente.

Las interrupciones fueron creadas para facilitar al programador el acceso a los diferentes dispositivos de la computadora (puertos de comunicaciones, terminales, impresoras, etc.).

Ejecución de una interrupción

Cuando durante la ejecución de un programa se produce una interrupción, el microprocesador realiza los siguientes pasos:

1.- Detiene la ejecución del programa

2.- Almacena los registros CS, IP y Banderas en la pila

3.- Modifica el CS y el IP para que apunten a la dirección donde se encuentra la rutina de interrupción.

4.- Ejecuta las instrucciones de la rutina de interrupción.

5.- Restablece usando la instrucción RETI los valores originales de los registros CS, IP y

Banderas.

6.- Continua con la ejecución del programa en el punto donde fue interrumpido.

Las rutinas se almacenan en la memoria de la computadora cada vez que ésta es inicializada, a esto se le conoce como vector de interrupciones.

Tipos de interrupciones

El microprocesador puede atender dos tipos de interrupciones: interrupciones por software e interrupciones por hardware.

Las interrupciones por software son llamadas desde los programas y son proporcionadas por el sistema operativo (MS-DOS). Existen dos tipos de estas: las interrupciones del DOS y las interrupciones del BIOS (Basic Input Output System o Sistema Básico de Entrada/Salida). Estas interrupciones son invocadas con la instrucción INT del ensamblador.

Por otro lado, las interrupciones por Hardware son proporcionadas por el propio microprocesador y también existen dos tipos: interrupciones por hardware internas y las interrupciones por hardware externas. Las interrupciones internas son invocadas por el microprocesador cuando se produce alguna operación incorrecta, como por ejemplo, un intento de dividir por cero o una transferencia de datos entre registros de diferentes longitudes.

Las interrupciones externas son provocadas por los dispositivos periféricos conectados al microprocesador. Para lograr esto, a cada dispositivo periférico se le asigna

una línea física de interrupción que lo comunica con el microprocesador por medio de un circuito integrado auxiliar, el cual se conoce como controlador programable de interrupciones (PIC).

Las computadoras basadas en el microprocesador 8086/8088 cuentan solamente con un PIC, con lo cual pueden proporcionar hasta 8 líneas de interrupción (IRQ), las cuales son llamadas IRQ0 a IRQ7, por otro lado, las computadoras basadas en el microprocesador 80286 y posteriores cuentan con dos chips controladores, con los cuales pueden proporcionar hasta un máximo de 16 líneas IRQ, las cuales son llamadas IRQ0 a IRQ15.

La siguiente es una lista de las interrupciones por software disponibles por el sistema operativo.

Interrupciones del BIOS

Manejo de dispositivos periféricos

砠 INT 10H Manejo de la pantalla.

砠 INT 13H Manejo de unidades de disco.

砠 INT 14H Manejo de los puertos de comunicaciones(RS232).

砠 INT 15H Manejo de cinta magnética.

砠 INT 16H Manejo del teclado.

砠 INT 17H Manejo de la impresora.

Manejo del estado del equipo

砠 INT 11H Servicios de la lista de elementos de la computadora.

砠 INT 12H Servicios para el cálculo del tamaño de la memoria.

Servicios de fecha y hora

砠 INT 1AH Manejo del reloj.

Impresión de pantalla

砠 INT 5H Impresión de la información contenida en la pantalla.

Servicios especiales

砠 INT 18H Activación del lenguaje Interprete Basic de la ROM.

砠 INT 19H Activación de la rutina de arranque de la computadora.

Interrupciones del DOS

砠 INT 20H Termina la ejecución de un programa.

牉NT 22H Dirección de terminación. Guarda la dirección donde se transfiere el control cuando termina la ejecución del programa.

砠 INT 23H Dirección de la interrupción que se ejecuta cuando se presiona

Ctrl-Break.

砠 INT 24H Manejo de errores críticos.

砠 INT 25H Lectura directa de sectores del disco.

砠 INT 26H Escritura directa de sectores del disco.

牉NT 27H Terminar un programa y devolver el control al DOS sin borrar el programa de la memoria.

牉NT 21H Esta interrupción proporciona una gran cantidad de funciones, las cuales deben ser invocadas en conjunto con el registro AH.

1 Terminación de un programa.

2 Entrada de carácter con eco.

3 Salida a pantalla.

4 Entrada por el puerto serie.

5 Salida por el puerto serie.

6 Salida a la impresora.

7 E/S directa por pantalla.

8 Entrada directa de carácter sin eco.

9 Entrada de carácter sin eco.

10 Visualizar cadenas de caracteres.

11 Entrada desde el teclado.

12 Comprobación del estado de entrada.

13 Borrar registro de entrada.

14 Inicializar unidad de disco.

A continuación se mostrarán algunos programas que utilizan llamadas a diferentes interrupciones por software tanto del BIOS como del DOS.

El siguiente programa utiliza la función 09h de la interrupción 21 del DOS para mostrar en la pantalla un mensaje.

.COMMENT

*

Programa: Int1.ASM

Descripción: Imprime una cadena de caracteres en la pantalla por medio de la función 09h de la interrupción 21h del DOS.

*

.MODEL tiny

.DATA

Mensaje db 'Interrupciones 21h del DOS',13,10,'$'

.CODE Inicio:

Lea DX,Mensaje

Mov Ah,09h

Int 21h

Mov ax,4C00h

Int 21h END Inicio END

El siguiente programa exhibe dos cadenas de caracteres en la pantalla, pero a diferencia del anterior éste no regresa al DOS inmediatamente, espera a que cualquier tecla sea presionada y entonces termina, para ello se utiliza la función 10h de la interrupción 16h del BIOS.

.COMMENT

*

Programa: Int2.ASM

Descripción: Imprime dos cadenas de caracteres en la pantalla por medio de la función

09h de la interrupción 21h del DOS y después espera a que una tecla sea presionada, esto por medio de la interrupción 16h del BIOS con la función 10h.

*

.MODEL tiny

.DATA

Mensaje db 'Mas interrupciones',13,10,'$' Mensaje2 db 'Presione cualquier tecla…',13,10,'$'

.CODE

Inicio:

Lea DX,Mensaje

Mov Ah,09h

Int 21h

Lea DX,Mensaje2

Mov Ah,09h

Int 21h

Mov Ah,10h

Int 16h

Mov ax,4C00h

Int 21h END Inicio END

Macros

Una de las principales desventajas de la programación en lenguaje ensamblador es la repetición constante de ciertos grupos de instrucciones. Por ejemplo el siguiente conjunto de instrucciones nos permite imprimir una variable de tipo cadena en la pantalla:

Lea DX,Cadena ;Direccionar la cadena

Mov AH,09h ;Usar la función 09h para imprimir cadenas

Int 21h ;llamada a la interrupción 21h del DOS

Si necesitamos que en nuestro programa se muestren mensajes constantemente, es obvio que debemos duplicar este conjunto de instrucciones por cada mensaje que se desea enviar a pantalla.

El principal problema que esto nos ocasiona es que el tamaño de nuestro programa crece considerablemente, y mientras más grande sea el programa, más difícil será encontrar la causa de algún error cuando éste ocurra.

La mejor solución en estos casos es el uso de las MACROS. Una macro es un conjunto de instrucciones que se agrupan bajo un nombre descriptivo (macroinstrucción) y que sólo es necesario declarar una vez (macrodefinición).

Una vez que la macro ha sido declarada, sólo es necesario indicar su nombre en el cuerpo del programa y el ensamblador se encargara de reemplazar la macroinstrucción por las instrucciones de la macro (expansión de la macro).

El formato general de una macro es el siguiente:

.MACRO Nombre [(parametro1, parametro2, etc)] INSTRUCCIONES

ENDM

Nuevamente, lo que se encuentra entre paréntesis cuadrados es opcional.

De acuerdo con esto, la macro para imprimir cadenas quedaría de la siguiente forma:

.MACRO Imprime_Cad(Cadena) Lea DX,Cadena

Mov Ah,09h

Int 21h

ENDM

Parámetros y etiquetas

Dentro de las propiedades más importantes de las macros se deben destacar la posibilidad de utilizar parámetros y etiquetas.

Los parámetros permiten que una misma macro pueda ser usada bajo diferentes condiciones, por ejemplo, se puede crear una macro para posicionar el cursor en

diferentes coordenadas de la pantalla e indicar sus coordenadas por medio de parámetros.

La siguiente macro nos muestra esta propiedad:

;Esta macro posiciona el cursor en las coordenadas que se le indican como

;parámetros. Es el equivalente al GotoXY de Pascal.

.MACRO gotoxy (x,y)

xor bh,bh ;Seleccionar página cero de video mov dl,x ;Columna

mov dh,y ;Renglón

mov ah,02h ;Función 02h para posicionar cursor int 10h ;llamada a la int 10h del BIOS

ENDM

También existen situaciones en las que los parámetros no son necesarios, es por esta razón que los parámetros son opcionales en la declaración de la macro.

;Esta macro realiza una pausa en el programa hasta que una tecla es ;presionada. Es el equivalente del readkey en Pascal.

.MACRO tecla mov ah,10h int 16h

ENDM

Por otro lado, las etiquetas también son útiles dentro de las macros. Suponga que se desea crear una macro que imprima una cadena un numero n de veces, esta macro podría ser declarada de la siguiente forma:

.MACRO Imprime_nCad (Cadena, Cuantos)

Mov CX,Cuantos ;Iniciar Contador

Lea DX,Cadena ;Direccionar la cadena que se va a imprimir

Mov Ah,09h ;Usar la función 09h Otra: ;Etiqueta interna Int 21h ;Imprimir la Cadena n veces Loop Otra ;Siguiente Impresión ENDM

Ensamble de macros

Como ya se mencionó antes, una macro es declarada una sola vez y puede ser llamada cuantas veces sea necesario dentro del cuerpo del programa.

Cada vez que el ensamblador encuentra una macroinstrucción, verifica si ésta fue declarada; si esta verificación es exitosa, el ensamblador toma las instrucciones del cuerpo de la macro y las reemplaza en el lugar donde la macro fue llamada.

El siguiente programa muestra la declaración y uso de las macros:

.COMMENT

Programa: Macros1.ASM

Descripción: Este programa muestra el uso de macros.

.MODEL TINY

; Declaración de variables

.DATA

cad db 'Ejemplo del uso de macros…',13,10,'$' cad1 db 'Presiona una tecla…','$'

cad2 db 'Ejemplo del uso de la macro gotoxy…','$'

;Aquí se declaran las macros.

;Esta macro imprime una cadena pasada como parámetro.

;Utiliza la función 09h de la Int 21h del DOS.

.MACRO imprime_cad(cadena)

lea dx,cadena mov ah,09h int 21h

ENDM

;Esta macro realiza una pausa en el programa hasta que una tecla se ;presione. Es el equivalente del readkey en Pascal.

.MACRO tecla mov ah,10h int 16h

ENDM

;Esta macro posiciona el cursor en las coordenadas que se le indican como

;parámetros. Es el equivalente al GotoXY de Pascal.

.MACRO gotoxy (x,y)

xor bh,bh mov dl,x mov dh,y mov ah,02h int 10h ENDM

;Esta macro limpia la pantalla.

;Utiliza la función 06h de la Int 10h del Bios.

.MACRO limpiar_pantalla mov ax,0600h

mov bh,17h mov cx,0000h mov dx,184fh int 10h

ENDM

;Aquí comienza el cuerpo del programa principal

.CODE

inicio: ;Declaración del punto de entrada limpiar_pantalla ;Llamada a la macro

gotoxy (0,0) ;Colocar el cursor en 0,0 imprime_cad(cad) ;Imprime el primer mensaje imprime_cad(cad1) ;Imprime el segundo mensaje

tecla ;Espera a que se presione una tecla

gotoxy (30,12) ;Colocar el cursor en 30,12 imprime_cad(cad2) ;Imprimir el tercer mensaje gotoxy (50,24) ;Colocar el cursor en 50,24 imprime_cad(cad1) ;Imprimir el segundo mensaje tecla ;Esperar por una tecla

mov ax,4c00h ;Fin del programa y regresar al DOS.

int 21h END inicio END

Ventajas y desventajas

Si bien es cierto que las macros proporcionan mayor flexibilidad a la hora de

programar, también es cierto que tienen algunas desventajas.

La siguiente es una lista de la principales ventajas y desventajas del uso de las macros.

Ventajas:

牍enor posibilidad de cometer errores por repetición.

牍ayor flexibilidad en la programación al permitir el uso de parámetros.

牃ódigo fuente más compacto.

牁l ser más pequeño el código fuente, también es más fácil de leer por otros.

Desventajas:

牅l código ejecutable se vuelve más grande con cada llamada a la macro.

牌as macros deben ser bien planeadas para evitar la redundancia de código.

PROGRAMACIÓN MODULAR

Definición de procedimientos

Un procedimiento es un conjunto de instrucciones que tienen la finalidad de ejecutar una tarea especifica dentro de un programa. Los procedimientos son muy similares a las macros.

Un procedimiento se declara una sola vez en el código fuente y cuando el programa se ensambla y ejecuta, el procedimiento se coloca en memoria para que pueda ser utilizado por el programa.

Las principales ventajas en el uso de procedimientos son: permiten una codificación más limpia y compacta, es decir el código fuente es más pequeño; también permiten el ahorro de memoria, esto es porque un mismo procedimiento puede ser llamado varias veces en el mismo programa y sólo requiere memoria una vez.

Los procedimientos tienen la desventaja de que reducen la velocidad de ejecución de los programas, esto se debe a la forma en que los procedimientos se ejecutan. A continuación se presentan los pasos necesarios para ejecutar un procedimiento:

1.- Se encuentra la llamada Call

2.- El microprocesador almacena en la Pila el contenido del IP

3.- Se coloca en el IP el valor del desplazamiento correspondiente al Procedimiento

4.- El microprocesador ejecuta las instrucciones del procedimiento

5.- El procedimiento termina cuando se encuentra la instrucción Ret

6.- Se saca de la pila el valor original del IP y se continua el flujo del programa

Un procedimiento se declara de la siguiente forma: PROC nombre

instrucción instrucción …. RET

ENDP NOMBRE

En donde PROC es una palabra reservada que indica el inicio de un procedimiento, RET es una instrucción que indica la terminación del conjunto de instrucciones de un procedimiento y finalmente ENDP es la palabra reservada para fin de procedimiento.

Paso de parámetros

Los procedimientos en lenguaje ensamblador no cuentan con un mecanismo para el paso

de parámetros; por lo cual, la única forma de lograr esto es colocando los parámetros que nos interesan en los registros de propósito general antes de que el procedimiento sea ejecutado.

El siguiente procedimiento coloca el cursor en las coordenadas establecidas en Dl y Dh. Proc GotoXY

xor bh,bh mov ah,02h int 10h

Ret

Endp GotoXY

En este ejemplo, las coordenadas XY se deben situar en el registro DX antes de que se llame al procedimiento.

Llamada a procedimientos

Los procedimientos son llamados por los programas por medio de la instrucción

CALL, seguida del nombre del procedimiento. Ejemplo:

Call GotoXY

El siguiente programa muestra la forma de pasarle parámetros a los procedimientos por medio de los registros generales. Este programa declara tres procedimientos:

GotoXY: Coloca el cursor en las coordenadas especificadas

Limpia_Pantalla: Limpia la pantalla

Imprime_Cad: Imprime una cadena en la posición actual del cursor

.COMMENT

*

Programa: Proc2.ASM

Descripción: Este programa ilustra la forma de utilizar procedimientos en los programas por medio de la instrucción Call y la forma de pasarles parámetros.

.MODEL TINY

.DATA

Cad1 db 'Esta es una cadena de prueba…',13,10,'$'

.CODE

INICIO: ;Punto de entrada al programa

Mov DL,20 ;X=20

Mov DH,10 ;Y=10

Call Gotoxy ;GotoXY 20,10

Lea DX,cad1 ;DX->Cad1

Call Imprime_Cad ;Imprimir Cad1

Mov Ax,04C00h ;Terminar y regresar al dos

Int 21h ; END INICIO

;*********************************************************************

;Procedimiento: GotoXY

;Descripción: Coloca el cursor una posición especifica de la pantalla

;Parámetros: Dl=X, Dh=Y

;********************************************************************* PROC GotoXY

Xor Bh,Bh

Mov Ah,02h

Int 10h

Ret

ENDP GotoXY

;***********************************************************************

;Procedimiento: Limpia_Pantalla

;Descripción: Imprime una cadena de caracteres en la posición del cursor

;Parámetros: La dirección de la cadena en DX

;*********************************************************************** PROC Imprime_Cad

Mov Ah,09h

Int 21h

Ret

ENDP Imprime_Cad

END

Procedimientos internos

Los procedimientos internos son aquellos que se declaran y se llaman dentro del mismo programa, también son llamados procedimientos locales.

El listado anterior muestra la forma de utilizar procedimientos internos.

Procedimientos externos

Los procedimientos externos, a diferencia de los internos, se declaran en módulos

o programas separados al programa donde el procedimiento es llamado, en otras palabras, la llamada al procedimiento se encuentra en un programa y el procedimiento en otro.

Para poder utilizar procedimientos externos, es necesario que sean declarados como públicos en el programa donde se encuentran y que sean llamados como externos en el programa donde serán usados. Para lograr esto, Pass32 cuenta con tres directivas de ensamble: .PUBLIC para declarar los procedimientos como públicos, .EXTERN para indicar que el procedimiento que se va a usar está fuera del programa y .INCLUDE para enlazar el programa que contiene los procedimientos con el programa que los llama.

El siguiente programa muestra el uso de las directivas de inclusión. Primeramente, el archivo Proc2.ASM se modificó para que su variable Cad1 fuera declarada como publica,

el programa Proc3.ASM contiene la línea .INCLUDE Proc2.ASM, lo cual indica al ensamblador que, en caso de que se soliciten datos, etiquetas o procedimientos externos, éstos se busquen en el archivo incluido.

Pass32 proporciona grandes facilidades para el manejo de procedimientos; en este caso, solamente Cad1 debe ser declarada como pública, puesto que los procedimientos se buscan y anexan automáticamente al programa que los llama si es que existen.

.COMMENT

*

Programa: Proc3.ASM

Descripción: Este programa ilustra la forma de utilizar procedimientos y datos externos en los programas por medio de las directivas de inclusión include y public.

.MODEL TINY

.INCLUDE proc2.ASM ;Incluir el archivo proc2.asm

;el cual contiene la variable de cadena

;Cad1 y los procedimientos externos

;usados en este programa.

.DATA

Cad2 db 'Esta es una cadena de prueba 2…',13,10,'$'

.CODE

INICIO: ;Punto de entrada al programa

Mov Dl,20 ;X=20

Mov Dh,10 ;Y=10

Call GotoXY ;GotoXY 20,10

Lea DX,Cad2 ;DX->Cad2 en Proc3.asm

Call Imprime_Cad ;Imprime Cad2

Lea DX,Cad1 ;DX->Cad1 en Proc2.asm

Call Imprime_Cad ;Imprime Cad1

Mov AX,04C00h ;Fin del programa

Int 21h ; END INICIO END

Con estas capacidades, es fácil crear bibliotecas de procedimientos y macros que puedan ser utilizados constantemente por los demás programas, ahorrando con ello tiempo de programación al reutilizar código fuente.

El siguiente programa muestra la forma de escribir una biblioteca de procedimientos y la forma de utilizarlos en los programas.

.COMMENT

*

Programa: Proc3.ASM

Descripción: Este programa ilustra la forma de utilizar procedimientos y datos externos

en los programas por medio de las directivas de inclusión include y public.

.MODEL TINY

.INCLUDE proclib.inc ;Incluir el archivo proclib.inc

;el cual contiene la variable de cadena

;Cad1 y los procedimientos externos

;usados en este programa.

.DATA

Cad1 db 'Esta es una cadena de prueba 2…',13,10,'$' Cad2 db 'Presiona una tecla…','$'

.CODE

INICIO: ;Punto de entrada al programa

Call limpia_Pantalla ; Mov Dl,20 ;X=20

Mov Dh,10 ;Y=10

Call GotoXY ;GotoXY 20,10

Lea DX,Cad1 ;DX->Cad1

Call Imprime_Cad ;Imprime Cad1

Mov Dl,40 ; Mov Dh,24 ;

Call GotoXY ;GotoXY 40,25

Lea DX,Cad2 ;

Call Imprime_Cad ;Imprime Cad2

Call Espera_Tecla ;Esperar por una tecla presionada

Mov AX,04C00h ;Fin del programa

Int 21h ;

END INICIO END

.COMMENT

Biblioteca de Procedimientos en Lenguaje ensamblador

.CODE

;*********************************************************************

;Procedimiento: GotoXY

; Descripción: Coloca el cursor una posición especifica de la pantalla

; Parámetros: Dl=X, Dh=Y

;********************************************************************* PROC GotoXY

Xor Bh,Bh

Mov Ah,02h

Int 10h

Ret

ENDP GotoXY

;***********************************************************************

;Procedimiento: Imprime_Cad

; Descripción: Imprime una cadena de caracteres en la posición del cursor

; Parámetros: La dirección de la cadena en DX

;***********************************************************************

PROC Imprime_Cad

Int 21h

Ret

ENDP Imprime_Cad

;**********************************************************************

;Procedimiento: Limpia_Pantalla

; Descripción: Limpia la pantalla de la computadora y coloca el cursor

; en 0,0.

; Parámetros: Ninguno

;********************************************************************** PROC Limpia_Pantalla

mov ax,0600h

mov bh,17h mov cx,0000h mov dx,184fh int 10h

Mov dx,0000h Call Gotoxy Ret

ENDP Limpia_Pantalla

;**********************************************************************

;Procedimiento: Espera_Tecla

; Descripción: Detiene la ejecución de un programa hasta que se presiona

; una tecla

; Parámetros: Ninguno

;********************************************************************** PROC Espera_Tecla

mov ah,10h int 16h

Ret

ENDP Espera_Tecla

PROGRAMACIÓN HÍBRIDA Pascal y ensamblador

Como ya se mencionó, la programación en lenguaje ensamblador proporciona un mayor control sobre el hardware de la computadora, pero también dificulta la buena estructuración de los programas.

La programación híbrida proporciona un mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje ensamblador y los lenguajes de alto nivel, todo esto con el fin escribir programas más rápidos y eficientes.

En esta sección se mostrará la forma para crear programas híbridos utilizando el lenguaje ensamblador y Turbo Pascal.

Turbo Pascal permite escribir procedimientos y funciones en código ensamblador e incluirlas como parte de los programas en lenguaje Pascal; para esto, Turbo Pascal cuenta con dos palabras reservadas: Assembler y Asm.

Assembler permite indicarle a Turbo Pascal que la rutina o procedimiento que se está escribiendo está totalmente escrita en código ensamblador.

Ejemplo de un procedimiento híbrido: Procedure Limpia_Pantalla;

Assembler; Asm

Mov AX,0600h Mov BH,18h Mov CX,0000h Mov DX,184Fh Int 10h

End;

El procedimiento del listado 23 utiliza la función 06h de la Int 10h del BIOS para limpiar la pantalla, este procedimiento es análogo al procedimiento ClrScr de la unidad CRT de Turbo Pascal.

Por otro lado, Asm nos permite incluir bloques de instrucciones en lenguaje ensamblador en cualquier parte del programa sin necesidad de escribir procedimientos completos en ensamblador.

Ejemplo de un programa con un bloque de instrucciones en ensamblador:

{ Este programa muestra como se construye un programa híbrido utilizando un bloque Asm… End; en Turbo Pascal.

El programa solicita que se introduzcan dos número, después calcula la suma por medio de la instrucción Add de ensamblador y finalmente imprime el resultado en la

pantalla.}

Program hibrido; Uses Crt;

Var

N1,N2,Res : integer; Begin

Writeln("Introduce un número: ");

Readln(N1);

Writeln("Introduce un número: "); Readln(N2);

Asm

Mov AX,N1; Add AX,N2; Mov Res,AX End;

Writeln("El resultado de la suma es: ",Res); Readln;

End.

El programa del listado 24 realiza la suma de dos cantidades enteras (N1 y N2) introducidas previamente por el usuario, después almacena el resultado en la variable Res y finalmente presenta el resultado en la pantalla.

El lenguaje ensamblador no cuenta con funciones de entrada y salida formateada, por lo cual es muy complicado escribir programas que sean interactivos, es decir, programas que soliciten información o datos al usuario. Es aquí donde podemos explotar la facilidad de la programación híbrida, en el programa anterior se utilizan las funciones Readln y Writeln para obtener y presentar información al usuario y dejamos los cálculos para las rutinas en ensamblador.

En el siguiente listado nos muestra la forma de escribir programas completos utilizando procedimientos híbridos.

{Este programa solicita al usuario que presione alguna tecla, cuando la tecla es presionada, ésta se utiliza para rellenar la pantalla.

El programa termina cuando se presiona la tecla enter. El programa utiliza tres procedimientos:

Limpia_Pantalla: Este se encarga de borrar la pantalla

Cursor_XY: Este procedimiento reemplaza al GotoXY de Pascal

Imprime_Car: Este procedimiento imprime en pantalla el carácter que se le pasa como parámetro. }

Program Hibrido2; Uses Crt;

Var

Car: Char;

i,j : integer;

{Este procedimiento limpia la pantalla y pone blanco sobre azul} Procedure Limpia_Pantalla;

Assembler;

Asm

Mov AX,0600h Mov Bh,17h Mov CX,0000h Mov DX,184Fh Int 10h

End;

{Este procedimiento imprime el carácter en la pantalla} Procedure Imprime_Car(C: Char);

Assembler; Asm

Mov Ah,02h

Mov Dl,C Int 21h End;

{Este procedimiento tiene la misma función que el procedimiento GotoXY de Turbo

Pascal}

Procedure Cursor_XY(X,Y: Byte);

Assembler; Asm

Mov Ah,02h

Mov Bh,00h Mov Dh,Y Mov Dl,X

Int 10h End; Begin

Limpia_Pantalla; Repeat Limpia_Pantalla; Cursor_XY(0,0);

Write('Introduce un carácter: '); Car:=ReadKey; Imprime_Car(Car); Limpia_Pantalla;

If car <> #13 then

Begin

For i:=0 to 24 do For j:=0 to 79 do Begin Cursor_XY(j,i); Imprime_Car(Car); End; Cursor_XY(30,24);

Write('Presiona enter para salir u otro para seguir…'); Readln;

Until car = #13; End.

Conclusión

Quizá el lenguaje ensamblador es el lenguaje de programación mas difícil de comprender, pero en la actualidad es una de las herramientas de programación más utilizadas para obtener un mayor conocimiento acerca del funcionamiento de una computadora personal y programar determinados dispositivos.

Las personas que deseen hacer uso de este lenguaje deberán tener un nivel de comprensión alto ya que como se menciono este lenguaje no es tan fácil, por lo que deberán poner gran empeño para el aprendizaje.

Existe en la actualidad una gran cantidad de programas ensambladores que nos permiten programar en ambientes operativos gráficos como Windows 95/98, Windows NT y Linux.

Aunque algunas personas piensan que el uso de este lenguaje esta ya obsoleto están muy equivocados, hoy en dia existen en internet infinidad de paginas que presentan información acerca de este tema (como es nuestro caso) y que se actualizan diariamente, no por algo existen estas paginas, es decir , si encontramos tanta cantidad de información es por que todavía esta en uso.

Bibliografía

Abel, P.; Lenguaje Ensamblador para IBM PC y Compatibles; Ed. Prentice Hall; 3ª Edición; 1996.

Brey, B.; Los microprocesadores de Intel: Arquitectura, Programación e Interfaces; Ed. Prentice Hall;

3ª Edición; 1995.

Caballar, J.; El libro de las comunicaciones del PC: técnica, programación y aplicaciones; Ed. Rama-Computec; 1ª Edición; 1997.

Morgan y Waite; Introducción al microprocesador 8086/8088; Ed. Byte Books/Mc Graw Hill; 1ª Edición; 1992.

Pawelczak; Pass32 32 bit Assembler V 2.5 Instruction Manual; 1997. Rojas, A.; Ensamblador Básico; Ed. Computec; 2ª Edición; 1995.

Socha y Norton; Assembly Language for the PC; Ed. Brady Publishing; 3ª Edición; 1992.

Tannenbaum, A.; Organización de Computadoras un enfoque estructurado; Ed. Prentice Hall; 3ª Edición; 1992.

http://www.cryogen.com/Nasm http://www.geocities.com/SiliconValley/Bay/3437/index.html

 

 

Autor:

Alva Hilario Gustavo Becerril López Nancy Cruz Matias Deisy

Gonzalez Maldonado Martha Yareli Romero Ortega Francisco Javier Sanchez Cruz Gustavo

JOCOTITLÁN MÉXICO, 15 DE ABRIL DE 2008

Partes: 1, 2, 3
 Página anterior Volver al principio del trabajoPágina siguiente