Você está na página 1de 7

EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.

htm

EL JUEGO DE INSTRUCCIONES DEL X86

¿Por qué aprender ensamblador?


A nosotros nos importa bien poco en qué lenguaje de programación se ha
compilado una aplicación, sólo en alguna ocasión será interesante saber en
qué lengua se ha escrito algún programa (y tampoco será imprescindible
averiguarlo). Todos sabéis que se programe en el lenguaje que se programe
la compilación traduce las líneas de código al único código que entiende la
máquina, éste código es el ensamblador y es la única lengua que necesitamos
conocer tanto para añadir como para quitar código a una aplicación. En esta
página tenéis la posibilidad de aprender un poco cada una de las
instrucciones más habituales y cómo hacer uso de ellas. Al final disponéis del
juego de instrucciones completo, de momento está en Ingles pero lo iremos
traduciendo al español, como siempre, cuando tengamos un rato.

Comenzaremos con los registros.


De los registros podíamos estar hablando días y días enteros, pero lo que nos
interesa saber de ellos es que son lugares donde guardar y conocer datos.
Con ellos podemos sumar, restar, multiplicar, guardar un dato, ejecutar una
función determinada de una interrupción, en fin, son imprescindibles. Aquí
tienes la lista de algunos registros.

AX Acumulador, de uso general. Se puede dividir en AH y AL. Obtendremos el


mismo resultado si hacemos "MOV AX , FF00" que si hacemos primero "MOV
AH , FF" y después "MOV AL , 00".
BX Registro base, de uso general. Se puede dividir en BH y BL.
CX Registro contador, de uso general. Se puede dividir en CH y CL.
DX Registro de datos, de uso general. Se puede dividir en DH y DL.
DS Registro del segmento de datos. Utilizado para apuntar a un segmento.
ES Registro del segmento extra. Lo mismo que DS.
SS Registro del segmento de pila. Nos indica el segmento donde se encuentra
la pila (mas abajo hablaremos de ella).
CS Registro del segmento de código. Nos indica el segmento donde se
encuentra el código que se está ejecutando.
BP Registro de apuntadores base. Digamos que este registro se utiliza para
apuntar donde guardamos datos.
SI Registro índice fuente.
DI Registro índice destino.
SP Registro del apuntador de la pila. Este registro nos indica dónde está la
pila en la que se guardan los datos que introducimos en ella.
IP Registro que apunta a la siguiente instrucción que se tiene que ejecutar.
F Registro de flags. Este registro es necesario leerlo en binario. Cada bit
representa el resultado de alguna operación, por ejemplo si comparamos dos
números este en este registro encontramos información sobre si uno es
menor o mayor que el otro o si son iguales, etc. Los flags (o banderas) son
los siguientes CF, PF, AF, ZF, SF, TF, IF y OF.

Antes de continuar hablaremos de la instrucción NOP. Esta instrucción es


nula, o sea que no hace absolutamente nada. Es utilizada para provocar un
retraso en la CPU y nosotros la utilizamos PARA ELIMINAR EL CODIGO QUE
NO QUEREMOS QUE SE EJECUTE (una forma de parchear) cambiando el

1 de 7 12/05/2009 15:52
EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.htm

código que existe por tantos nop's como bytes queremos eliminar.

¿Qué es la pila?
Ahora que sabemos como guardar un dato determinado usando los registros,
nos damos cuenta de que en ocasiones necesitaremos guardar mas datos
que registros tenemos. ¿Como solucionamos esto? pues con el uso de la
pila. Supongamos que debemos de guardar 10 números y solo disponemos
de 4 registros de uso general, la solución es hacer los siguiente:

MOV AX , PRIMER_NUMERO..... <= cargamos en ax el número


PUSH AX ....................................... <= y lo dejamos caer en la pila
MOV AX , SEGUNDO_NUMERO. <= cargamos en ax el siguiente nº
PUSH AX........................................ <= y también lo descargamos en la pila.

.... así hasta terminar de descargar nuestros datos. ¿Donde se han guardado?
pues en SS:SP.

