Instrucciones básicas del X86
Instrucciones básicas 8086
Este listado no pretende ser un substituto del manual Intel de instrucciones del 8086 -del que fervientemente recomiendo una minuciosa lectura una vez que haya comprendido bien esto- sino la más breve descripción posible para poder avanzar un poco más en los aspectos más básicos que se precisan para comprender el tutorial de lenguaje Assembly de +gthorne. Esta es una lista completa de instrucciones 8086 a las que sólo le faltan las instrucciones ESC, LOCK y WAIT, que no son útiles a nuestros fines inmediatos.
En la siguiente tabla se muestran encolumnados los Mnemónicos (como MOV), los operandos (como fuente, destino) y la descripción de la operación. Los operandos son combinaciones entre tipos (registro, memoria e inmediato) con los direccionamientos admitidos en cada instrucción. Las instrucciones IN y OUT admiten un cuarto tipo de operando: puertos de I/O, con direccionamiento registro o inmediato.
Instrucciones de movimientos de datos
-----------------------------------------------------------------------------------------------
MOV destino,fuente
;la única instrucción que utiliza todos los tipos de direccionamiento
XCHG destino,fuente
;Intercambia los contenidos de destino y fuente
XLAT tabla_fuente
;carga el registro AL con el byte direccionado por (BX+AL)
LAHF
;carga las flags S, Z, A, P y C en AH
SAHF ;guarda AH en el registro de flags
LDS destino,fuente
;transfiere un puntero de 32 bits al registro DS y al registro destino
LES destino,fuente
;transfiere un puntero de 32 bits al registro ES y al registro destino
LEA destino,fuente
;transfiere el offset de fuente (una dirección) a destino (un registro)
PUSH fuente
;guarda fuente en el stack (en la dirección SS:SP)
POP destino
;recupera del stack (dirección SS:SP-1) y guarda en registro destino
PUSHF
;almacena el registro de flags en/desde el stack
POPF ;recupera el registro de flags en/desde el stack
USHA
; almacena los reg DI,SI,BP,SP,BX,DX,CX,AX en/desde el stack
POPA ;recupera los reg DI,SI,BP,SP,BX,DX,CX,AX en/desde el stack
IN origen
;carga desde un puerto origen un byte o word en AL o AX
OUT destino
;escribe Al o AX en el puerto destino (direccionam. inmediato o DX)
Operaciones aritméticas
ADD destino,fuente
;suma fuente + destino y guarda el resultado en destino
ADC destino,fuente
;suma fuente + destino + Carry y guarda el resultado en destino
SUB destino,fuente
;resta destino - fuente y guarda el resultado en destino
SUB destino,fuente
;resta destino - fuente - Carry y guarda el resultado en destino
MUL fuente
;multiplica AL o AX * fuente y guarda el resultado en DX:AX
IMUL fuente
;igual que la anterior pero con numeros enteros con signo
DIV fuente
;divide DX:AX / fuente y guarda cociente en AX y resto en DX
IDIV fuente
;igual que la anterior pero con numeros enteros con signo
AND destino,fuente
;opera destino AND fuente y guarda resultado en destino
OR destino,fuente
;opera destino OR fuente y guarda el resultado en destino
XOR destino,fuente
;opera destino XOR fuente y guarda el resultado en destino
NOT destino
;el NOT cambia todos los 1 en 0 y los 0 en 1 de destino.
NEG destino
;NEG realiza el complemento a 2 de destino
INC destino
;Incremente an 1 el contenido de destino
DEC destino
;Decrementa en 1 el contenido de destino
DAA / DAS
;Efectúa el ajuste decimal en suma / resta del registro AL
AAA/AAD/ AAM/AAS
;ajustan el registro AL a valor decimal desempaquetado (para aplicar en operaciones suma, resta, multiplicación y división)
Instrucciones de rotación
RCL destino,contador
;rota destino a traves de carry a la izquierda contador veces
RCR destino,contador
;rota destino a traves de carry a la derecha contador veces
ROL destino,contador
;rota destino a la izquierda contador veces
ROR destino,contador
;rota destino a la derecha contador veces
SAL destino,contador
;desplaza destino a la izquierda contador veces y rellena con ceros
SAR destino,contador
;desplaza destino a la derecha contador veces y rellena con bit SF
SHR destino,contador
;desplaza destino a la derecha contador veces y rellena con ceros
NOTAS SOBRE INSTRUCCIONES DE ROTACIÓN
El bit SF (signo) es el que está más a la izquierda : si destino es operando es de 8 bits "SF" es el bit número 7 y si destino es un operando de 16 bits, es el bit número 15
En el procesador 8086 se permite un dato inmediato en lugar de especificar un registro como contador solo si ese dato inmediato es 1. Por lo tanto, para uno de esos procesadores la instrucción RCL AX,1 es válida mientras que la RCL AX,5 no lo es. A partir de 80286 se puede especificar cualquier numero de rotaciones como dato inmediato. Como DEBUG presupone 8086, cualquier valor inmediato distinto de 1 da error.
Si en un programa para 8086 se desean rotar más de un bit a la vez, el valor contador se carga en CL
Para rotar un nibble (lo que es muy común en la conversión de binario a BCD) es más rápido y ocupa menos memoria si se utilizan 4 rotaciones de contador igual a 1 que si se utiliza el registro CL
Las instrucciones SAL y SHL son equivalentes
La flag de Overflow cambia con una logica precisa si la rotación es de una posición. En caso de rotaciones mayores, OVF queda indefinida.
En los procesadores 80286 en adelante la rotación se hace MODULO 32, es decir que se rotará la cantidad de veces igual al resto de la división contador/32, o sea que ROL AX,33 equivale a ROL AX,1 o ROL AX,65.
Una rotación con CL=0 equivale a un NOP de dos bytes
Instrucciones de comparación
CMP destino,fuente
;compara fuente y destino. Modifica las flags V, Z, S, C, P y AC
TEST destino,fuente
;AND entre fuente y destino . Ninguno de los operandos cambia.
TEST modifica las mismas flags que CMP pero siempre deja a V = 0 y C = 0.
Instrucciones de strings
CMPS string_destino,string_fuente
;compara las dos cadenas de a bytes o words
CMPSB string_destino,string_fuente
;origen y destino indicados por DS:SI y ES:DI (bytes)
CMPSW string_destino,string_fuente ;origen y destino indicados por DS:SI y ES:DI (words)
LODS string_fuente
;mueve un byte o una word desde fuente a AL o AX
LODSB string_fuente
;origen indicado por DS:SI (mueve un byte a AL)
LODSW string_fuente ;origen indicado por DS:SI (mueve una word a AX)
STOS string_destino
;mueve un byte o una word al destino desde AL o AX
STOSB string_destino
;destino indicado por ES:DI (mueve AL a un byte)
STOSW string_destino ;destino indicado por ES:DI (mueve AX a una word)
MOVS string_destino,string_fuente
;mueve un byte o word de fuente a destino
MOVSB string_destino,string_fuente
;origen y destino indicados por DS:SI y ES:DI (un byte)
MOVSW string_destino,string_fuente ;origen y destino indicados por DS:SI y ES:DI (una word)
SCAS string_destino
;compara la cadena de destino con AL o AX
SCASB string_destino
;destino indicado por ES:DI (compara AL con un byte)
SCASW string_destino ;destino indicado por ES:DI (compara AX con una word)
En todos los casos, si se utiliza el prefijo REP, la cantidad de elementos de la cadena a operar está dada por el contenido del registro CX, si no es un solo elemento de la cadena. A cada operación, CX es decrementado y SI y DI son incrementados o decrementados de acuerdo con el estado de la flag de dirección (Si D=0, se incrementan). El incremento o decremento de estos registros se hace de a uno si son operaciones de bytes o de a dos si son de a words. Para los casos en que se especifica el largo del operando con la B o W final, la string_destino está apuntada por ES:DI, la string_fuente está apuntada por DS:SI .
Instrucciones de repetición
LOOP
offset
;decrementa CX. Si CX no es cero, salta a offset (IP = IP + offset)
LOOPZ
offset
;decrementa CX, Si CX <> 0 y Z = 1 , salta a offset (IP = IP + offset)
LOOPNZ
offset
;decrementa CX, Si CX <> 0 y Z = 0 , salta a offset (IP = IP + offset)
En todos los casos, si no se produce el salto, se ejecuta la próxima instrucción
REP
instrucción
;decrementa CX y repite la siguiente instrucción MOVS o STOS hasta que CX=0
REPZ
instrucción
;igual que REP, pero para CMPS y SCAS. Repite si la flag Z queda en 1 (igualdad)
REPNZ
instrucción
;igual queREPZ, pero repite si la flag Z queda en 0 (las cadenas son distintas)
Instrucciones de salto
CALL
destino
;llama a procedimiento. IP <-- offset de destino y CS <-- segmento de destino
RET
valor
;retorna desde un procedimiento (el inverso de CALL), valor es opcional
INT
número
;llamado a interrupción. CS:IP <-- vector de INT.Las flags se guardan en el stack
INTO
;llama a la INT 4 si la flag de overflow (V) está en 1 cuando se ejecuta la instrucción
IRET
;retorna de interrupción al programa restaurando flags
JMP
dirección
;Salta incondicionalmente al lugar indicado por dirección
JA
offset
;salta a IP + offset si las flags C=0 Y Z=0 (salta si primer operando es mayor)
JAE
offset
;salta a IP + offset si la flag C=0 (salta si primer operando es mayor o igual)
JB
offset
;salta a IP + offset si las flags C=1 (salta si primer operando es menor)(igual a JC)
JBE
offset
;salta a IP + offset si las flags C=1 o Z=1 (salta si primer operando es menor o igual)
JZ
offset
;salta a IP + offset si las flags Z=1 (salta si primer operando es igual al segundo)(=JE)
JG
offset
;salta a IP + offset si las flags S=V Y Z=0 (salta si primer operando es mayor)
JGE
offset
;salta a IP + offset si las flags S=V (salta si primer operando es mayor o igual)
JL
offset
;salta a IP + offset si las flags S<>V (salta si primer operando es menor)
JLE
offset
;salta a IP + offset si las flags S<>V o Z=1(salta si primer operando es menor o igual)
JNC
offset
;salta a IP + offset si la flag C=0 (salta si no hay carry)
JNZ
offset
;salta a IP + offset si la flag Z=0 (salta si no son iguales o no es cero)
JNO
offset
;salta a IP + offset si la flag V=0 (salta si no hay overflow)
JNP
offset
;salta a IP + offset si la flag P=0 (salta si no hay paridad -o la paridad es impar =JPO)
JNS
offset
;salta a IP + offset si la flag S=0 (salta si no hay hay bit de signo)
JO
offset
;salta a IP + offset si la flag V=1 (salta si hay desbordamiento -overflow)
JP
offset
;salta a IP + offset si la flag P=1 (salta si la paridad es par ) (=JPE)
JS
offset
;salta a IP + offset si la flag S=1 (salta si el signo es negativo)
JCXZ
offset
;salta a IP + offset si la flag CX=0 (salta si el registro CX es cero)
Las instrucciones de saltos por Above o Below se refieren entre dos valores sin signo (JA, JAE, JB y JBE), mientras que las Greater y Less se refieren a la relación entre dos valores con signo (JG, JGE, JL y JLE). .
Instrucciones que afectan flags
CLC/CMC/STC
;pone a cero / complementa / pone en 1 la flag C (carry)
CLD/STD
;pone a cero / uno la flag de dirección (D=0 hace que SI y DI se incrementen)
CLI/STI
;deshabilita / habilita las interrupciones por hardware enmascarables
Instrucciones misceláneas
NOP
;no-operación: el procesador pasa a la instrucción siguiente sin hacer nada
CBW
;convierte el byte de AL en palabra (AX), copiando el bit 7 a todo el registro AH
CWD
;convierte word en double-word, copiando bit 15 de AX a todo el registro DX
HLT
;el procesador se detiene hasta que llegue un Reset o una interrupción por hard.
Alguien puede preguntarse para qué puede servir una instrucción que no hace absolutamente nada como la NOP. Simplemente para llenar espacio, y es realmente una de las instrucciones más útiles para un cracker, a punto tal que algunos mecanismos anticracking sofisticados buscan durante la ejecución de un programa si alguien lo arregló sustituyendo algunas instrucciones por NOPs, y en caso de detectarlo, abortan la ejecución. Pero esto es tema para más adelante.