Empecemos por el salto sin condiciones, con el que podremos cambiar el control a cualquier punto del programa.
Sería como el “Goto” del Basic, símplemente transferir el control a otro punto del programa. La orden es
JMP ( de Jump, salto )
Si record is a ‚stas alturas los registros CS:IP, se podra ver que‚ es lo que hace realmente la instrucción, y no es mas que incrementar o decrementar IP para llegar a la zona del programa a la que queremos transferir el control ( IP es el Offset que indica la zona de memoria que contiene la siguiente instrucción a ejecutar, y CS el segmento )
El formato mas sencillo para el salto sería JMP 03424h, lo que saltaría a esa zona.
Pero es digamos que “algo pesado” calcular en que‚ dirección va a estar esa instrucción, con lo que utilizaremos etiquetas. Aquí hay un ejemplo, en el que de paso se repasa un poco:
MOV AX,0CC34h
MOV CL,22h
JMP PALANTE
VUELVE: CMP BX,AX
JMP FIN
PALANTE: MOV BX,AX
JMP VUELVE
FIN: XOR CX,CX
Ahora voy a comentar un poco el programa. Tras la primera instrucción, AX vale 0CC34h, y tras la segunda, CL vale 22h. Despues se realiza un salto a la instrucción etiquetada con “PALANTE”.
La etiqueta ha de estar continuada por dos puntos ‘:’, y puede ser llamada desde cualquier lugar del programa. Tambi‚n podremos hacer un MOV AX,[PALANTE], como hacíamos antes con un MOV AX,[BX], pero asignando a AX el valor que haya en la dirección en la que esta “PALANTE”.
El caso, que tras el salto a “PALANTE”, se copia el valor del registro BX en AX, y se vuelve a “VUELVE”. Se realiza una comparación entre AX y BX, que pondr el flag de cero a 1 ( recordemos la anterior lección ), se saltar a “FIN”, donde tan sólo se realizar la orden Xor CX,CX cuyo resultado, por cierto, es poner CX a cero tenga el valor que tenga ( y esto se utilizar bastante programando, por eso me ha dado por incluir la orden )
Volvamos con la sintaxis del JMP con algunos ejemplos de como utilizarlo:
JMP 100h
Salta a la dirección 100h. Un archivo .COM comienza normalmente en esa
dirección, así que quiz lo ve is en algunos virus.
JMP 542Ah:100h
Salta a la dirección 100h pero del segmento 542Ah. ¨ Os acord is aún
de los Segments y Offsets ?. Se trata de un salto lejano.
JMP SHORT 223Ah
Salto corto a la dirección 223Ah. Tranquilidad, ahora explico lo de salto
corto, lejano,…
JMP NEAR 55AAh
Salto cercano, es diferente al corto
JMP [100h]
Salta a la dirección contenida en 100h. Sin embargo es un error, ya que
no se especifíca si es cercano, lejano, si se lee un sólo byte,… o sea,
que ‚sta instrucción no vale.
JMP WORD PTR [BX]
Ahora si vale ;). Salta a la dirección contenida en la palabra ( dos
bytes ) a la que apunta BX. O sea, si BX valiese 300h y en 300h los dos
bytes fuesen 0CC33h, el JMP saltaría a ‚sta dirección.
JMP DWORD PTR [BX+SI+5]
Dword son 32 bits, o sea, un salto lejano. Y saltaría al contenido en
la dirección de memoria a la que apuntan la suma de BX,SI y 5.
Ahora voy a contar algo sobre los saltos lejanos, cercanos y cortos. El
salto corto se realiza entre el punto en el que se est y +127 o −128, o
sea, que la cantidad que se puede contener en un byte con signo. A veces
es necesario indicar que se trata de salto corto, cercano o lejano.
El salto cercano se realiza contando como distancia el contenido de dos
bytes, o sea, que el rango sería desde 32767 a −32768 bytes de distancia.
Y el lejano se realiza contando como distancia el contenido de cuatro
bytes, y,… paso de calcular la distancia, pero es mucha X-)
Por ejemplo, es incorrecto que haya en la dirección 100h una instrucción
que diga JMP SHORT 500h, ya que la distancia no corresponde a un salto
corto. Adem s, el salto dependiendo de que sea cercano, corto o largo se
codifica de manera diferente en modo hexadecimal.
SALTOS CONDICIONALES
¨ Record is aquel IF-THEN-ELSE, o el FOR, o el WHILE-DO ?
Bien, pues aquí est lo que suple a ‚stas instrucciones en lenguaje
ensamblador. Se basan compl‚tamente en los flags, por ello el rollo de la
anterior lección, pero est n simplificados de tal manera que no os har
falta sab‚roslos de memoria para poder hacerlos.
Los saltos podrían resumirse en un modo “Basic” de la manera IF-THEN-GOTO
de tal manera que cuando se cumple una condición se salta a un sitio
determinado.
He aquí los tipos de saltos condicionales ( las letras en mayúsculas son
las instrucciones ):
JO: Jump if overflow. Salta si el flag de desbordamiento est a uno
JNO: Jump if not overflow. Salta si el flag de desbordamiento est a
cero.
JC, JNAE, JB: Los tres sirven para lo mismo. Significan: Jump if Carry,
Jump if Not Above or Equal y Jump if Below. Saltan por lo tanto si al
haber una comparación el flag de acarreo se pone a 1, es entonces
equivalente a < en una operación sin signo. Vamos, que si se compara así:
CMP 13h,18h, saltar , ya que 13h es menor que 18h. Tambi‚n se suelen usar
para detectar si hubo fallo en la operación, ya que muchas interrupciones
al acabar en fallo encienden el carry flag.
JNC, JAE, JNB: Otros tres que valen ex ctamente para lo mismo. Jump if
not Carry, Jump if Above or Equal y Jump if Not Below. Saltan por tanto si
al haber una comparación el flag de acarreo vale 0, o sea, es equivelente
al operador >=. En la comparación CMP 0,0 o CMP 13h,12h saltar , ya que el
segundo operando es MAYOR O IGUAL que el primero.
JZ o JE: Jump if Zero o Jump if Equal. Salta si el flag de cero est a
1, o sea, si las dos instrucciones comparadas son iguales. Saltaría en el
caso CMP 0,0
JNZ o JNE: Jump if Not Zero o Jump if Not Equal. Salta si el flag de cero
est a 0, o sea, si las dos instrucciones comparadas no son iguales.
JBE o JNA: Jump if Below or Equal o Jump if Not Above. Saltaría si en
resultado de la comparación el primer miembro es menor o igual que el
segundo ( <= )
JA o JNBE: Jump if Above o Jump if Not Below of Equal. Justo lo contrario
que la anterior, salta si en el resultado de la comparación el primer
miembro es mayor al segundo.
JS: Jump if Sign. Salta si el flag de signo est a uno.
JNS: Jump if Not Sign. Salta si el flag de signo est a cero.
JP, JPE: Jump if Parity o Jump if Parity Even. Salta si el flag de
paridad est a uno.
JNP, JPO: Jump if Not Parity, Jump if Parity Odd. Salta si el flag de
paridad est a cero.
JL, JNGE: Jump if Less, Jump if Not Greater of Equal. Salta si en el
resultado de la comparación, el primer número es inferior al segundo, pero
con números con signo.
JGE, JNL: Jump if Greater or Equal, Jump if Not Less. Salta si en el
resultado de la comparación, el primer número es mayor o igual que el
segundo, pero con números con signo.
JLE, JNG: Jump if Lower or Equal, Jump if Not Greater. Salta si en el
resultado de la comparación, el primer número es menor o igual que el
segundo, pero con números con signo.
JG, JNLE: Jump if Greater, Jump if Not Lower or Equal. Salta si en el
resultado de la comparación, el primer número es mayor que el segundo, para
números con signo.
Fiuuuuu !!! Menuda lista. Bueno, aconsejo que os qued‚is de cada
parrafito con uno, aunque algunos se usen poco, pero como veis para una
misma instrucción hay varios,… y para gustos no hay nada escrito, lo mismo
os da usar JG que JNLE por ejemplo.
Vamos, que despu‚s de toda ‚sta aridez me temo que voy a tener que poner
algunos ejemplos de los m s utilizados:
MOV AX,1111h
MOV BX,1112h
CMP AX,BX ; AX es menor que BX ( toma perogrullada )
JB tirapalante ; Saltar a tirapalante
HLT ; Esta orden bloquea el ordenador, halt
tirapalante: DEC BX ; Ahora BX valdr 1111h
CMP AX,BX ; Ahora valen igual
JNE Acaba ; No saltar , ya que son iguales
JE Continua ; Esta vez si
Continua: DEC BX ; Ahora BX vale 1110h
CMP AX,BX
JE Acaba ; No son iguales, por tanto no saltar
JB Acaba ; No es menor, tampoco salta
JG Acaba ; Es mayor, ahora SI saltar
Acaba: XOR AX,AX
XOR BX,BX ; AX y BX valen ahora cero.
Espero que con ‚sto haya aclarado un poco la utilidad de los saltos.
Evidentemente, ahora al escribir sabemos cuando uno es menor o mayor, pero
a veces mediante interrupciones sacaremos valores que no conoceremos al ir
a programar, o quiz lo hagamos de la memoria, y querremos comprobar si
son iguales, etc‚tera.
Por cierto, que en los saltos condicionales se puede hacer como en los
incondicionales, o sea, formatos como:
JE 0022h
JNE 0030h
JNO AL
Sin embargo, estamos limitados a saltos cortos, o sea, de rango a 127
bytes hacia adelante o 128 hacia atr s, no pudiendo superar ‚sta distancia.
BUCLES
He aquí el equivalente al FOR-TO-NEXT en ensamblador, se trata de la
orden LOOP. Lo que hace ‚sta orden es comparar CX con cero; si es igual,
sigue adelante, si no lo es, vuelve al lugar que se indica en su operando
decrementando CX en uno. Por lo tanto, CX ser un contador de las veces
que ha de repetirse el bucle. Vamos con un ejemplo:
MOV CX,0005h
bucle: INC DX
CMP DX,0000h
JE Acaba
LOOP bucle
Acaba: …
Veamos como funciona ‚ste programa. Se mueve a CX el valor 5h, que van
a ser las veces que se repita el bucle. Ahora, llegamos al cuerpo del bucle.
Se incrementa DX y se compara con 0, cuando es igual salta a “Acaba”. Si
llega a la orden LOOP, CX se decrementar y saltar a bucle. Esto se
repetir cinco veces. En fin, que el programa acabar en el grupo de
instrucciones de “Acaba” cuando la comparación de un resultado positivo o
cuando el bucle se haya repetido cinco veces.
Tambi‚n tiene la limitación de que sólo realiza saltos cortos, y tambi‚n
puede usarse como el JMP, de la forma:
LOOP 0003h
LOOP [AL]
En resumen, la orden LOOP es la equivalente a CMP CX,0/JNZ par metro,
donde par metro es el operando de LOOP.
Y en fin, hemos terminado con los condicionales. Parece muy rido, pero
luego seguramente usar‚is poco m s que un JZ o JNZ al principio,… y el
LOOP, claro. Ya no nos queda mucho. La explicación de la pila y las
interrupciones, y ya podr‚is empezar a programar.’