Para recuperar lo introducido en la pila, hay que saber que siempre sale
primero el último dato que entra, este es el motivo de que se le llame pila, se
apilan los datos. Imagina que amontonas platos uno encima de otro... para
sacar el primer plato que has puesto debes de sacarlos TODOS. Este es el
concepto de la pila.

POP AX <= Recupera de la pila EL ULTIMO DATO INTRODUCIDO y lo deposita en el


registro AX.

Bien... Ya hemos visto que son los registro, ahora vamos a ver como los
guardamos en la pila y como los recuperamos de ella...

PUSH REGISTRO..... <= Guarda en la pila un registro.


PUSH NUMERO........ <= Guarda en la pila un número.
PUSHF....................... <= Guarda en la pila los flag.
PUSHA...................... <= Guarda en la pila los registros AX, CX, DX, BX, SP, BP, SI y DI
en este mismo orden.
POPA........................ <= Recupera de la pila los registros DI, SI, PB, SP, BX, DX, CX y AX
en este mismo orden.
POPF......................... <= Recupera de la pila los flags.
POP REGISTRO....... <= recupera un dato de la pila y lo deposita en "REGISTRO".

Instrucciones de salto
Si has programado alguna vez en cualquier Básic, sabrás que las instrucciones de salto
tales como goto y gosub son la madre de cualquier programa. En ensamblador es lo
mismo, solo que tenemos muchisimas más posibilidades.

JMP DIRECCION.... <= Hace que el programa salte a dirección. Sería como el goto del
Básic.
CALL DIRECCION. <= Hace que el programa salte a dirección para ejecutar un
fragmento de código y cuando termina retorna a la siguiente instrucción despues de call
con RET. Sería como el gosub del Básic.

Después de una instrucción de comparación de 2 números podemos hacer saltos


condicionados:

CMP AX , BX............ <= Compara el registro ax con bx.


JE DIRECCION......... <= Salta a dirección si los registros son iguales.
CMP AX , NUMERO. <= Compara ax con número.

2 de 7 12/05/2009 15:52
EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.htm

JA DIRECCION......... <= Salta si ax es mayor que número.


JAE DIRECCION....... <= Salta si ax es mayor o igual que número.
JB DIRECCION.......... <= Salta si ax es menor que número.
JBE DIRECCION....... <= Salta si ax es menor o igual que número.
JA DIRECCION.......... <= Salta si ax es mayor o igual que número.
JNE DIRECCION....... <= Salta si no son iguales.
JCXZ DIRECCION..... <= Salta si CX es cero.

Instrucción nula

¿para qué sirve una instrucción que no hace nada? NOP es


una instrucción cuya misión es la de provocar un retraso en la CPU, es
frecuente verla en fragmentos de código donde se hacen operaciones de
lectura/escritura en puertos para darle tiempo a aceptar otra instrucción al
periferico al que se le hace la solicitud. Esta instrucción es muy útil a la hora
de parchear un programa, cuando hay un fragmento de código que no
queremos que se ejecute simplemente NOPEAMOS los bytes que nos interesa
y eliminamos lo que no nos interesa.

Instrucciones aritméticas
Hay muchas instrucciones que nos permiten sumar, restar, multiplicar, dividir
etc. pero solo mencionaré las de uso mas frecuente.

ADD AX , BX................. <= Esta instrucción la leeremos como "súmale a ax el contenido


de bx y depositalo en ax". Sería como a=a+b en Básic.
SUB AX , NUMERO........ <= Es lo mismo que la instrucción anterior pero restando.
INC BX............................ <= Incrementa en uno el contenido de bx.
DEC CX........................... <= Decrementa en uno el contenido de cx.
MUL BX.......................... <= Atención, para multiplicar un número pondremos en el
registro ax uno de los números a multiplicar, a continuación hacemos mul destino donde
destino ha de ser bx, cx ó dx y además contendrá el otro número por el que hay que
multiplicar ax. En Básic A=A*B.
DIV BX........................... <= Funciona igual mul pero para dividir.

