Академический Документы
Профессиональный Документы
Культура Документы
Programación en lenguaje ensamblador/Primeros
conceptos
De Wikilibros, la colección de libros de texto de contenido libre.
< Programación en lenguaje ensamblador
Contenido
1 Registros de la CPU
2 Sintaxis del lenguaje ensamblador
2.1 Direccionamientos
3 El primer programa
4 Hola mundo
5 Saltos incondicionales y condicionales
5.1 Saltos incondicionales
5.2 Comparaciones
5.2.1 Saltos condicionales
5.2.2 Instrucción genérica para comparar
Registros de la CPU
La CPU x86 tiene 14 registros internos y básicos. Algunos son realmente de 32 bits pero por ahora se utilizará el
modo real que es compatible con el procesador 8086 (igualmente accesibles a la parte alta de éstos registros,
inclusive en el modo real). Los registros son los siguientes (estos registros son de 16 bits nombrados de la siguiente
manera, a excepción del registro de banderas).
Registros de uso general
AX: Acumulador (AL:AH)
BX: Registro base (BL:BH)
CX: Registro contador (CL:CH)
DX: Registro de datos (DL:DH)
Registros de segmento (Solo se pueden usar para los usos mencionados a excepción de ES)
DS: Registro del segmento de datos
ES: Registro del segmento extra
SS: Registro del segmento de pila
CS: Registro del segmento de código
Registros punteros (También pueden tener uso general)
BP: Registro de apuntadores base
SI: Registro índice fuente
DI: Registro ìndice destino
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 1/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
Registros especiales (Solo se pueden usar para los usos mencionados)
SP: Registro apuntador de la pila
IP: Registro apuntador de la siguiente instrucción
F: Registro de banderas (8 bits)
La parte baja del registro AX se llama AL y la parte alta AH. La parte baja del registro BX se llama BL y la parte
alta BH, y también ocurre lo mismo con el registro CX y DX.
Bits del registro de banderas
Overflow
NV (Apagado): No hay desbordamiento
OV (Encendido): Si lo hay
Direction
UP: Hacia adelante
DN: Hacia atras
Interrupts
DI: Desactivadas
EI: Activadas
Sign
PL: Positivo
NG: Negativo
Zero
NZ: No es cero
ZR: Si lo es
Auxilary carry
NA: No hay acarreo auxiliar
AC: Hay acarreo auxiliar
Parity
PO: Impar
PE: Paridad par
Carry
NC: No hay acarreo
CY: Si lo hay
Sintaxis del lenguaje ensamblador
La sintaxis es la siguiente
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 2/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
Nombre de la instrucción Operando 1, Operando 2, Operando 3, Operando 4, ...
El nombre de la instrucción está formada por 2 o 3 letras, los operandos pueden ser registros, constantes o
direcciones de memoria. La cantidad de operandos dependerá de la instrucción.
Por ejemplo:
MOV AL, [1000]
Esta instrucción indica que se copie el valor de la porción de la memoria que esté en la ubicación 1000 (En
hexadecimal) a la parte baja del registro AX (AL). Cuando un operando es un valor de una dirección de memoria,
ésta dirección se escribe entre corchetes, recordar que el operando 1 es el destino y el operando 2 es el origen. Y
cuando es una constante dependerá del ensamblador, en el caso del debug (Un programa que sirve para crear y
editar aplicaciones que viene con el DOS) se interpretarán como hexadecimales, en los siguientes ejemplos se
interpretará que las constantes son números hexadecimales.
También se puede tomar un valor de la memoria apuntado por un registro, por ejemplo:
MOV AL, [DI]
DI está apuntado al valor que está en la memoria que será copiado al registro AL. El nombre MOV viene de la
palabra move, que es una palabra del ingles que significa mover. Justamente la instrucción mencionada significa,
mover el valor apuntado por DI a AL.
También se puede copiar el valor de un registro a otro
MOV AL, BL
En este caso se copia el valor de BL a AL
Igualmente se puede copiar el valor de la parte baja de un registro a la parte alta de otro registro
MOV CH, DL
Así como también operar con las partes altas
MOV AH, DH
Inclusive se puede copiar el valor de un registro a una dirección de memoria
MOV [1000], AL
Igualmente apuntada la dirección de memoria a DI
MOV [DI], AL
Y también con los registros completos (Solamente completos en el procesador 8086)
MOV AX, DX
También trabajar con los registros completos para todos los procesadores de 32 bits
MOV EBX, EDX
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 3/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
En éste caso mueve la totalidad del registro DX a la totalidad del registro BX, en éste caso se está trabajando con
los registros en forma extendida (32 bits), pero hay que tener precaución ya que el procesador 8086 no interpretará
correctamente ésta instrucción (El procesador 8086 es obsoleto por ésta desventaja y otras más, por ejemplo sólo
puede direccionar 1 MB), además el debug no puede interpretar ésta instrucción.
No se puede realizar lo siguiente porque no se pueden pasar valores en la memoria sin la intervención de un
registro, además no se ha especificado el tamaño
MOV [1000], [2000]
Igualmente no se puede hacer lo siguiente
MOV [DI], [1000]
Así como también lo siguiente
MOV [DI], [SI]
Sin embargo lo siguiente es correcto
MOV [1000], AX
Pero no lo siguiente porque no se está especificando el tamaño
MOV [SI], 1F
Lo correcto sería lo siguiente
Si se quiere transferir un byte
MOV byte [SI], 1F
Si se quiere transferir una palabra (16 bits)
MOV word [SI], 1F
Si se quiere transferir una doble palabra (32 bits)
MOV dword [SI], 1F
Direccionamientos
Dado que es necesario transferir datos, existen los siguientes tipos de direccionamiento:
Valor de un registro Ejemplo: MOV AX, DX
Constante Ejemplo: MOV BX, 1AB
Valor apuntado por una constante Ejemplo: MOV AX, [1000]
Apuntado por un registro de segmento y uno de offset (Solo puede ser BX, BP, DI o SI) Ejemplo: MOV CX,
ES:[DI]
Apuntado por DS y la suma de BX con una constante o apuntado por SS y la suma de BP con una constante
Ejemplo: MOV DX, DS:[BP+1000]
Apuntado por DS y la suma de DI o SI con una constante Ejemplo: MOV BX, DS:[SI+6F9]
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 4/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
Apuntado por DS y la suma de BX y SI o BX y DI con una constante o apuntado por SS y la suma de BP y
SI o BP y DI con una constante
Ejemplos
MOV AX, DS:[BX][SI]+1FB9
MOV DX, SS:[BP][DI]+C9F8
El primer programa
Éste programa sumará 1000 + 2000 y volcará el resultado en AX
En DOS, en el símbolo de sistema, escribir Cls y luego Debug. Aparecerá un guión (De ésta manera se inicia
el debug, con el comando Debug).
Escribir "A 0100" y presionar la tecla Enter. "A" es una orden del debug que permite ensamblar
instrucciones a partir de una dirección (Normalmente se empieza en la dirección 0100h), el Debug
generalmente utiliza números hexadecimales.
Aparecerá lo siguiente ("xxxx" es el segmento en donde está el programa, aparecerá un número en éste lugar,
que será el valor de CS).
A 0100
xxxx:0100
Escribir las siguientes instrucciones en assembler
MOV AX, 1000
MOV BX, 2000
ADD AX, BX
INT 20
Presionar la tecla Enter
Escribir "p 0100" (Con ésta orden se ejecuta el programa y se mostrarán los sucesivos cambios de los
registros). Luego aparece "el programa ha terminado de forma normal" o "Program terminated normally".
Luego (Al terminar el programa), antes del mensaje que indica el fin del programa, aparece lo siguiente (Bloque de
estado):
AX=3000 BX=2000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=XXXX ES=XXXX SS=XXXX CS=XXXX IP=0108 NV UP EI PL NZ NA PE NC
0CB3:0108 CD20 INT 20
El Debug muestra el estado de los registros antes de ejecutar la instrucción que muestra en el bloque de estado.
El programa hace lo siguiente
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 5/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
La instrucción MOV AX, 1000 ordena que AX tome el valor de 1000.
La instrucción MOV BX, 2000 ordena que BX tome el valor de 2000.
La instrucción ADD AX, BX ordena que AX sea sumado con BX
Por lo tanto es lógico que AX tenga el valor 3000 luego de la instrucción "ADD AX, BX", ya que se le sumó a AX
el valor de BX.
La instrucción INT 20 ordena provocar una interrupción que es 20h, que le cede el control a DOS, y DOS termina
el programa. Una interrupción es una interrupción de la ejecución de un programa para realizar una determinada
tarea, a veces el control no vuelve al programa original (Por ejemplo en el caso de INT 20h en el DOS).
Las interrupciones pueden ejecutarse por las circunstancias más variadas, por ejemplo el usuario presiona una tecla
y ésto provoca una interrupción y se ejecuta las instrucciones del controlador de teclado y almacena la tecla
presionada, luego le devuelve el control al programa original (Con una instrucción sin operandos llamada IRET).
Cuando ocurre una interrupción se empuja a la pila CS e IP, y éstos 2 registros se modifican para apuntar a la rutina
deseada. Los valores de éstos 2 registros están almacenados en la tabla de vectores de interrupción (Ésta está
ubicada en el comienzo de la memoria en 0000:0000). Para encontrar éstos 2 valores (Llamado vector de
interrupción), se multiplica el número de interrupción por 4 (El offset), y se lee 4 bytes en el offset mencionado y
en el segmento 0000. Los primeros 2 bytes (El primer word) del vector de interrupción es el offset (IP), y los 2
restantes (El segundo word) es el segmento (CS).
En el caso de la interrupción 20h fue provocada por el mismo programa, para evitar interrupciones que no sean
provocadas por el programa se utiliza la instrucción CLI y para luego activarlas se utiliza STI, pero no se pueden
enmascarar las interrupciones menores de 8 ya que no son enmascarables. Hay que tener en cuenta que en la
arquitectura x86, el microprocesador almacena en la memoria, desde los bytes menos significativos hasta los más
significativos (Si no se tiene en cuenta ésto puede haber misteriosos fallos del programa que se está programando).
Por lo tanto en un vector de interrupción, el primer word (Palabra) contiene el valor que se le asignará a IP
(Offset), el segundo word contiene el valor que se le asignará a CS (Segmento), cuando se provoque la
interrupción del correspondiente vector.
Hola mundo
Éste programa mostrará "Hola mundo" en la pantalla, utilizando servicios de DOS.
Se entra al Debug y se escribe lo siguiente (Sin utilizar la orden ensamblar)
E 1000 'Hola mundo$'
"E" significa escribir, se escribe en el segmento de datos (Indicado por DS). La sintaxis de ésta orden del debug es
la siguiente:
E Offset '[Cadena de carácteres]'
El carácter "$" que está a la derecha de la frase "Hola mundo", sirve para que el servicio de DOS que se va a
utilizar para mostrar Hola mundo en la pantalla no muestre información más alla del carácter que está a la
izquierda del carácter '$', es decir éste carácter limitador es el fin de la cadena, es decir a partir de éste no mostrará
más caracteres.
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 6/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
Importante: Si no finaliza la cadena con el carácter '$', al llamar al servicio de DOS para mostrar el carácter,
probablemente se bloqueará la PC hasta encontrar un carácter '$', inclusive puede ser que nunca lo encuentre.
A continuación ensamblar las siguientes instrucciones (A partir de 0100h):
MOV AH, 09
MOV DX, 1000
INT 21
INT 20
Luego ejecutar el ejemplo con la orden "g"
El programa mostrará el mensaje "Hola mundo", luego el debug mostrará un mensaje diciendo que el programa ha
terminado normalmente.
Al provocar la interrupción 21h se llama a un servicio de DOS, el número de servicio está determinado por la parte
alta de AX (AH).
El servicio 09h muestra la información en forma de carácteres a partir del comienzo apuntado por el registro DX
(El offset, en éste caso 1000h), muestra la información hasta el carácter anterior al carácter '$' (Anteriormente
mencionado).
Luego se provoca la interrupción 20h que finaliza el programa.
La orden escribir del debug también acepta bytes individuales, por ejemplo:
E 3000 0, BF, 5F, C4
También acepta en forma mixta (Bytes individuales y cadenas de carácteres)
E 3000 'JRJGOR', 0, 21, 'Ejd', 2F
Es decir la orden ensamblar está acompañada del offset de los datos a escribir y de los items.
Un item puede ser un byte individual o una cadena de carácteres (Que ésta última debe estar entre simples
comillas).
Saltos incondicionales y condicionales
A veces un programa debe cambiar el flujo del programa en forma incondicional o bajo una condición (Para tomar
una decisión), por lo tanto debe haber instrucciones que permitan cambiar el flujo de un programa sin ningún
requisito, o en caso de que una condición se cumpla. Existen instrucciones para éste propósito. Son las
instrucciones de saltos incondicionales y condicionales, que saltan a un determinado punto si se cumpla la
condición.
Saltos incondicionales
La única instrucción que existe para éste fin es JMP (Abreviatura de JUMP, que significa en inglés SALTAR). La
sintaxis es la siguiente.
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 7/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
JMP XXXX
XXXX: Es la ubicación de la instrucción en donde se continuará el programa (A partir de ésta se ejecutan las
siguientes).
Ejemplo:
XXXX:0100 MOV AX, 1000
XXXX:0103 JMP 0107
XXXX:0105 XOR AX, AX
XXXX:0107 INT 20
En éste caso al ejecutarse la instrucción de salto incondicional (JMP), se continúa la ejecución a partir de la
instrucción (INT 20h), no ejecutandose la instrucción XOR (Ésta instrucción realiza la operación XOR de el
operando 2 sobre el operando 1) que provocaría el borrado de registro AX (Que provocaría que AX tome el valor
0), si se ejecuta.
Es decir, se ejecutan las siguientes instrucciones:
MOV AX, 1000
JMP 0107
INT 20
No se ejecuta "XOR AX, AX" por el salto incondicional.
El operando puede ser una dirección constante (Por ejemplo 0107), un salto a nivel de offset, también puede ser un
salto largo (Que cambie los valores de los registros CS e IP), (Por ejemplo FFFF:0000, que salta al ROM BIOS).
También puede ser el valor de un registro, por ejemplo:
JMP DI
En éste caso salta a la instrucción apuntada por DI.
También puede ser un valor apuntado por un registro puntero, por ejemplo:
JMP [SI]
En éste caso salta a la instrucción apuntada por el valor apuntado por SI.
El operando puede ser cualquier direccionamiento válido (Puede ser cualquiera de los direccionamientos utilizados
en el operando origen de la instrucción MOV, explicados anteriormente).
Comparaciones
Saltos condicionales
Son similares a JMP en la sintaxis, pero la diferencia es el nombre.
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 8/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
Las instrucciones son las siguientes:
JE o JZ: Salta si está prendido el bit Zero del registro de banderas.
Objetivo: Saltar si la última comparación realizada da igual.
JA o JNBE: Salta si el bit carry (CF) o el bit zero (ZF) del registro de banderas está desactivado.
Objetivo: Saltar si la última comparación realizada con números naturales da mayor.
JB o JNAE: Salta si CF está activada.
Objetivo: Saltar si la última comparación realizada con números naturales da menor.
JG o JNLE: Salta si ZF es cero o si OF y SF son iguales.
Objetivo: Saltar si la última comparación realizada con números enteros da mayor.
JL o JNGE: Saltar si SF es diferente a OF
Objetivo: Saltar si la última comparación realizada con números enteros da menor.
JC: Saltar si CF está prendida
Objetivo: Saltar si hay acarreo
JO: Saltar si OF está prendido
Objetivo: Saltar si hay desbordamiento
JP: Saltar si PF está prendido
Objetivo: Saltar si hay paridad
JS: Saltar si SF está prendido
Objetivo: Saltar si es negativo
JNE o JNZ: Comportamiento inverso a JE o JZ
JNA o JBE: Comportamiento inverso a JA o JNBE
JNB o JAE: Comportamiento inverso a JB o JNAE
JNG o JLE: Comportamiento inverso a JG o JNLE
JNL o JGE: Comportamiento inverso a JL o JNGE
JNC: Comportamiento inverso a JC
JNO: Comportamiento inverso a JO
JNP o JPO: Comportamiento inverso a JP
JNS: Comportamiento inverso a JS
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 9/10
1/4/2017 Programación en lenguaje ensamblador/Primeros conceptos Wikilibros
Hay otras instrucciones que hacen saltos condicionales, pero que no necesitan la instrucción CMP, son las
siguientes:
JCXZ: Salta si el registro CX es cero.
LOOP: Decrementa CX, restándole 1 y salta si CX es distinto de cero.
Objetivo: Hacer un bucle, utilizando como contador CX
LOOPE: Decrementa CX en 1 y salta si CX es distinto de cero y ZF está prendido.
Objetivo: Hacer un bucle, utilizando como contador CX y terminar si el contador llega a cero, o se apaga el bit
Zero.
LOOPNE: Decrementa CX en 1 y salta si ZF está prendido
Objetivo: Hacer un bucle que siga funcionando hasta que se apague el bit Zero.
La sintaxis de éstas instrucciones son similares a la instrucción JMP, lo único que cambia es el nombre.
Instrucción genérica para comparar
La instrucción es CMP, ésta permite comparar 2 operandos, la sintaxis es la siguiente:
CMP <Operador 1>, <Operador 2>
El operador 1, se compara con el 2.
Los operandos pueden ser cualquier direccionamiento válido, cumpliendo las reglas de la instrucción MOV con
respecto a los operandos.
Ésta instrucción compara 2 operandos y luego cambia el registro de banderas en base al resultado de la
comparación.
Obtenido de «https://es.wikibooks.org/w/index.php?
title=Programación_en_lenguaje_ensamblador/Primeros_conceptos&oldid=291828»
Esta página fue modificada por última vez el 28 oct 2015 a las 08:25.
El texto está disponible bajo la Licencia Creative Commons AtribuciónCompartirIgual 3.0; pueden
aplicarse términos adicionales. Véase Términos de uso para más detalles.
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_lenguaje_ensamblador/Primeros_conceptos 10/10