Bueno, pues parece que nos vamos acercando al final,... ahora voy a
contar con algo de detalle del resto de las órdenes en lenguaje ensamblador
las m s importantes y que m s merezcan conocerse:
XCHG
La función de xchg es la de intercambiar valores entre registros y
memoria, de tal manera que puede funcionar así:
XCHG reg,reg ( XCHG AX,BX )
XCHG mem,reg o reg,mem ( XCHG AX,Word ptr 0000:0084h )
LEA
"Load Effective Adress", sirve al usar como puntero a DX ( recordemos,
al hacer que apuntase hacia un offset que nos interesaba ), y como
sustituyente al MOV en ‚stos casos especialmente.
Imaginemos que el offset al que queremos apuntar es Sunset+bp-si, o sea,
el lugar donde est la etiqueta "Sunset" m s el valor de bp menos el de si.
Si lo hiciesemos con movs quedaría tal que así:
MOV dx,Offset sunset
ADD dx,bp
SUB dx,si
La órden LEA integra ‚stas operaciones:
LEA dx,[Sunset+Bp-Si]
Pudiendo usar en el operando cualquier dirección de memoria y pudiendo
sum rsele registros.
LDS y LES
El puntero anteriormente utilizado nos puede servir mucho si lo que
pretendemos localizar se halla en el mismo segmento que el programa,... pero
si est en otro lugar, tendremos tambi‚n que averiguar de alguna manera su
segmento. Para ‚sto se usan LDS y LES.
Teniendo la misma sintaxis que LEA, aunque pudiendo poner un registro
de segmento ( pej, Lea SI,CS:[DI+3] ), sus resultados los ligeramente diferentes.
Adem s de ponerse en el operando destino ( SI en el ejemplo anterior ) el
Desplazamiento u Offset, el Segmento indicado en el operando origen quedar
en DS o ES según la órden sea LDS o LES.
Por ejemplo, si hacemos:
LDS DX,0000:[DI-23]
En DX quedar la dirección a la que apunta DI-23, y en DS quedar 0000,
el segmento en que se encuentra.
Igualente suceder en ES:
LES SI,3342h:[Bp]
SI valdr BP, y ES tomar el valor de 3342h.
DELAYs
A veces nos puede interesar perder algo de tiempo, y ‚sta órden tiene
adem s luego m s utilidades,... es la órden REP ( repeat ). Se repite, y
cada vez que lo hace disminuye CX en una unidad. Se usa especialmente para
órdenes como Movsb, etc, que vienen ahora. Pero símplemente que entend is
que si hago:
Mov CX,300h
Rep
La órden rep se repite 300h veces, y cuando la supera CX vale 0.
INSTRUCCIONES DE CADENA
Son un subconjunto de instrucciones muy útiles para diversas funciones:
inicializar zonas de memoria, copiar datos de una zona a otra, encontrar
valores determinados o comparar cadenas, etc etc.
Su comportamiento depende del flag de dirección del que habl bamos unas
lecciones m s atr s, y que se puede cambiar dir‚ctamente con ‚stas dos
instrucciones:
STD: SeT Direction flag, lo pone a uno.
CLD: CLear Direction flag, lo pone a cero.
Las instrucciones que vamos a usar como de cadena siempre tienen una S
de String al final, y casi siempre adem s una B o una W indicando Byte o
Word ( el tama¤o ). Es tan común el uso de la B o la W que siempre lo
pondr‚ así ( es mejor especificar para prevenir posibles fallos )
Y ‚stas son:
LODSB/LODSW
Lee un byte/palabra en la dirección de memoria dada por DS:SI y la
almacena dependiendo de su tama¤o en AL o AX. Si el flag de dirección est
a cero, según sea byte o palabra, SI aumentar en 1 o 2 unidades ( para
poder continuar la operación de lectura ). Si est a uno el flag, se
decrementar en 1 o 2 unidades dependiendo del tama¤o ( byte/palabra )
STOSB/STOSW
Es el equivalente a "grabar" si lo anterior era "cargar". Almacenar el
contenido de AL o AX ( como siempre, dependiendo del tama¤o ) en ES:DI,
copiando según si es B o W uno o dos bytes cada vez que se ejecute.
Si el flag de dirección est a cero, DI aumentar cada vez que se
realice la órden en una o dos unidades ( dependiendo tel tama¤o, B o W ).
Si est a uno, decrecer .
MOVSB/MOVSW
Mueve el byte o palabra contenido en la dirección de memoria a la que
apunta DS:SI a la dirección de memoria de ES:DI.
Si el flag de dirección est a 0, con cada MOVS que realicemos SI y DI
aumentar n en una unidad ( MOVSB ) o dos ( MOVSW ). Si est a uno, se
decrementar n de igual manera.
REP
Acabo de hablar sobre ‚l,... pues bien, si se utiliza como operando suyo
una de ‚stas órdenes, la repetir CX veces. Por ejemplo, si queremos
copiar digamos la tabla de vectores de interrupción a un lugar que hemos
reservado:
cld ; A asegurarnos de que el flag de dirección est‚
;a cero.
mov cx,400h
xor dx,dx ; pone dx a 0
push dx
pop ds ; No est permitido hacer xor ds,ds, por lo que
;metemos dx, que vale 0, en la pila, y sacamos
;DS valiendo 0.
xor si,si ; SI que valga 0.
push cs
pop es ; Vamos a asegurarnos de que ES valga CS, o sea,
;el segmento en el que est el programa ahora.
mov di,buffer ; DI apunta al lugar donde vamos a guardar la
;tabla.
rep movsb ; Repite ‚sto 400h veces, y cada vez que lo hace
;incrementa DI y SI.
int 20h ; Acaba la ejecución
buffer: db 400h dup (?) ; Esto deja un espacio de 400h bytes que nos
;va a servir para almacenar la tabla de
;vectores de interrupción.
Bueno, pues espero que con ‚ste programa ejemplo quede todo clarito :))
Por supuesto, es muy mejorable. Podemos para empezar reducir el 400h a 200h
en CX, y hacer un rep movsw, con lo que trasladar‚mos de palabra en palabra
las instrucciones.
DATOS
Acabamos de ver algo nuevo, ¨ qu‚ significa eso de 'db' que aparece en
el anterior problema ?
El objetivo de ‚sta orden, al igual que DW o DD es dejar espacio para
datos en una determinada zona del programa, o introducirlos ahí. Voy a
mostrar algunos ejemplos:
db 'A saco con todos$'
DB se refiere a un byte de longitud, y se usa por ejemplo para guardar
una cadena. Ver‚is que pongo un $ al final de la cadena, bien, ‚sto ha
de hacerse siempre, ya que al utilizar interrupciones para mostrar una
cadena de caracteres por pantalla, el ordenador lee desde el punto
indicado hasta el $, que es cuando se para.
dw 0ffffh ; W de word, palabro... almacena un número en
;esa posición
db 'A',' ','s','a','c','o' ; Variaciones sobre el tema, va
;presentandolo car cter a car cter.
db dup 5 (90h)
A ver, que ‚sto ha sido m s raro, ¨ verdad ?. Significa que repite 5
veces el car cter o número que hay entre par‚ntesis, o sea, que ‚sto
colocaría cinco '90h' en ese sitio.
dw dup 300h (?)
Deja un espacio de trescientas palabras ( seiscientos bytes ) para
poder almacenar cosas. Su contenido no tiene importancia, se trata de
lugar de almacenamiento ( como el lugar en el que copiabamos la tabla de
vectores en el ejercicio anterior )
Tambi‚n existe DQ, Define Quadword. Os dejo que imagin‚is ;)
ACCESO A PUERTOS I/O
Símplemente describir‚ las instrucciones que permiten mandar y recibir
datos de ellos; IN y OUT.
Los puertos son todos de ocho bits, aunque se pueden usar palabras para
su lectura. Existen 64K puertos, o sea, el valor m ximo de cualquier registro de
Offset.
IN lee un byte o una palabra del puerto y lo almacena en AX/AL, tal que
así:
IN AL,DX ; Lee del puerto DX y almacena en AL
IN AX,DX ; Lee de DX y almacena en AL el valor, leyendo
;AH desde el puerto DX+1
DX es lo único que puede variar siendo otro registro, no se permite en
AX/AL
OUT manda un byte al puerto, pudi‚ndose hacer así ( mediante el registro
AX o AL ):
OUT DX,AL ; Al puerto DX, manda el valor contenido en AL
OUT DX,AX ; A DX manda el contenido de AL, y despu‚s en
;el puerto DX+1 envía AH. Observese ‚sta
;peculiaridad tanto aquí como en el anterior.
Como antes, AL o AX no pueden ser otra cosa, DX podría si ser otro
registro ( o dir‚ctamente un número )
ANULACION DE INTERRUPCIONES
Hay veces que necesitamos que mientras se est ejecutando nuestro
código no se puedan ejecutar interrupciones, debido a que estamos haciendo
algo delicado, como por ejemplo tocando la tabla de vectores de
interrupción, y no queremos que se ejecute una interrupción que tenemos
a medio cambiar.
No tendremos m s que poner la órden
CLI
O CLear Interrupts, que lo que hace es que hasta que encuentre una órden
STI ( SeT Interrupts ), no se puedan ejecutar interrupciones.
Y bueno, ‚sto casi se ha acabado !. Sólo faltan las estructuras de
COM y EXE para que pod is empezar a programar, que consig is un programa
ensamblador ( Tasm, A86, Masm,... recomiendo el primero ), y que pill‚is
las Interrupciones de Ralph Brown ( ¨ que no las encuentras, si est n en
todos lados ! ? ), y ale, a hacer cosas ;D