Instrucciones de bucle
Si necesitamos repetir un fragmento de código cualquier cantidad de veces
usaremos los bucles que son como los for-next del Básic.

MOV CX , REPETICION...<= Carga en cx la cantidad de veces que se repetirá


el bucle.
bucle:...........................<= Esto es una etiqueta.
... ................................<= Instrucciones a ejecutar.
... ................................<= Instrucciones a ejecutar.
LOOP bucle.....................<= Reduce el valor de cx en uno y salta a bucle
mientras cx sea mayor que cero.

Instrucciones de lectura/escritura de puertos

3 de 7 12/05/2009 15:52
EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.htm

Cada dispositivo que está conectado a nuestro ordenador se comunica con él


a través de un puerto. Habras oido hablar del puerto serie o el paralelo.
Piensa en los puertos como en lugares a donde ha de llegar un dato o donde
podremos encontrar un dato. Para enviar un dato a un puerto se utilizan las
siguientes instrucciones:

MOV DX , NUMERO_DE_PUERTO
MOV AX , NUMERO_A_ENVIAR
OUT DX , AX

Y para leer un dato de un puerto:

MOV DX , NUMERO_DE_PUERTO
IN AX , DX

Juego completo (con tiempo iremos traduciendo y comentando


todas las instrucciones)

AAA - Ascii Adjust for Addition


AAD - Ascii Adjust for Division
AAM - Ascii Adjust for Multiplication
AAS - Ascii Adjust for Subtraction
ADC - Add With Carry
ADD - Arithmetic Addition
AND - Logical And
ARPL - Adjusted Requested Privilege Level of Selector (286+
PM)
BOUND - Array Index Bound Check (80188+)
BSF - Bit Scan Forward (386+)
BSR - Bit Scan Reverse (386+)
BSWAP - Byte Swap (486+)
BT - Bit Test (386+)
BTC - Bit Test with Compliment (386+)
BTR - Bit Test with Reset (386+)
BTS - Bit Test and Set (386+)
CALL - Procedure Call
CBW - Convert Byte to Word
CDQ - Convert Double to Quad (386+)
CLC - Clear Carry
CLD - Clear Direction Flag
CLI - Clear Interrupt Flag (disable)
CLTS - Clear Task Switched Flag (286+ privileged)
CMC - Complement Carry Flag
CMP - Compare
CMPS - Compare String (Byte, Word or Doubleword)
CMPXCHG - Compare and Exchange
CWD - Convert Word to Doubleword
CWDE - Convert Word to Extended Doubleword (386+)
DAA - Decimal Adjust for Addition
DAS - Decimal Adjust for Subtraction
DEC - Decrement
DIV - Divide
ENTER - Make Stack Frame (80188+)
ESC - Escape
HLT - Halt CPU

4 de 7 12/05/2009 15:52
EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.htm

IDIV - Signed Integer Division


IMUL - Signed Multiply
IN - Input Byte or Word From Port
INC - Increment
INS - Input String from Port (80188+)
INT - Interrupt
INTO - Interrupt on Overflow
INVD - Invalidate Cache (486+)
INVLPG - Invalidate Translation Look-Aside Buffer Entry
(486+)
IRET/IRETD - Interrupt Return
Jxx - Jump Instructions Table
JCXZ/JECXZ - Jump if Register (E)CX is Zero
JMP - Unconditional Jump
LAHF - Load Register AH From Flags
LAR - Load Access Rights (286+ protected)
LDS - Load Pointer Using DS
LEA - Load Effective Address
LEAVE - Restore Stack for Procedure Exit (80188+)
LES - Load Pointer Using ES
LFS - Load Pointer Using FS (386+)
LGDT - Load Global Descriptor Table (286+ privileged)
LIDT - Load Interrupt Descriptor Table (286+ privileged)
LGS - Load Pointer Using GS (386+)
LLDT - Load Local Descriptor Table (286+ privileged)
LMSW - Load Machine Status Word (286+ privileged)
LOCK - Lock Bus
LODS - Load String (Byte, Word or Double)
LOOP - Decrement CX and Loop if CX Not Zero
LOOPE/LOOPZ - Loop While Equal / Loop While Zero
LOOPNZ/LOOPNE - Loop While Not Zero / Loop While Not
Equal
LSL - Load Segment Limit (286+ protected)
LSS - Load Pointer Using SS (386+)
LTR - Load Task Register (286+ privileged)
MOV - Move Byte or Word
MOVS - Move String (Byte or Word)
MOVSX - Move with Sign Extend (386+)
MOVZX - Move with Zero Extend (386+)
MUL - Unsigned Multiply
NEG - Two's Complement Negation
NOP - No Operation (90h)
NOT - One's Compliment Negation (Logical NOT)
OR - Inclusive Logical OR
OUT - Output Data to Port
OUTS - Output String to Port (80188+)
POP - Pop Word off Stack
POPA/POPAD - Pop All Registers onto Stack (80188+)
POPF/POPFD - Pop Flags off Stack
PUSH - Push Word onto Stack
PUSHA/PUSHAD - Push All Registers onto Stack (80188+)
PUSHF/PUSHFD - Push Flags onto Stack
RCL - Rotate Through Carry Left
RCR - Rotate Through Carry Right
REP - Repeat String Operation

5 de 7 12/05/2009 15:52
EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.htm

REPE/REPZ - Repeat Equal / Repeat Zero


REPNE/REPNZ - Repeat Not Equal / Repeat Not Zero
RET/RETF - Return From Procedure
ROL - Rotate Left
ROR - Rotate Right
SAHF - Store AH Register into FLAGS
SAL/SHL - Shift Arithmetic Left / Shift Logical Left
SAR - Shift Arithmetic Right
SBB - Subtract with Borrow/Carry
SCAS - Scan String (Byte, Word or Doubleword)
SETAE/SETNB - Set if Above or Equal / Set if Not Below
(386+)
SETB/SETNAE - Set if Below / Set if Not Above or Equal
(386+)
SETBE/SETNA - Set if Below or Equal / Set if Not Above
(386+)
SETE/SETZ - Set if Equal / Set if Zero (386+)
SETNE/SETNZ - Set if Not Equal / Set if Not Zero (386+)
SETL/SETNGE - Set if Less / Set if Not Greater or Equal
(386+)
SETGE/SETNL - Set if Greater or Equal / Set if Not Less
(386+)
SETLE/SETNG - Set if Less or Equal / Set if Not greater or
Equal
SETG/SETNLE - Set if Greater / Set if Not Less or Equal
(386+)
SETS - Set if Signed (386+)
SETNS - Set if Not Signed (386+)
SETC - Set if Carry (386+)
SETNC - Set if Not Carry (386+)
SETO - Set if Overflow (386+)
SETNO - Set if Not Overflow (386+)
SETP/SETPE - Set if Parity / Set if Parity Even (386+)
SETNP/SETPO - Set if No Parity / Set if Parity Odd (386+)
SGDT - Store Global Descriptor Table (286+ privileged)
SIDT - Store Interrupt Descriptor Table (286+ privileged)
SHL - Shift Logical Left
SHR - Shift Logical Right
SHLD/SHRD - Double Precision Shift (386+)
SLDT - Store Local Descriptor Table (286+ privileged)
SMSW - Store Machine Status Word (286+ privileged)
STC - Set Carry
STD - Set Direction Flag
STI - Set Interrupt Flag (Enable Interrupts)
STOS - Store String (Byte, Word or Doubleword)
STR - Store Task Register (286+ privileged)
SUB - Subtract
TEST - Test For Bit Pattern
VERR - Verify Read (286+ protected)
VERW - Verify Write (286+ protected)
WAIT/FWAIT - Event Wait
WBINVD - Write-Back and Invalidate Cache (486+)
XCHG - Exchange
XLAT/XLATB - Translate
XOR - Exclusive OR

6 de 7 12/05/2009 15:52
EL JUEGO DE INSTRUCCIONES DEL X86 http://www.terra.es/personal/guillet/juego.htm

7 de 7 12/05/2009 15:52

Você também pode gostar