Tutorial Emu 8086 En español

TraducitoDescripción completa

Views 33 Downloads 0 File size 1MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Tutorial Emu86 1) sistemas de numeración tutorial ¿Qué es? Hay muchas formas de representar el mismo valor numérico. Hace mucho tiempo, los seres humanos utilizaban palos para contar y, posteriormente aprendieron a dibujar imágenes de palos en el suelo y eventualmente en el papel. Así, el número 5 fue representado como: | | | | | (para 5 palos). Más tarde, los romanos comenzaron a utilizar símbolos diferentes para varios números de palos: | | | todavía significaba tres palos, pero un V ahora significó cinco palos, y una X se utiliza para representar diez de ellos! Con unos palos para contar fue una idea genial para su tiempo. Y el uso de símbolos en lugar de verdaderos palos fue mucho mejor.

Sistema Decimal La mayoría de las personas hoy en día utilizan una representación decimal para contar. En el sistema decimal hay 10 dígitos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Estos dígitos puede representar cualquier valor, por ejemplo: 754. El valor está formado por la suma de cada dígito multiplicado por la base (en este caso es 10 porque hay 10 dígitos en el sistema decimal) en poder de posición de dígito (a contar desde cero):

La posición de cada dígito es muy importante! Por ejemplo, si coloca "7" al final: 547 Será otro valor:

Nota importante: cualquier número en poder de cero es 1, incluso cero en poder de cero es 1:

Sistema binario Los equipos no son tan inteligentes como los seres humanos (o no todavía), es fácil hacer una máquina electrónica con dos estados: on y off, o 1 y 0. Los ordenadores utilizan el sistema binario, el sistema binario utiliza 2 dígitos: 0, 1 Y, por lo tanto, la base es 2. Cada dígito en un número binario se llama BIT, 4 bits forma un cuarteto, 8 bits forman un byte, dos bytes forman una palabra, dos palabras que forman una palabra doble (poco usado):

Hay una convención para agregar "b" en el extremo de un número binario, de esta manera podemos determinar que 101b es un número binario con valor decimal de 5.

El número binario 10100101b equivale al valor decimal de 165:

Sistema hexadecimal Sistema hexadecimal utiliza 16 dígitos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F Y, por lo tanto, la base es 16. Los números hexadecimales son compactos y fáciles de leer. Es muy fácil convertir números del sistema binario al sistema hexadecimal y viceversa, cada nibble (4 bits) se pueden convertir a un dígito hexadecimal utilizando esta tabla:

Decimal (Base 10)

Binario (Base 2).

Hexadecimal (base 16)

0

0000

0

1

0001

1

2

0010

2

3

0011

3

4

0100

4

5

0101

5

6

0110

6

7

0111

7

8

1000

8

9

1001

9

10

1010

Un

11

1011

B

12

1100

C

13

1101

D

14

1110

E

15

1111

F

Hay una convención para agregar "h" en el extremo de un número hexadecimal, de esta manera podemos determinar que 5Fh es un número hexadecimal con valor decimal de 95. También vamos a añadir un "0" (cero) en el principio de números hexadecimales que comienzan con una letra (A..F), por ejemplo, 0E120h. El número hexadecimal 1234h es igual al valor decimal de 4660:

La conversión del sistema decimal a cualquier otra A fin de convertir en sistema decimal, a cualquier otro sistema, es necesario dividir el valor decimal por la base del sistema deseado,

cada vez que usted debe recordar el resultado y mantener el resto, el proceso de división continúa hasta que el resultado es cero. Los restos se utilizan entonces para representar un valor en ese sistema. Vamos a convertir el valor de 39 (base 10) al sistema hexadecimal (base 16):

Como ves tenemos este número hexadecimal: 27h. Todos los restos fueron inferiores a 10 en el ejemplo anterior, así que no usamos todas las cartas. Aquí está otro ejemplo más complejo: Vamos a convertir el número decimal a hexadecimal 43868 formulario:

El resultado es 0AB5ch, estamos utilizando the above table para convertir residuos en 9 letras correspondientes.

Utilizando el mismo principio podemos convertir a formato binario (usando 2 como el divisor), o convertir un número hexadecimal y, a continuación, convertir a número binario utilizando the above table:

Como ves tenemos este número binario: 1010101101011100b

Los números firmados No hay manera de decir con certeza si el byte hexadecimal 0FFh es positivo o negativo, puede representar tanto el valor decimal "255" y "- 1". 8 bits puede ser utilizado para crear 256 combinaciones (incluyendo el cero), de modo que simplemente suponen que los primeros 128..127 combinaciones ( 0) se representan los números positivos y próximos 128 combinaciones (128..256) se representan los números negativos. A fin de obtener "- 5", debemos restar 5 del número de combinaciones (256), por lo que explicaremos: 256 - 5 = 251. Mediante esta compleja forma de representar los números negativos tiene algún significado, en Matemáticas cuando agregue "- 5" "5" debe ponerse a cero. Esto es lo que sucede cuando el procesador agrega dos bytes 5 y 251, el resultado obtiene más de 255, debido al desborde procesador obtiene cero!

Cuando las combinaciones 128..256 se utiliza el bit más alto es siempre 1, así que esto quizá utilizada para determinar el signo de un número. El mismo principio se utiliza para las palabras (valores) de 16 bits, 16 bits, crear 65.536 combinaciones, primera 32768..32767 combinaciones ( 0) se usan para representar números positivos, y el próximo 32768 combinaciones (32767..65535) representan los números negativos.

Existen algunas herramientas útiles para la EMU8086 para convertir números y realizar cálculos de cualquier expresión numérica, todo lo que necesitas es un clic en menú Math:

Base Converter le permite convertir números desde cualquier sistema y a cualquier sistema. Teclee un valor en cualquier cuadro de texto, y el valor será convertido automáticamente a todos los demás sistemas. Se puede trabajar tanto con 8 bits y 16 bits de valores. Base múltiple se puede utilizar la calculadora para realizar cálculos entre números en diferentes sistemas y convertir números de un sistema a otro. Escriba una expresión y pulse enter, el resultado aparecerá en el sistema de numeración elegida. Puede trabajar con valores de hasta 32 bits. Se comprueba cuando se firma el evaluador asume que todos los valores (excepto decimal y el doble de palabras) deben ser tratadas como firmado. Palabras dobles siempre se tratan como valores con signo, por lo que 0FFFFFFFFh se convierte en -1. Por ejemplo, desea calcular: 0FFFFh * 10h + 0FFFFh (ubicación de memoria máxima que se puede acceder por CPU 8086). Si cheque firmado y Word obtendrá -17 (porque se evalúa como (-1) * 16 + (-1) . Para hacer el cálculo con los valores sin signo

desmarque firmado, de manera que la evaluación será 65535 * 16 + 65535 y usted debe recibir 1114095. También puede usar la base Converter para convertir no decimales Firmado a valores decimales, y hacer los cálculos con valores decimal (si es más fácil para usted). Estas operaciones son compatibles: ~ No (invierte los bits). * Se multiplican. / Dividir. % Modulus. + suma. - Restar (y unarios -). > Desplazamiento a la derecha. & AND como bit. ^ XOR a nivel de bits. | o binaria.

Números binarios debe tener elsufijo " b ", por ejemplo: 00011011b Los números hexadecimales deben tener elsufijo " h ", y empezar con un cero cuando el primer dígito es una letra (A..F), por ejemplo: 0ABCDh Octal (base 8) números debe tener elsufijo " o ", por ejemplo: 77s

2) ensamblador 8086 Tutorial para principiantes (parte 1) Este tutorial está pensado para aquellos que no están familiarizados con ensamblador en absoluto, o tienen una idea muy lejanos. Por supuesto, si usted tiene conocimiento de algún otro lenguaje de programación (Basic, C/C++, Pascal...) que puede ayudar mucho.

Pero incluso si usted está familiarizado con ensamblador, sigue siendo una buena idea mirar a través de este documento a fin de estudiar la UEM8086 de sintaxis. Se supone que tienes algunos conocimientos sobre representación numérica (hex/bin), si no es altamente recomendable para estudiar numbering systems tutorial antes de continuar.

¿Qué es el lenguaje ensamblador? El lenguaje ensamblador es un lenguaje de programación de bajo nivel que usted necesita para obtener algunos conocimientos acerca de la estructura de computadores para entender nada. El modelo informático sencillo como yo lo veo:

El bus del sistema (que se muestra en amarillo) conecta los distintos componentes de un ordenador. La CPU es el corazón del equipo, la mayoría de los cálculos ocurren en el interior de la CPU. RAM es un lugar donde los programas se cargan para ser ejecutado.

Dentro de la cpu

Registros de propósito general 8086 CPU tiene 8 registros de propósito general, cada registro tiene su propio nombre: Axe - el registro acumulador (dividido en AH / AL). BX : la dirección base register (dividido en BH / BL). CX - el recuento registro (dividido en CH / CL). DX - el registro de datos (dividido en DH / dl). Is - fuente registro de índice. DI - destino registro de índice. BP - base puntero. Puntero de pila SP -. A pesar del nombre de un registro, es el programador que determina el uso de cada registro de propósito general. El principal objetivo de un registro es mantener un número (variable). El tamaño de los registros anteriores es de 16 bits, es algo así como: 0011000000111001b (en formato binario), o 12345 en decimal (humano). 4 registros de propósito general (AX, BX, CX, DX) están hechas de dos registros de 8 bits, por ejemplo, si AX= 0011000000111001b, A continuación, AH=00110000b Y AL=00111001b. Por lo tanto, cuando Modificar cualquiera de los registros de 8 bits 16 bits de registro también se actualiza, y viceversa. La misma es para otros 3 registros, "H" es para la alta y "L" es para la parte baja.

Porque los registros están ubicados dentro de la CPU, que son mucho más rápido que la memoria. Acceder a una ubicación de memoria requiere el uso de un sistema de bus, por lo que toma mucho más tiempo. Acceder a los datos en un registro que usualmente no toma tiempo. Por lo tanto, usted debe intentar guardar variables en los registros. registro establece son muy pequeñas y la mayoría de los registros tienen fines especiales que limitan su uso como variables, pero todavía son un excelente lugar para almacenar datos temporales de cálculos. Los registros de segmento CS - puntos en el segmento que contiene el programa actual. DS - generalmente apunta al segmento donde estén definidas las variables. ES - registro de segmento extra, es un codificador para definir su uso. SS : puntos en el segmento que contiene la pila. Aunque es posible almacenar los datos en los registros de segmento, esto nunca es una buena idea. Los registros de segmento tiene un propósito muy especial - apuntando a los bloques de memoria accesible. Los registros de segmento trabajar juntos con propósito general Regístrese para acceder a cualquier valor de la memoria. Por ejemplo, si quisiéramos tener acceso a la memoria en la dirección física 12345h (hexadecimal), debemos definir el DS = 1230h y si = 0045h. Esto es bueno, ya que de esta manera podemos acceder a mucha más memoria que con un registro único que está limitado a valores de 16 bits. CPU hace un cálculo de dirección física multiplicando el registro de segmento por 10h y agregar registro de propósito general (1230h * 10h + 45h = 12345h):

La dirección formada con 2 registros se denomina una dirección efectiva. Por defecto BX, SI y DI registra trabaja con registro de segmento DS; BP y SP trabajar con SS registro de segmento. Otros registros de propósito general puede constituir una eficaz dirección! También, aunque BX puede formar una dirección efectiva, BH y BL no puede. Registros de propósito especial

IP - El puntero de instrucciones. - Registro de flags determina el estado actual de la Microprocesador.

Registro IP siempre trabaja junto con el registro de segmento CS y señala que actualmente ejecuta la instrucción. Registro de flags es modificado automáticamente por uso de CPU después de operaciones matemáticas, ello permite determinar el tipo de resultado, y determinar las condiciones para transferir el control a otras partes del programa. Generalmente no se puede acceder a estos registros directamente, la manera en que usted puede tener acceso a AX y otros registros generales, pero es posible cambiar los valores de los registros de sistema utilizando algunos trucos que aprenderá un poco más tarde.

3) ensamblador 8086 Tutorial para principiantes (parte 2) Memory Access Para tener acceso a la memoria, podemos utilizar estos cuatro registros: BX, IS, DI, BP. combinando estos registros dentro de [ ] símbolos, podemos obtener diferentes ubicaciones de memoria. Estas combinaciones son compatibles (modos de direccionamiento): [SI] + BX [BX + DI] BP + [SI] [BP + DI]

[SI] [DI] D16 (offset variable solamente) [BX]

[BX + IS + d8] [BX + DI + d8] [BP + IS + d8] [BP + DI + d8]

[SI + d8] [DI + d8] [BP + d8] [BX + d8]

[BX + IS + d16] [BX + DI + d16] [BP + IS + d16] [BP + DI + d16]

[SI + d16] [DI + d16] [BP + d16] [BX + d16]

D8 - estancias de 8 bits firmado desplazamiento inmediato (por ejemplo: 22, 55h, -1, etc...). D16 - estancias para 16 bits firmado desplazamiento inmediato (por ejemplo: 300, 5517h, -259, etc...). El desplazamiento puede ser un valor inmediato o el desplazamiento de una variable, o incluso ambos. Si hay varios valores, ensamblador evalúa todos los valores y calcula un valor inmediato. El desplazamiento puede ser dentro o fuera de los símbolos [ ], ensamblador genera el mismo código de máquina para ambas formas. El desplazamiento es un valor con signo, por lo que puede ser positivo o negativo. Generalmente el compilador se encarga de la diferencia entre d8 y d16, y se genera el código de máquina.

Por ejemplo, supongamos que el DS = 100, BX = 30, SI = 70. El modo de direccionamiento siguiente: [SI] + bx + 25 es calculada por el procesador a esta dirección física: 100 * 16 + 30 + 70 + 25 = 1725. Por defecto DS registro de segmento se utiliza para todos los modos, excepto aquellos con BP , para registrar estos SS registro de segmento se utiliza. Hay una manera fácil de recordar todas las combinaciones posibles con este gráfico:

Puede formar todas las combinaciones válidas por tomar sólo un elemento de cada columna o saltando la columna por no tomar nada de él. Como ves BX y BP nunca van juntos. SI Y DI también no van juntos. Aquí hay un ejemplo de un modo de direccionamiento válido: [BX+5] , [BX+SI] , [DI+BX-4]

El valor de registro de segmento (CS, DS, SS, ES) se denomina segmento, y el valor de finalidad registrar (BX, IS, DI, BP) se denomina desplazamiento. Cuando DS contiene el valor 1234h y si contiene el valor 7890h también puede ser registrada como 1234:7890. La dirección física será 1234h * 10h + 7890h = 19BD0h. Si cero es agregado a un número decimal se multiplica por 10, sin embargo 10h = 16, de manera que si el cero es agregado a un valor hexadecimal, se multiplica por 16, por ejemplo: 7h = 7 70h = 112

Con el fin de decir el compilador sobre el tipo de datos, estos prefijos debe utilizarse: Ptr - byte a byte. Ptr - palabra por palabra (dos bytes). Por ejemplo: byte ptr [BX] ; Acceso de byte o word ptr [BX] ; palabra de acceso. Ensamblador admite prefijos cortos: B. - por byte ptr W - para word ptr. En ciertos casos el ensamblador puede calcular automáticamente el tipo de datos.

Instrucción MOV Copia el segundo operando (fuente) para el primer operando (destino). El operando de origen puede ser un valor inmediato, el generalFinalidad registrar o ubicación de memoria. El registro de destino puede ser un registro de propósito general, o la ubicación de la memoria. Los operandos deben ser del mismo tamaño, lo que puede ser un byte o un Word. Estos tipos de operandos son compatibles: MOV REG, memoria Memoria MOV, REG MOV REG REG Memoria inmediata, MOV MOV REG, inmediata REG: AX, BX, CX, DX, ah, AL, BL, BH, CH, CL, DH, DL, DI, IS, BP y SP. Memoria: [BX], [BX+IS+7], variable, etc... Immediate: 5, -24, 3FH, 10001101b, etc...

Para el segmento registra sólo estos tipos de mov son compatibles: MOV SREG, memoria Memoria, SREG MOV MOV, SREG REG. MOV SREG REG SREG: DS, ES, SS, y sólo como segundo operando: CS. REG: AX, BX, CX, DX, ah, AL, BL, BH, CH, CL, DH, DL, DI, IS, BP y SP. Memoria: [BX], [BX+IS+7], variable, etc...

La instrucción mov puede utilizarse para establecer el valor de los registros CS e IP. Aquí está un breve programa que muestra el uso de la instrucción mov: ORG 100h ; esta directiva necesaria para un simple de 1 segmento de programa .com. MOV AX, 0B800h ; define el hacha a valor hexadecimal de B800h. DS, MOV AX ; copia el valor de AX para DS. MOV CL, 'A' ; definir CL al código ASCII de la 'A', es 41h. MOV CH, 1101_1111b ; ajuste CH al valor binario. MOV BX, 15EH ; definir BX 15EH. [], MOV BX CX ; copiar contenidos de CX en memoria en B800:015E RET ; devuelve al sistema operativo.

Puede copiar y pegar el programa anterior a la EMU8086 editor de código y presione [] botón compilar y emular (o pulse la tecla F5 en el teclado). La ventana del emulador debe abrir con este programa cargado, haga clic en elbotón [ ] en un solo paso y observar los valores de registro.

Cómo copiar y pegar: 1. Seleccione el texto, haga clic con el ratón antes de que el texto y arrástrelo hacia abajo hasta que todo esté seleccionado. 2. Pulse la combinación Ctrl + C para copiar. 3. Ir a emu8086 editor de código fuente y pulse la combinación Ctrl + V para pegar.

Como puede adivinar, ";" se utiliza para comentarios, nada después de ";" symbol es ignorado por el compilador.

Usted debe ver algo como esto cuando el programa termina:

En realidad el mencionado programa escribe directamente a la memoria de vídeo, así que usted puede ver que MOV es una instrucción muy potente

4) ensamblador 8086 Tutorial para principiantes (parte 3) Variables Variable es una ubicación de memoria. Para un programador es mucho más fácil tener algún valor deben guardarse en una variable denominada "var1" y luego en la dirección 5A73:235B, especialmente cuando usted tiene 10 o más variables. Nuestro compilador soporta dos tipos de variables: Byte y Word. Sintaxis para una declaración de variable: Nombre Valor en DB Nombre Valor DW DB - estancias para Definir Byte. DW - estancias para Definir Word. Nombre : puede ser cualquier combinación de letras o dígitos, aunque debe comenzar con una letra. Es posible declarar variables sin nombre por no especificar el nombre (esta variable tendrá una dirección pero sin nombre). - El valor puede ser cualquier valor numérico en cualquier sistema de numeración compatibles (hexadecimal, binario o decimal), o "?" symbol para variables no inicializadas.

Como usted probablemente sabe de la parte 2 de este tutorial, instrucción mov se utiliza para copiar valores desde el origen hasta el destino. Veamos otro ejemplo con instrucción mov:

ORG 100h MOV AL, var1 MOV BX, var2 RET ; detiene el programa. VAR1 DB 7 var2 DW 1234h

Copie el código de arriba a la EMU8086 editor de código fuente, y pulsar la tecla F5 para compilar y cargar en el emulador. Usted debe conseguir algo como esto:

Como puede ver, esta opción se parece mucho a nuestro ejemplo, excepto que las variables son reemplazados con ubicaciones de memoria real. Cuando el compilador convierte el código máquina, reemplaza automáticamente todos los nombres de variables con sus desplazamientos. De forma predeterminada segmento es cargado en el registro DS (cuando se cargan archivos COM el valor de registro DS está configurado con el mismo valor como registro CS (segmento de código). En la lista de memoria primera fila es un desplazamiento, segunda fila es un valor hexadecimal, la tercera fila es el valor decimal, y la última fila es un valor de caracteres ASCII.

Compilador no es sensible a mayúsculas y minúsculas, por lo que "VAR1var1 " y "" se refieren a la misma variable. El desplazamiento de var1 es 0108h, y dirección completa es 0B56:0108. El desplazamiento de var2 es 0109h, y dirección completa es 0B56:0109, esta variable es una palabra así que ocupa 2 bytes. Se supone que se almacena en el byte bajo la dirección inferior, por lo que 34h está situada antes de las 12h. Usted puede ver que hay algunas otras instrucciones después de la instrucción RET, esto sucede porque disassembler no tiene la menor idea de donde los datos se inicia, sólo procesa los valores en la memoria y se entiende como válidas las instrucciones (8086 aprenderemos más tarde). Incluso puede escribir el mismo programa usando la directiva DB solamente: ORG 100h ; una directiva sólo para hacer un simple archivo .com (se expande en ningún código). DB 0A0h DB 08h DB 01h DB 8Bh DB 1Eh DB 09h DB 01h DB 0c3h 7 DB DB 34h DB 12h

Copie el código de arriba a la EMU8086 editor de código fuente, y pulsar la tecla F5 para compilar y cargar en el emulador. Usted debe tener el mismo código desensamblado, y la misma funcionalidad! Como puede adivinar, el compilador convierte el código fuente del programa para el conjunto de bytes, este juego se llama código de máquina, procesador entiende el código máquina y lo ejecuta.

ORG 100h es una directiva del compilador (compilador indica cómo manejar el código fuente). Esta directiva es muy importante cuando se trabaja con variables. Indica que el archivo ejecutable del compilador se cargarán en el desplazamiento de 100h (256 bytes), por lo que el compilador debe calcular la dirección correcta para todas las variables cuando se reemplaza los nombres de variables con sus desplazamientos. Las directivas no son nunca convierten a cualquier código máquina real. ¿Por qué archivo ejecutable cargado en el desplazamiento de 100h? Sistema operativo mantiene algunos datos sobre el programa en los primeros 256 bytes del segmento de código (CS), tales como parámetros de línea de comandos, etc. Aunque esto es cierto para los archivos COM, EXE archivos se cargan en el desplazamiento de 0000, y generalmente usan segmento especial de variables. Quizás hablaremos más acerca de los archivos EXE, más tarde.

Las matrices Las matrices pueden ser vistos como cadenas de variables. Una cadena de texto es un ejemplo de una matriz de bytes, cada carácter se presenta como un valor de código ASCII (0..255). Aquí están algunos ejemplos: definición de matriz a DB, 48h, 65h, 6CH, 6CH, 6FH, 00h b DB 'hola', 0 b Es una copia exacta de una matriz, cuando el compilador ve una cadena entre comillas se convierte automáticamente al conjunto de bytes. Este gráfico muestra una parte de la memoria donde estas cabinas son declarados:

Puede acceder al valor de cualquier elemento de la matriz usando corchetes, por ejemplo: MOV AL, a[3]. También puede utilizar cualquiera de los índice de memoria los registros BX, IS, DI, BP, por ejemplo: MOV IS, 3 MOV AL, un[si]

Si necesita declarar una matriz grande puede usar los paquetes de actualización de operador. La sintaxis para el DUP: Número DUP ( value(s) ) Number : número de duplicar para hacer (cualquier valor constante). Valor - expresión que DUP se duplicaran. Por ejemplo: c DB 5 dup(9) es una forma alternativa de declarar: c DB 9, 9, 9, 9, 9 Un ejemplo más: D DB 5 dup(1, 2) es una forma alternativa de declarar: D DB 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 Por supuesto, puede usar DW en vez de DB si es necesario para mantener los valores mayores de 255 o inferior a -128. DW no puede utilizarse para declarar cadenas.

Obtener la dirección de una variable Hay LEA (Carga dirección efectiva) instrucción operador OFFSET y alternativas. Ambos offset y lea puede utilizarse para obtener la dirección de desplazamiento de la variable. LEA es más potente porque también le permite obtener la dirección de un índice de variables. Obteniendo la dirección de la variable

puede ser muy útil en algunas situaciones, por ejemplo cuando se necesita para pasar parámetros a un procedimiento.

Recordatorio: A fin de indicar al compilador acerca del tipo de datos, estos prefijos debe utilizarse: PTR - byte a byte. PTR - palabra por palabra (dos bytes). Por ejemplo:

BYTE PTR [BX] ; Acceso de byte. WORD PTR [BX] ; palabra de acceso. Emu8086 admite prefijos cortos: B. - Por BYTE PTR W - para WORD PTR. En ciertos casos el ensamblador puede calcular automáticamente el tipo de datos.

Aquí es el primer ejemplo:

ORG 100h MOV AL, VAR1 ; comprobar el valor de VAR1 desplazándolo a AL. LEA BX, VAR1 ; obtiene la dirección de var1 en BX. MOV BYTE PTR [BX], 44h ; modificar el contenido de var1. MOV AL, VAR1 ; comprobar el valor de VAR1 desplazándolo a AL. RET. VAR1 DB 22h Final

Aquí hay otro ejemplo, que utiliza en lugar de OFFSET LEA:

ORG 100h

MOV AL, VAR1 ; comprobar el valor de VAR1 desplazándolo a AL. MOV BX, OFFSET VAR1 ; obtiene la dirección de var1 en BX. MOV BYTE PTR [BX], 44h ; modificar el contenido de var1. MOV AL, VAR1 ; comprobar el valor de VAR1 desplazándolo a AL. RET. VAR1 DB 22h Final

Ambos ejemplos tienen la misma funcionalidad. Estas líneas: LEA BX, var1 MOV BX, OFFSET VAR1 Incluso son compilados en el mismo código de máquina: MOV BX, num num es un valor de 16 bits de la variable desplazamiento. Por favor, note que sólo estos registros pueden ser utilizados dentro de corchetes (como punteros de memoria): BX, IS, DI, BP! (Véase la parte anterior del tutorial).

Constantes Al igual que las variables son constantes, pero existen sólo hasta que se compila el programa (montado). Después de la definición de una constante su valor no puede ser cambiado. Para definir constantes EQU directiva se usa: Nombre EQU < cualquier expresión > Por ejemplo: K EQU 5 MOV AX, k

El ejemplo anterior es funcionalmente idéntico al código: MOV AX, 5

Puede ver las variables mientras se ejecuta el programa seleccionando "Variables" de la "Ver" Menú del emulador.

Para ver matrices que se debe hacer clic en una variable y establecer elementos de propiedad tamaño de la matriz. En lenguaje ensamblador no son tipos de datos estrictos, de manera que cualquier variable puede ser presentada como una matriz. Variable puede visualizarse en cualquier sistema de numeración: HEX - hexadecimal (base 16). BIN - binario (base 2). OCT - octal (base 8). Firmado - firmado decimal (base 10). No firmada : signo decimal (base 10). CHAR - ASCII Código char (hay 256 símbolos, algunos símbolos son invisibles).

Puede editar el valor de una variable cuando el programa se está ejecutando, simplemente haga doble clic en él o selecciónelo y haga clic en el botón Editar. Es posible introducir números en cualquier sistema, números hexadecimales deben tener elsufijo " h ", "b" binarios, octales sufijo

"o" sufijo, números decimales no requieren ningún sufijo. La cadena puede ser introducidos de esta forma: 'Hola mundo', 0 Esta cadena es cero (terminado). Las matrices pueden ser introducidos de esta forma: 1, 2, 3, 4, 5 (La matriz puede ser matriz de bytes o palabras, depende de si ha seleccionado una palabra o byte para editar variable). Las expresiones se convierten automáticamente, por ejemplo: cuando se introduce esta expresión: 5 + 2 se convertirá en 7 etc...

5) ensamblador 8086 Tutorial para principiantes (parte 4)

se

Interrumpe Las interrupciones pueden ser vistos como una serie de funciones. Estas funciones hacen que el aprendizaje sea mucho más fácil, en lugar de escribir un código para imprimir un carácter simplemente puede llamar a la interrupción y lo hará todo por usted. Hay también interrumpir funciones que trabajan con disco duro y otro hardware. Llamamos funciones tales interrupciones de software. También son activados por interrupciones de hardware diferentes, estos son los llamados interrupciones de hardware. Actualmente estamos interesados en interrupciones de software solamente.

Para realizar una interrupción de software hay una instrucción INT, tiene una sintaxis sencilla: El valor INT Donde el valor puede ser un número entre 0 y 255 (o 0 a 0FFh), generalmente utilizaremos los números hexadecimales. Usted puede pensar que hay sólo 256 funciones, pero eso no es correcto. Cada interrupción pueden tener sub-funciones. Para especificar una sub-función AH registro deben establecerse antes de llamar a la interrupción. Cada interrupción puede tener hasta 256 sub-funciones (así obtenemos 256 * 256 = 65536 funciones). En general AH registro se utiliza en otros registros, pero a veces puede estar en uso. Generalmente, otras se utilizan registros para pasar parámetros y datos para sub-función. El siguiente ejemplo utiliza INT 10h subfunción 0Eh escriba un mensaje "Hello!". Esta función muestra un carácter en la pantalla, avanzar el cursor y desplazar la pantalla según sea necesario. ORG 100h ; Directiva para hacer un simple archivo .com. ; La subfunción que estamos utilizando ; No modifica el registro de AH ; return, de modo que podamos establecer sólo una vez. MOV AH, 0Eh ; seleccione sub-función. ; INT 10h / 0Eh sub-función

; Recibe un código ASCII del carácter ; que se imprimirán ; en al registro. MOV AL, 'H' ; código ASCII: 72 INT 10h ; print it! MOV AL, 'e' ; código ASCII: 101 INT 10h ; print it! MOV AL, 'l' ; código ASCII: 108 INT 10h ; print it! MOV AL, 'l' ; código ASCII: 108 INT 10h ; print it! MOV AL, 'o' ; código ASCII: 111 INT 10h ; print it! MOV AL, '!' ; código ASCII: 33 INT 10h ; print it! RET ; devuelve al sistema operativo.

Copie y pegue el programa anterior a la EMU8086 editor de código fuente y, a continuación, pulse [] botón compilar y emular. Ejecutarlo! Consulte list of supported interrupts para obtener más información acerca de las interrupciones.

6) ensamblador 8086 Tutorial para principiantes (parte 5) Biblioteca de funciones comunes emu8086.inc Para facilitar la programación hay algunas funciones comunes que pueden ser incluidos en el programa. Para realizar su programa utilizar funciones definidas en otro archivo debe usar la directiva Include seguida de un nombre de archivo. Compilador busca automáticamente el archivo en la misma carpeta donde está ubicado el archivo de código fuente, y si no puede encontrar el archivo allí busca en SC carpeta. Actualmente, no puede ser capaz de comprender plenamente el contenido de la EMU8086.inc (ubicado en la carpeta Inc), pero está bien, ya que sólo necesita comprender qué es lo que puede hacer. Para utilizar cualquiera de las funciones de la EMU8086.inc debe tener la siguiente línea al comienzo del archivo de origen: Incluyen "emu8086.inc'

Emu8086.inc define las macros siguientes: Char - macro PUTC con 1 parámetro, imprime un carácter ASCII en la posición actual del cursor. GOTOXY col, fila - macro con 2 parámetros, se establece la posición del cursor. Cadena de impresión - macro con 1 parámetro, imprime una cadena. Cadena PRINTN - macro con 1 parámetro, imprime una cadena. Lo mismo que imprimir, pero agrega automáticamente "retorno de carro" al final de la cadena. CURSOROFF - desactiva el cursor de texto.

CURSORON - Activa el cursor de texto. Para utilizar cualquiera de las anteriores macros simplemente escriba su nombre en algún lugar de su código, y si se requiere parámetros, por ejemplo:

Incluir emu8086.inc ORG 100h PRINT "Hello World!" GOTOXY 10, 5 PUTC 65 ; 65 - es un código ASCII para 'A' PUTC 'B'. RET ; volver al sistema operativo. Fin ; Directiva para detener el compilador.

Cuando el compilador procesará su código fuente busca la EMU8086. archivo inc para las declaraciones de las macros y reemplaza los nombres de macros con código real. Generalmente las macros son relativamente pequeñas piezas de código, uso frecuente de una macro puede hacer que tu ejecutable demasiado grande (procedimientos son mejores para la optimización de tamaño).

Emu8086.inc también define los procedimientos siguientes: PRINT_STRING - Procedimiento para imprimir una cadena terminada en nulo en la posición actual del cursor, recibe la dirección de cadena en DS:Si registrarse. Utilizar declare: DEFINE_PRINT_STRING antes del fin de la directiva. Peste - Procedimiento para imprimir una cadena terminada en nulo en la posición actual del cursor (como print_string), pero recibe la dirección de la cadena de la pila. La cadena terminada en cero debería definirse justo después de la instrucción CALL. Por ejemplo: Llame peste Db 'Hello World!', 0 Utilizar declare: DEFINE_PESTA antes del fin de la directiva.

GET_STRING - Procedimiento para obtener una cadena terminada en nulo de un usuario, la cadena recibida se escribe en la memoria intermedia en DS:DI, tamaño de buffer debe estar en DX. Procedimiento detiene la entrada cuando se pulsa 'Enter'. Utilizar declare: Definir_GET_STRING antes del fin de la directiva. CLEAR_SCREEN - Procedimiento para borrar la pantalla, (hecho por el desplazamiento de toda la ventana de la pantalla), y ajustar la posición del cursor al comienzo de la misma. Utilizar declare: Definir_CLEAR_SCREEN antes del fin de la directiva. SCAN_NUM - procedimiento que obtiene el número firmado varios dígitos desde el teclado y almacena el resultado en el registro CX. Utilizar declare: Definir_scan_NUM antes del fin de la directiva. PRINT_NUM - procedimiento en el que se imprime un número firmado en el registro AX. Utilizar declare: Definir_PRINT_NUM y definir_PRINT_NUM_UNS antes del fin de la directiva. PRINT_NUM_UNS - procedimiento en el que se imprime un número sin signo en el registro AX. Utilizar declare: Definir_PRINT_NUM_UNS antes del fin de la directiva. Para utilizar cualquiera de los procedimientos descritos anteriormente, primero debería declarar la función en la parte inferior de tu archivo (pero antes del final de la directiva) y, a continuación, utilice la instrucción CALL seguido de un nombre de procedimiento. Por ejemplo:

Incluyen "emu8086.inc' ORG 100h LEA IS, msg1 ; pedir el número Llamada print_string ; Llame a scan_num ; obtener número de CX. MOV AX, CX ; copia el número AX. ; Imprimir la siguiente cadena: Llame peste DB 13, 10, "Se han introducido: ' 0 Llamada print_num ; número de impresión en AX.

RET ; volver al sistema operativo. Msg1 DB 'Introduzca el número: ' 0 Definir_scan_NUM DEFINE_PRINT_STRING Definir_PRINT_NUM Definir_PRINT_NUM_UNS ; requerida para imprimir_num. DEFINE_PESTA Fin ; Directiva para detener el compilador.

Primer compilador procesa las declaraciones (estas son sólo las macros que regularmente se expanden a procedimientos). Cuando el compilador obtiene a la instrucción CALL reemplaza el nombre de procedimiento con la dirección del código donde se declara el procedimiento. Cuando se ejecuta la instrucción CALL se transfiere el control al procedimiento. Esto es bastante útil, ya que incluso si llama al mismo procedimiento 100 veces en el código tendrá todavía relativamente pequeño tamaño de ejecutable. Parece complicado, ¿no es así? Eso está muy bien, con el tiempo aprenderá más, actualmente es necesario que comprenda el principio básico.

7) ensamblador 8086 Tutorial para principiantes (parte 6) Instrucciones aritméticas y lógicas La mayoría de las instrucciones aritméticas y lógicas afectan al registro de estado del procesador (o banderas)

Como puede ver hay 16 bits en este registro, cada bit se denomina una bandera y puede tomar un valor de 1 o 0. Lleve Bandera (CF) - Este indicador está fijado en 1, cuando hay un desbordamiento unsigned. Por ejemplo, cuando se agrega bytes 255 + 1 (resultado no está en el rango 0...255). Cuando no hay ninguna inundación este indicador está fijado en 0. Bandera de cero (ZF) - 1 cuando el resultado es cero. Para ninguno, cero resultados este indicador está fijado en 0. Signo distintivo (SF) - establecer a 1 cuando el resultado es negativo. Cuando el resultado es positivo , se establece en 0. En realidad este indicador toma el valor del bit más significativo.

Indicador de desbordamiento (DE) - 1 cuando hay firmado un desbordamiento. Por ejemplo, cuando se agrega bytes 100 + 50 (resultado no está en el rango de 128...127). Bandera de paridad (PF) : este indicador está fijado en 1, cuando hay un número par de bits en consecuencia, y a 0 cuando hay un número impar de bits. Incluso si el resultado es una palabra sólo 8 bits de baja son analizados! Pabellón Auxiliar (AF) - Set 1 si existe un unsigned desbordamiento para low nibble (4 bits). Habilitar indicador de interrupción (SI) - Si este indicador está fijado en 1 CPU reacciona a interrupciones desde dispositivos externos. Indicador de dirección (DF) - Este indicador es utilizado por algunas instrucciones para procesar los datos de las cadenas, si este indicador está fijado en 0 , el tratamiento se realiza hacia adelante, cuando este indicador está fijado en 1, el tratamiento se realiza hacia atrás.

Hay 3 grupos de instrucciones.

Primer grupo: agregar, SUB,CMP Y , test, o, XOR Estos tipos de operandos son compatibles: REG, memoria, REG REG, REG, memoria inmediata, inmediato REG. REG: AX, BX, CX, DX, ah, AL, BL, BH, CH, CL, DH, DL, DI, IS, BP y SP. Memoria: [BX], [BX+IS+7], variable, etc... Immediate: 5, -24, 3FH, 10001101b, etc... Después de la operación entre operandos, resultado siempre se almacenan en el primer operando. Instrucciones de prueba de CMP y afectar las banderas y no almacenar un resultado (estas instrucciones se utilizan para tomar decisiones durante la ejecución del programa).

Estas instrucciones sólo afectan a estas banderas: CF SF ZF , ,, , pf, AF. ADD - Añadir segundo operando en primer lugar. SUB - restar el segundo operando en primer lugar. CMP - restar el segundo operando desde la primera de las banderas sólo. Y - Y lógico entre todos los bits de los dos operandos. Estas reglas se aplican: 1Y1=1 1Y0=0 0Y1=0 0Y0=0 Como puede ver, obtendremos 1 sólo si ambos bits son 1. Prueba - el mismo que para las marcas, pero sólo. O - O lógico entre todos los bits de los dos operandos. Estas reglas se aplican: 1O1=1 1o0=1 0o1=1 0O0=0 Como puede ver, obtendremos 1 cada vez, cuando al menos uno de los bits es 1. XOR lógico - operación OR exclusiva (XOR) entre todos los bits de los dos operandos. Estas reglas se aplican: 1 XOR 1 = 0 1 0 = 1 XOR 0 XOR 1 = 1 0 XOR 0 = 0 Como puede ver, obtendremos 1 bits cada vez que son diferentes entre sí.

Segundo grupo: MUL, IMUL, DIV, IDIV

Estos tipos de operandos son compatibles: Memoria reg. REG: AX, BX, CX, DX, ah, AL, BL, BH, CH, CL, DH, DL, DI, IS, BP y SP. Memoria: [BX], [BX+IS+7], variable, etc... Instrucciones IMUL y mul afectan estos indicadores sólo: CF, de Cuando el resultado es superior al tamaño operando estos indicadores se establece en 1, cuando el resultado encaja en tamaño operando estos indicadores se establece en 0. IDIV y DIV para las banderas son indefinidos. MUL - Unsigned multiplicar: Cuando un operando es un byte: AX = AL * operando. Cuando un operando es una palabra: (DX) = Ax AX * operando. IMUL - Firmado multiplicar: Cuando un operando es un byte: AX = AL * operando. Cuando un operando es una palabra: (DX) = Ax AX * operando. DIV - Unsigned dividir: Cuando un operando es un byte: Al = Ax / operando AH = resto (módulo). . Cuando un operando es una palabra: AX = (DX AX) / operando DX = resto (módulo). . IDIV - Firmado dividir:

Cuando un operando es un byte: Al = Ax / operando AH = resto (módulo). . Cuando un operando es una palabra: AX = (DX AX) / operando DX = resto (módulo). .

Tercer grupo: INC, DEC, NOT NEG Estos tipos de operandos son compatibles: Memoria reg. REG: AX, BX, CX, DX, ah, AL, BL, BH, CH, CL, DH, DL, DI, IS, BP y SP. Memoria: [BX], [BX+IS+7], variable, etc... INC, DEC instrucciones afectan estos indicadores sólo: ZF, SF, de, pf, AF. Ni instrucción no afecta a las Banderas! NEG instrucción afecta a estos indicadores sólo: CF SF ZF , ,, , pf, AF. - No invertir cada bit de operando. NEG - Hacer operando de complemento a dos (negativo). En realidad invierte cada bit de operando y, a continuación, agrega 1. Por ejemplo, 5 será -5 y -2 será 2.

8) ensamblador 8086 Tutorial para principiantes (parte 7) Control de flujo de programa Controlar el flujo del programa es una cosa muy importante, es en este punto donde el programa puede tomar decisiones de acuerdo con ciertas condiciones. Saltos incondicionales La instrucción básica que transfiere el control a otro punto en el programa JMP. La sintaxis básica de instrucción JMP: Etiqueta JMP Para declarar una etiqueta en tu programa, simplemente escriba su nombre y agregue ":" al final, la etiqueta puede ser cualquier combinación de caracteres pero no puede

empezar con un número, por ejemplo, aquí hay 3 rótulo legal definiciones: Label1 label2::: Etiqueta puede ser declarada en una línea separada o ante cualquier otra instrucción, por ejemplo: X1: MOV AX, 1 X2: MOV AX, 2 He aquí un ejemplo de la instrucción JMP:

Org

100h

Mov ax, 5 hacha a 5. Mov definir bx a 2. Jmp

calc

; define el bx, 2 ;

; ir a 'CALC'.

Espalda: jmp detener

; ir a 'Stop'.

Calc: add ax, bx bx ; añadir a AX. Jmp atrás ; ir 'atrás'. Stop: Ret

; volver al sistema operativo.

Por supuesto, hay una manera más fácil de calcular algunas de dos números, pero aún así es un buen ejemplo de la instrucción jmp. Como se puede ver en este ejemplo jmp es capaz de transferir el control hacia adelante y hacia atrás. Se puede saltar en cualquier lugar en el segmento de código actual (65.535 bytes). Corto saltos condicionales

A diferencia de la instrucción jmp que realiza un salto incondicional, hay instrucciones de que hacer un salto condicional (salto sólo cuando algunas condiciones son en la ley). Estas instrucciones se dividen en tres grupos, el primer grupo sólo prueba única bandera, segundo compara números como firmado, y la tercera compara números como unsigned. Instrucciones de salto que la prueba única bandera Instrucciones

Descripción

Condición

Instrucciones opuesto

JZ , JE

Si el salto (igual a cero).

ZF = 1

El JNE, JNZ

JC , JB, JNAE

Saltar si llevar (por debajo, pero no por encima de la igualdad).

CF = 1

JNC, JNB, JAE

JS

Saltar si firmar.

SF = 1

JNS

JO

Saltar si el desbordamiento.

De = 1

JNO

JPE, JP

Incluso si la paridad de salto.

PF = 1

JPO

JNZ , JNE

Saltar si no nulo (no igual).

ZF = 0

JZ, JE

JNC , JNB, JAE

Saltar si no llevar (no por debajo, por encima de la igualdad).

CF = 0

JC, JB, JNAE

JNS

Saltar si no firmar.

SF = 0

JS

JNO

Saltar si no se desborde.

De = 0

JO

Los JPO, JNP

Saltar si la paridad impar (sin paridad).

PF = 0

JPE, JP

Como ya se puede observar que hay algunas instrucciones que hagan lo mismo, eso es correcto, que incluso se montan en el mismo código de máquina, así que es bueno recordar que cuando compile JE instrucción - tendrá que desmontar como: JZ, JC está montada la misma como JB etc... diferentes nombres se utilizan para hacer que los programas sean más fáciles de entender, a código y lo más importante para recordar. muy compensado dissembler no tiene ni idea de qué era la instrucción original parezca que es el motivo por el que utiliza la mayoría de nombre común.

Si emular este código, verá que todas las instrucciones están ensambladas en JNB, el código de operación (opcode) para esta instrucción es 73h Esta instrucción tiene dos bytes de longitud fija, el segundo byte es el número de bytes que se van a agregar al registro de propiedad intelectual si la condición es verdadera. porque la instrucción tiene sólo 1 byte para mantener el desplazamiento se limita a pasar el control a -128 bytes o 127 bytes hacia adelante, este valor siempre es firmado.

Jnc un

jnb un

Jae un Mov ax, 4 A: mov ax, 5 de ret.

9) ensamblador 8086 Tutorial para principiantes (parte 8) Procedimientos

Procedimiento es una parte de código que puede ser llamado desde su programa a fin de realizar alguna tarea específica. Realizar procedimientos de programa más estructural y más fáciles de entender. Generalmente el procedimiento devuelve al mismo punto desde donde se llamó. La sintaxis de declaración de procedimiento: Nombre PROC ; Aquí va el código ; del procedimiento ... Nombre RET ENDP

Nombre : es el nombre del procedimiento, el mismo nombre que debería estar en la parte superior y la inferior, esta se utiliza para comprobar el correcto cierre de procedimientos. Probablemente, usted ya sabe que la instrucción RET se utiliza para volver al sistema operativo. En la misma instrucción se utiliza para retorno de procedimiento (sistema operativo realmente ve su programa como un procedimiento especial). PROC y ENDP son directivas del compilador, por lo que no están montados en cualquier código máquina real. Compilador recuerda la dirección del procedimiento. La instrucción call se utiliza para llamar a un procedimiento. Aquí está un ejemplo:

ORG 100h Llamada m1 MOV AX, 2 RET ; volver al sistema operativo. M1 PROC MOV BX, 5 RET ; volver al llamador. M1 ENDP Final

En el ejemplo anterior se llama al procedimiento m1, HACE MOV BX, 5, y se regresa a la instrucción siguiente después de llamar: MOV AX, 2. Hay varias maneras de pasar parámetros al procedimiento, la manera más sencilla de pasar parámetros es mediante el uso de registros, aquí es otro ejemplo de un procedimiento que recibe dos parámetros en AL y BL registra, multiplica estos parámetros y devuelve el resultado en el registro AX:

ORG 100h MOV AL, 1 MOV BL, 2 Llamada m2 Llamada m2 Llamada m2 Llamada m2 RET ; volver al sistema operativo. M2 PROC MUL BL ; AX = AL * BL. RET ; volver al llamador. M2 ENDP Final

En el ejemplo anterior al valor del registro se actualizan cada vez que se llama al procedimiento, BL registro permanece inalterado, por lo que este algoritmo calcula 2 en poder de 4, por lo que el resultado final en el registro AX es 16 (o 10h).

Aquí va otro ejemplo, que utiliza un procedimiento para imprimir un mensaje: ¡Hola, mundo!

ORG 100h LEA IS, msg ; Cargar la dirección de msg para SI.

Llamada print_me RET ; volver al sistema operativo. ; ============================================================= ; Este procedimiento imprime una cadena, la cadena debe ser NULL ; Finaliza (tienen cero en el extremo) ; La cadena dirección debería ser en SI registro: Print_me PROC Next_char: B CMP.[si], 0 ; compruebe por cero para detener JE detener ; MOV AL, [SI] ; próximo get char ASCII. MOV AH, 0Eh ; teletipo el número de función. INT 10h ; Utilizar interrumpir para imprimir un char en AL. Agregar IS, 1 ; advance índice de matriz de cadenas. JMP next_CHAR ; volver atrás, y otro de tipo char. Stop: RET ; volver al llamador. print_me ENDP ; ============================================================= Msg DB "Hello World!" 0 ; cadena terminada en nulo. Final

"B" - prefijo antes [SI] significa que necesitamos comparar bytes, no palabras. Cuando es necesario comparar las palabras agregar "w" en lugar del prefijo. Cuando uno de los operandos es respecto de un registro no es necesario porque el compilador sabe el tamaño de cada registro.

10) ensamblador 8086 Tutorial para principiantes (parte 9) La pila La pila es un área de memoria para mantener los datos temporales. La pila es utilizada por la instrucción Call para mantener la dirección de retorno de procedimiento, instrucción RET obtiene este valor de la pila y vuelva a ese desplazamiento. La misma cosa sucede cuando la instrucción INT pide una interrupción, se almacena en la pila flag register, segmento de código y desplazamiento. Instrucción IRET se utiliza para devolver de interrumpir la llamada. También podemos utilizar la pila para mantener cualquier otro dato, existen dos instrucciones que funcionan con la pila: PUSH - almacena el valor de 16 bits en la pila. POP - obtiene el valor de 16 bits desde la pila. Sintaxis de instrucción push: Empujar REG Empujar SREG Empujar la memoria Inmediata inserción REG: AX, BX, CX, DX, DI, IS, BP y SP. SREG: DS, ES, SS, CS. Memoria: [BX], [BX+IS+7], 16 bits variable, etc... Immediate: 5, -24, 3FH, 10001101b, etc...

La sintaxis de la instrucción POP: POP REG POP SREG Memoria POP REG: AX, BX, CX, DX, DI, IS, BP y SP. SREG: DS, ES, SS, (excepto CS). Memoria: [BX], [BX+IS+7], 16 bits variable, etc...

Notas: Trabajar con PUSH y POP sólo valores de 16 bits! Nota: sólo funciona con inmediata inserción 80186 CPU y más tarde!

Utiliza la pila LIFO (último en entrar primero en salir) algoritmo, esto significa que si queremos empujar estos valores uno por uno en la pila: 1, 2, 3, 4, 5 el primer valor que obtendremos será de pop 5, 4, 3, 2, y sólo entonces 1.

Es muy importante hacer igual número de PUSHy POP, de lo contrario la pila tal vez esté dañado y será imposible volver al sistema operativo. Como ya sabéis utilizamos la instrucción RET para volver al sistema operativo, de modo que cuando comienza un programa hay una dirección de retorno en la pila (generalmente es 0000h). La instrucción push y pop son especialmente útiles porque no tenemos demasiados registros para funcionar, por lo tanto, aquí hay un truco: Almacenar el valor original del registro en la pila (mediante PUSH).

Utilice el registro para cualquier propósito.

Restaurar el valor original del registro de pila (utilizando POP).

Aquí está un ejemplo: ORG 100h MOV AX, 1234h PUSH AX ; almacenar el valor de AX en la pila. MOV AX, 5678h ; modificar el valor de AX. POP AX ; restaurar el valor original de AX. RET. Final

Otro uso de la pila es para intercambiar los valores, aquí está un ejemplo:

ORG 100h MOV AX, 1212h ; almacenar 1212h en AX. MOV BX3434h ; store3434h en BX

PUSH AX ; almacenar el valor de AX en la pila. Empujar BX ; almacenar el valor de BX en la pila. POP AX AX ; establecer al valor original de BX. POP BX BX ; establecer al valor original de AX. RET. Final

El cambio ocurre porque utiliza la pila LIFO (último en entrar primero en salir) algoritmo, así que cuando nos empuje 1212h y luego 3434h, en pop por primera vez, vamos a conseguir 3434h y solamente después de 1212h.

El área de memoria de pila está establecido por SS (segmento de pila) Registro y SP (puntero de pila) registro. Generalmente el sistema operativo configura los valores de estos registros en el inicio del programa.

" Fuente" instrucción push hace lo siguiente: Restar 2 de registro SP. Escribir el valor de fuente a la dirección SS:SP. " " La instrucción pop destino hace lo siguiente: Escribir el valor en la dirección SS:SP al destino. Añadir 2 al registro SP.

La actual dirección apuntada por SS:SP se llama la parte superior de la pila. Para los archivos COM segmento de pila es generalmente el segmento de código, y el puntero de pila se ajusta al valor de 0FFFEh. En la dirección SS:0FFFEh almacena una dirección de retorno para la instrucción RET que se ejecuta en el final del programa. Puede ver visualmente el funcionamiento de pila haciendo clic en [] la pila de botón en la ventana del emulador. La parte superior de la pila está marcada con el signo " < ".

11) ensamblador 8086 Tutorial para principiantes (parte 10) Las macros Las macros son al igual que los procedimientos, pero no realmente. Las macros parecen procedimientos, sino que existen sólo hasta que el código se compila, luego de la compilación de todas las macros son reemplazados con instrucciones reales. Si se declara una macro y nunca utilizado en el código, el compilador simplemente ignorarlo. emu8086.inc Es un buen ejemplo de cómo las macros pueden utilizarse, este archivo contiene varias macros para que la codificación sea más fácil para usted. Definición de macro: Nombre MACRO [parámetros],...

ENDM

A diferencia de los procedimientos, las macros deben definirse por encima del código que utiliza, por ejemplo: MACRO MyMacro p1, p2, p3 MOV AX, p1 MOV BX, p2. MOV CX, p3 ENDM ORG 100h Mimacro 1, 2, 3 Mimacro 4, 5, DX RET.

El código anterior es ampliado en: MOV AX, 00001h MOV BX, 00002h MOV CX, 00003h MOV AX, 00004h MOV BX, 00005h MOV CX, DX

Algunos hechos importantes acerca de las macros y procedimientos: Cuando desee utilizar un procedimiento debe utilizar la instrucción Call, por ejemplo: Llame MyProc Si desea utilizar una macro, puede simplemente escribir su nombre. Por ejemplo: Mimacro Procedimiento se encuentra en alguna dirección específica en la memoria y, si se utiliza el mismo procedimiento 100 veces, la CPU va a transferir el control a esta parte de la memoria. El control se devuelve al programa por instrucción RET. La pila se usa para guardar la dirección de retorno. La instrucción de llamada toma alrededor de 3 bytes, por lo que el tamaño del archivo ejecutable de salida crece muy insignificante, no importa cómo muchas veces el procedimiento es utilizado. La macro se expande directamente en el código del programa. Así que si usted utiliza la misma macro 100 veces, el compilador se expande la macro 100 veces, haciendo el archivo ejecutable de salida más grande, cada vez todas las instrucciones de una macro se inserta. Usted debe usar o cualquier pila de registros de propósito general para pasar parámetros al procedimiento. Para pasar parámetros a la macro, puede simplemente escribir después del nombre de la macro. Por ejemplo: Mimacro 1, 2, 3 Para marcar el final de la macro ENDM directiva es suficiente. Para marcar el final del procedimiento, usted debe escribir el nombre del procedimiento ante la directiva ENDP.

Las macros son expandidas directamente en el código, por lo tanto, si hay etiquetas dentro de la definición de macro puede obtener la declaración de "duplicado" error cuando se utiliza macros para dos o más veces. Para evitar este problema, utilice la directiva local seguido por los nombres de las variables, etiquetas o nombres de procedimiento. Por ejemplo:

Mimacro2 MACRO Locales de label1, label2 CMP AX, 2 JE label1 CMP AX, 3 JE label2 Label1: INC AX Label2: Agregar AX, 2 ENDM

ORG 100h Mimacro2 Mimacro2 RET.

Si planea utilizar las macros en varios programas, puede ser una buena idea colocar todas las macros en un archivo separado. Colocar ese archivo en la carpeta Inc y uso incluyen la directiva de nombre de archivo a utilizar macros. Library of common functions - emu8086.inc Para ver un ejemplo de archivo.

12) ensamblador 8086 Tutorial para principiantes (parte 11). Hacer su propio sistema operativo

Normalmente, cuando se inicia un equipo intentará cargar el primer sector de 512 bytes (que es el cilindro 0, Cabeza 0, Sector 1) desde el disquete en la unidad A: para la ubicación de memoria 0000h:7C00h y darle el control. Si esto falla, el BIOS intenta utilizar el MBR del primer disco duro en su lugar. Este tutorial cubre el arranque desde una unidad de disquete, los mismos principios se utilizan para arrancar desde un disco duro. Pero el uso de una unidad de disquete tiene varias ventajas: Usted puede mantener su sistema operativo existente intacta (Windows, DOS, Linux, Unix, ser-os...). Es fácil y seguro para modificar el registro de arranque de un disquete. Ejemplo de un sencillo programa de arranque de disquete:

; Directiva para crear el archivo de arranque: #Make_boot# ; Boot record está cargado en 0000:7C00, ; por tanto, informar al compilador que requiera ; correcciones: ORG 7C00H PUSH CS ; asegúrese DS=CS POP DS Mensaje de carga ; dirección en is registrarse: LEA IS, msg ; Función teletipo id: MOV AH, 0Eh Imprimir: MOV AL, [SI] AL CMP, 0 JZ hecho INT 10h ; imprimir utilizando el teletipo. INC IS JMP IMPRIMIR ; Espere a que "cualquier tecla": hecho: MOV AH, 0 INT 16h

; Almacenar valor mágico en 0040h:0072h: ; 0000h - arranque en frío. ; 1234h - Arranque en caliente. MOV AX, 0040h DS, MOV AX W MOV.[0072h], 0000h ; el arranque en frío. JMP

0FFFFh:0000h

; Reiniciar!

New_line EQU 13, 10 Msg DB 'hola este es mi primer programa de arranque!' DB_nueva línea, "Presione cualquier tecla para reiniciar', 0

Copie el ejemplo anterior para el editor de código fuente y pulse emular. el emulador se carga automáticamente el archivo .bin a 0000h:7C00H (utiliza archivos .binf complementario para saber dónde cargar).

Se puede ejecutar como un programa ordinario, o puede usar la unidad virtual menú para escribir 512 bytes a 7c00h para el sector de arranque de una unidad de disco virtual (es "floppy_0" el archivo en c:\emu8086). Después de que su programa se escriben en la unidad de disquete virtual, puede seleccionar desde un disquete de arranque desde el menú de la unidad virtual.

Archivos .bin para registros de arranque están limitadas a 512 bytes (tamaño de sector). Si el nuevo sistema operativo va creciendo a lo largo de este tamaño, tendrá que usar un programa de arranque para cargar los datos de otros sectores (como micro-os_loader.asm ). Un ejemplo de un pequeño sistema operativo se puede encontrar en c:\emu8086\Ejemplos y "online": micro-os_loader.asm microos_kernel.asm

Crear extensiones para su sistema operativo (más de 512 bytes), puede utilizar sectores adicionales de un disquete. Se recomienda el uso dearchivos .bin " " para este propósito (para crear ".bin" Seleccionar Archivo "BIN Plantilla" desde "Archivo" -> "nuevo" menú). Escribir "" el archivo .bin para el disco virtual, seleccione "Escribir archivo .bin a disquete..." del menú "Disco Virtual" del emulador, usted debe escribir en cualquier lugar, pero el sector de arranque (que es el cilindro: 0, Jefe de Sector:: 0 , 1).

Puede usar esta utilidad para escribir archivos .bin para disquete virtual ("FLOPPY_0" Archivo "), en lugar deescribir 512 bytes a 7c00h a boot sector" Menú. Sin embargo, usted debe recordar que el archivo .bin que está diseñado para ser un registro de inicio siempre debe estar escrita en el cilindro: 0, 0, head: sector: 1 Ubicación del Sector de arranque: Cilindro: 0 Cabeza: 0 Sector: 1

Para escribir archivos .bin al disquete use writebin real.asm, compilarlo a com archivo y ejecutarlo desde la línea de comandos. Para escribir un registro de arranque Tipo: writebin loader.bin ; para escribir el tipo de módulo de kernel: writebin kernel.bin /k - El parámetro /k indica el programa para escribir el archivo en el sector 2, en lugar de sector 1. No importa en qué orden se escriben los archivos en la unidad de disquete, pero no importa donde usted escribe.

Mote: este no es el registro de arranque MS-DOS/Windows compatible, el sector de arranque no es incluso compatible con Linux o Unix, el sistema operativo no le permite leer o escribir archivos en este disco hasta que se vuelva a formatearlo, por lo tanto asegúrese de que el disquete se utiliza no contienen ninguna información importante. Sin embargo, puede escribir y leer cualquier cosa a y desde este disco con bajo nivel de acceso a disco interrupciones, incluso es posible proteger la información valiosa de los demás de esta manera; incluso si alguien obtiene el disco que probablemente pensará que es vacío y reformateará porque es la opción

predeterminada en el sistema operativo Windows... un buen tipo de auto destructivas portador de datos :).

Unidad de disquete idealizado y estructura de disquete:

Para un disquete: 1440 KB Disco tiene 2 lados, y hay 2 jefes; uno para cada lado (0..1), los cabezales de la unidad se mueva por encima de la superficie del disco en cada lado. (numerados 0..79). (1..18).

Cada lado tiene 80 cilindros

Cada cilindro tiene 18 sectores

Cada sector tiene 512 bytes.

El tamaño total del disco es: 2 x 80 x 18 x 512 = 1,474,560 Bytes. Nota: el MS-DOS (Windows) disquete formateado tiene ligeramente menos espacio libre en él (alrededor de 16,896 bytes) debido a que el sistema operativo necesita lugar para almacenar los nombres de los archivos y la estructura de directorios (a menudo llamado FAT o tabla de asignación del sistema de archivos). varios nombres de archivo menos espacio en disco. La forma más eficiente para almacenar archivos es escribir directamente a los sectores en lugar de utilizar el

sistema de archivos, y en algunos casos también es el modo más fiable, si usted sabe cómo usarlo. Leer sectores desde la unidad de disquete use INT 13h / AH = 02h.

13) ensamblador 8086 Tutorial para principiantes (parte 12) Control de dispositivos externos

Hay 7 dispositivos conectados al emulador: semáforos, el motor de pasos, pantalla LED, termómetro, impresora, robot y simple dispositivo de prueba. Puede ver los dispositivos cuando haga clic en "dispositivos virtuales" Menú del emulador. Para obtener información técnica, consulte la I/O ports sección de emu8086 referencia. En general, es posible utilizar cualquier CPU de la familia x86 para controlar todo tipo de dispositivos, la diferencia quizás en base I/O número de puerto, esto puede modificarse utilizando algunos complicados equipos electrónicos. Normalmente elarchivo " .bin " está escrito en la memoria de sólo lectura (ROM) chip, el sistema lee el programa desde ese chip, lo carga en la memoria RAM módulo y ejecuta el programa. Este principio se utiliza para muchos dispositivos modernos tales como hornos microondas y etc...

Semáforo

Normalmente para controlar los semáforos de una matriz (tabla) de valores se utiliza. En determinados períodos de tiempo se lee el valor de la matriz y enviados a un puerto. Por ejemplo: ; Dispositivo externo de control con microprocesador 8086. ; Prueba realista para c:\emu8086\dispositivos\Traffic_Luces.exe. #Start=_Luces de tráfico.exe# Nombre de "tráfico"

Mov ax, all_rojo 4, ax

Mov is, offset situación

Siguiente: mov ax, [si] 4, ax ; Espere 5 segundos (5 millones de microsegundos) mov cx, 4Ch ; 004C4B40h = 5.000.000 mov dx, 4B40h mov ah, 86h Int 15h

Agregar si, 2; la siguiente situación cmp si, sit_final jb next Mov is, offset situación Jmp siguiente

; FEDC_BA98_7654_3210 situación dw 0000_0011_0000_1100b s1 dw 0000_0110_1001_1010b s2 dw 0000_1000_0110_0001b s3 dw 0000_1000_0110_0001b s4 dw 0000_0100_1101_0011b sit_end = $

Todas_red

dot

0000_0010_0100_1001b

Stepper-Motor

El motor puede estar medio intervino girando en el par de imanes, seguido por un único y así sucesivamente. El motor puede estar lleno intervino girando en el par de imanes, seguido por otro par de imanes y al final seguido por un solo imán y así sucesivamente. La mejor manera de hacer pleno paso es realizar dos pasos. La mitad de paso es igual a 11,25 grados. Paso completo es igual a 22,5 grados. El motor puede girar tanto en el sentido de las agujas del reloj y contra-reloj-wise. Ver stepper_motor.asm en c:\emu8086\Ejemplos\ Vea también la I/O ports sección de emu8086 referencia.

Robot

Lista completa de conjunto de instrucciones del robot está dada en la I/O ports sección de la UEM8086 referencia. Para controlar el robot un complejo algoritmo debe utilizarse para lograr la máxima eficiencia. La forma más sencilla, pero muy ineficiente, es aleatorio moviendo algoritmo, vea robot.asm en c:\emu8086\Ejemplos\

También es posible utilizar una tabla de datos (al igual que para los semáforos), esto puede ser bueno si el robot trabaja siempre en el mismo entorno.

14) El Editor de código fuente

Con el ratón Editor admite las siguientes acciones del ratón: Acción del ratón

Resultado

L clic encima del texto

Cambia la posición de intercalación

Haga clic en el botón R

Muestra el menú de clic derecho

L-Botón pulsado durante la selección y arrastre

Mueve texto

Ctrl + L-Botón pulsado durante la selección y arrastre

Copia el texto

Haga clic sobre el botón L margen izquierdo

Selecciona la línea

Haga clic sobre el botón L margen izquierdo y arrastre

Selecciona varias líneas

Alt + L-Botón pulsado y arrastre

Seleccionar columnas de texto

L-Botón haga doble clic sobre el texto

Seleccionar palabra bajo el cursor

Girar la rueda del ratón IntelliMouse

Desplazarse por la ventana verticalmente

Solo haga clic en Rueda del ratón IntelliMouse

Seleccione la palabra bajo el cursor

Haga doble clic en la rueda de ratón IntelliMouse

Seleccione la línea bajo el cursor

Haga clic y arrastre la barra divisora

Dividir la ventana en varias vistas o ajustar la actual posición del divisor

Haga doble clic en la barra separadora

Dividir la ventana en la mitad en varias vistas o unsplit la ventana si ya dividida

Teclas de acceso directo del Editor: Combinación de teclas de comando ========================================================================== Alternar marcador Control + F2 Marcador siguiente F2 Marcador anterior Mayús + F2 Copiar Ctrl + C, Control + Insert Control de corte X + Mayús + Supr, Control + Alt + W Cortar la línea Control + Y. Cortar frase Control + Alt + K Pegar Control + V, Shift + Insert Deshacer Control + Z, Alt + Retroceso El Documento Final de Control + Fin Extensión del final del documento Control + Mayús + Fin Control + Inicio Inicio del documento Inicio de documento Extender Control + Mayús + Inicio Buscar Control + F, Alt + F3 Buscar siguiente F3 Buscar palabra siguiente Control + F3

Buscar anterior Mayús + F3 Buscar anterior palabra Control + Shift + F3 Buscar y reemplazar el Control + H, Control + Alt + F3 Vaya a la línea Control + G Vaya a coincidir con rodillera Control + ] Control + A Seleccionar todo Seleccionar la línea Control + Alt + F8 Seleccione Intercambiar Anchor Control + Mayús + X Insertar nueva línea encima de Control + Mayús + N Ficha Selección de sangría Selección anular sangría Mayús + Tab Aplicar tabulaciones a la selección Control + Mayús + T No aplicar tabulaciones a la selección Control + Shift + Space. Selección en minúsculas Control + L Control de selección en mayúsculas + U, Control + Shift + U Control de la palabra izquierda + Izquierda Palabra derecha Control + Derecho Frase izquierda Control + Alt + Izquierda Frase correcta Control + Alt + botón derecho Alternar Insertar Overtype Mostrar espacio en blanco Control + Alt + T Control de ventana de desplazamiento arriba + abajo Control de ventana de desplazamiento abajo + Arriba Ventana de desplazamiento izquierda CTRL + REPÁG Ventana de desplazamiento derecha Ctrl + AVPÁG Eliminar una palabra a final de Control + Supr Borrar la palabra para iniciar el Control + Retroceso Extender un carácter a la izquierda Mayús + Izquierda Extender un carácter a la derecha Mayús + Derecho Extender la palabra izquierda Control + Shift + Izquierda Extender la palabra derecha Control + Mayús + Derecho Extender la línea para iniciar Mayús + Inicio Ampliar a la línea final Mayús + Fin Extender la línea hasta Mayús + Flecha arriba Extender la línea hacia abajo Mayús + Flecha abajo Ampliar Page Up Shift + REPÁG Ampliar Page Down Shift + NEXT Bloque de comentario Ctrl + Q Bloque sin comentario Ctrl + W

Reglas de sintaxis de las expresiones regulares para buscar y reemplazar

Comodines: ? (Cualquier carácter), + (para uno o más ot algo), * (cero o mas de algo). Conjuntos de caracteres: Los caracteres encerrados entre corchetes será tratada como un conjunto de opciones. Rangos de caracteres puede especificarse con un - (p. ej. [A-C]). O lógico: Las subexpresiones se pueden ORed juntos | con el símbolo de canalización. Las subexpresiones entre paréntesis: Una expresión regular puede ser encerrada entre paréntesis y se trata como una unidad. Caracteres de escape: Secuencias como: \T - ficha... Será sustituido por un equivalente de carácter individual. \\ Representa la barra invertida.

Si hay problemas con el editor de código fuente puede que necesite copiar manualmente "cmax20.ocx" desde la carpeta de programa en Windows\System o Windows\System32 sustituyendo cualquier versión existente de dicho archivo (puede ser necesario reiniciar antes de sistema permite sustituir el archivo existente).

15)compilar el código de ensamblaje

Escriba su código dentro del área de texto, y haga clic en Compilar botón. Se le pedirá un lugar donde guardar el archivo compilado. Tras una compilación exitosa puede emular haga clic en el botón para cargar el archivo compilado en el emulador.

El tipo de archivo de salida directivas: #Make_com# #Make_bin# #Make_boot# #Make_exe#

Puede insertar estas directivas en el código fuente para especificar el tipo de salida necesaria para el archivo. Sólo si el compilador no puede determinar el tipo de salida automáticamente y cuando no puede encontrar alguna de estas directivas se le puede preguntar por el tipo de salida antes de crear el archivo. Prácticamente no hay diferencia entre cómo .com y .bin se montan porque estos archivos raw son archivos binarios, pero el archivo .exe tiene un encabezado especial al principio del archivo que es utilizado por el sistema operativo para determinar algunas de las propiedades del archivo ejecutable.

Descripción de los tipos de archivos de salida: #Make_com# - El más antiguo y el más simple el formato de un archivo ejecutable, dichos archivos se cargan con 100h prefijo (256 bytes). Seleccione Limpiar desde el menú Nuevo si va a compilar un archivo COM. La directiva de compilador ORG 100h debe agregarse antes del código. Ejecución siempre comienza desde el primer byte del archivo. Este tipo de archivo se selecciona automáticamente si org 100h directiva se encuentran en el código. Apoyado por DOS y Símbolo del sistema de Windows.

#Make_exe# - más avanzado formato de un archivo ejecutable no está limitada por el tamaño y el número de segmentos. segmento de pila debe ser definida en el programa. Puede seleccionar exe template desde el menú Nuevo para crear un simple programa exe con datos predefinidos, apilado y segmentos de código. El punto de entrada (donde comienza la ejecución) está definida por un programador. Este tipo de archivo se selecciona automáticamente si el segmento de pila se encuentra apoyado por dos y símbolo del sistema de Windows.

#Make_bin# - un simple archivo ejecutable. Puede definir los valores de todos los registros, el segmento y offset para área de memoria donde este archivo será cargado. Al cargar "Miarchivo.BIN " a emulator buscará un "mi.BINF" archivo y cargar "mi.BIN" archivo a la ubicación especificada en "My.BINF" Archivo, registra también se establecen mediante la información contenida en dicho archivo (abrir este archivo en un editor de texto para editar o investigar). En caso de que el emulador no es capaz de encontrar "mi.BINF" file, se utilizan los valores del registro actual y "mi.BIN" archivo se carga en CS:IP actual. La ejecución se inicia a partir de los valores de CS:IP. Tipo de archivo bin no es exclusivo del emulador, sin embargo las directivas son únicos y no funcionará si el archivo .bin es ejecutada fuera del emulador porque su salida se almacena en un archivo separado independientemente del código binario puro.

Se crea el archivo .BINF ensamblador automáticamente si encuentra alguna de las siguientes directivas. Estas directivas se pueden insertar en cualquier parte de la fuente Código preestablecido a registros o memoria antes de iniciar la ejecución del programa:

#Make_bin# #LOAD_segment=1234# #LOAD_offset=0000# #AL=12# #AH=34# #BH=00# #BL=00# #CH=00# #CL=00# #DH=00# #DL=00# #DS=0000# #S=0000# # SI=0000# #DI=0000# #BP=0000# #CS=1234# #IP=0000# #SS=0000# #SP=0000# #MEM=0100:FFFE,00FF0100:FF00,F4#

Todos los valores deben estar en formato hexadecimal. Cuando no se especifica estos valores se establecen de forma predeterminada: LOAD_segment = 0100 LOAD_OFFSET = 0000 CS = ES = SS = DS = 0100 IP = 0000 Si LOAD_segmento y LOAD_offset no están definidos y, a continuación, CS y se utilizan los valores de IP y viceversa. "#Mem=..." La directiva puede ser usada para escribir valores en memoria antes de que comienza un programa

#MEM=nnnn[bytestring]-nnnn:nnnn[bytestring]# por ejemplo: #MEM=1000,01ABCDEF0122-0200,1233# Todos los valores están en hexadecimal, nnnn - por dirección física, o (nnnn:nnnn) para la dirección lógica.

- Separa las entradas. Se admiten espacios en su interior. Nota: todos los valores están en hexadecimal hex. prefijo/sufijo no es necesario. Para cada byte debe ser exactamente de 2 caracteres, por ejemplo: 0A, 12 o 00. Si ninguna de las anteriores directivas directivas están preestablecidas en el código fuente, binf archivo no se crea. Emulador cuando se carga el archivo .bin sin .binf utilizará el archivo c:\emu8086\default.binf en su lugar. Esto también se aplica a cualquier otro tipo de archivos con extensiones que no están familiarizados con el emulador.

El formato de un típico ".BINF" archivo:

AA BB CC

8000 ; carga al segmento. 0000 ; carga para compensar. 55 ; al. 66 ; AH 77 ; BL 88 ; BH 99 ; CL ; CH ; DL ; DH DDEE ; DS ABCD ; ES EF12 ; si 3456 ; DI 7890 ; BP 8000 ; CS 0000 ; C123 ; SS D123 ; SP

Podemos observar que la primera va un número en formato hexadecimal y luego un comentario. Los comentarios se agregan sólo para hacer un poco de orden, cuando se carga un archivo BINF emulador no importa

comentarios simplemente busca valores de líneas específicas, por lo que orden de línea es muy importante. Nota: el archivo .binf existente se sobrescribe automáticamente al volver a compilar. En caso de carga al valor de desplazamiento no es cero (0000), ORG ????h debe ser añadido a la fuente de un archivo .bin donde ????h es la carga Desplazamiento, esto se debe hacer para permitir que el compilador calcular direcciones correctas.

#Make_boot# - este tipo es una copia de la primera pista de un disquete (sector de arranque). La única diferencia con #make_bin# Es que el segmento de carga está predefinido en 0000:7c00h (este valor se escribe en el archivo .binf acompañado). De hecho puede utilizar #make_bin# sin ninguna falta de rendimiento, sin embargo, para hacer la prueba correcta en emulador necesitará añadir estas directivas: #cs=0# y #ip=7c00# - Ensamblador escribe estos valores en el archivo .binf. Puede escribir un sector de arranque de un disquete virtual (FLOPPY_0) a través del menú en el Emulador: [Unidad virtual] -> [512 bytes de escritura a 7c00 a boot sector] Primero debe compilar un archivo .bin y cargarlo en el emulador (ver "micro-os_loader.asm" y "microos_kernel.asm" en "c:\emu8086\Examples\" para más información). A continuación, seleccione [unidad virtual] -> [arranque desde disquete] Menú para arrancar emulador desde un disquete virtual. Entonces, si tiene curiosidad, puede escribir los mismos archivos en disquete real y arrancar el ordenador desde él. Puede utilizar "writebin.asm" desde c:\emu8086\\Ejemplos de micro-sistema operativo no tienen MS-DOS/Windows compatible el sector de arranque, así que es mejor utilizar un disquete vacío. Consulte para tutorial 11 obtener más información.

La directiva de compilador org 7c00h debe agregarse antes el código cuando se inicia el ordenador, se carga la primera pista de un disco flexible en la dirección 0000:7c00. El tamaño de un archivo de registro de arranque debe ser inferior a 512 bytes (limitado por el tamaño de un sector del disco). ejecución siempre comienza desde el primer byte del archivo. Este tipo de archivo es exclusivo de emu8086 emulador.

Error al procesar Compilador de lenguaje ensamblador (o assembler) informes sobre errores en otra ventana de información:

MOV DS, 100 - es instrucción ilegal porque los registros de segmento no se pueden establecer directamente, registro de propósito general debe ser utilizado, por ejemplo

MOV AX, 100 DS, MOV AX MOV AL, 300 - es instrucción ilegal porque al registrar sólo tiene 8 bits y, por lo tanto, valor máximo es 255 (o 11111111b), y la mínima es de -128.

Al guardar un archivo ensamblado, el compilador también guarda otros 2 archivos que luego son utilizados por el emulador para mostrar código fuente original cuando se ejecute el binario ejecutable y seleccione líneas correspondientes. Muy a menudo el código original difiere de los discapacitados el código porque no hay comentarios, ningún segmento y no las declaraciones de variables. Las directivas del compilador no producen código binario, pero todo se convierte en código máquina puro. A veces una sola instrucción original se ensambla en varias instrucciones de código máquina, esto se hace principalmente para la compatibilidad con microprocesador 8086 original (por ejemplo LOD AL, 5 se monta en cinco lod secuencial AL, 1 instrucciones). *.~asm - Este archivo contiene el código fuente original que se utilizó para realizar un archivo ejecutable. *.Debug - Este archivo contiene información que permite que el emulador seleccionar las líneas de código fuente original mientras se ejecuta el código de máquina. *.El símbolo - tabla de símbolos, contiene información que permite mostrar la ventana de "variables". Es un archivo de texto simple, así que usted puede ver en cualquier editor de texto (incluyendo la UEM8086 editor de código fuente). *.Binf - este archivo ASCII contiene información que es utilizada por el emulador para cargar el archivo BIN en la ubicación especificada, y establezca los valores de registro antes de la ejecución; (creado sólo si un archivo ejecutable es un archivo BIN).

16) utilizando el emulador de microprocesador Si desea cargar el código en el emulador, simplemente haga clic en Emular . Pero usted también puede usar el emulador para cargar archivos ejecutables, incluso si no tienes el código fuente original. Seleccione Mostrar emulador desde el menú del emulador.

Intente cargar archivos de "MyBuildcarpeta ". Si no hay archivos en "MyBuildcarpeta " volver al editor de código fuente, seleccionar ejemplos desde el menú Archivo, cargar cualquier ejemplo, compilarlo y, a continuación, cargar en el Emulador:

[Solo Paso] botón ejecuta instrucciones uno por uno parar después de cada instrucción. [] Botón Run Ejecuta instrucciones uno por uno con retardo definido por el paso de retardo entre instrucciones. Haga doble clic en Registrar cuadros de texto abre la ventana Visor extendido con el valor del registro que convierten a todas las formas posibles. Puede modificar el valor del registro directamente en esta ventana. Haga doble clic en el elemento de la lista de memoria extendida abre Word Viewer con valor cargado desde lista de memoria en la ubicación seleccionada. El byte menos significativo está en la dirección inferior: Low Byte se cargan desde la posición seleccionada y el byte alto desde la siguiente dirección de memoria. Puede modificar el valor de la palabra de la memoria directamente en el Ventana Visor, extendida

Puede modificar los valores de los registros de tiempo de ejecución escribiendo sobre los valores existentes. [Flags] botón le permite ver y modificar banderas en tiempo de ejecución.

17) unidades virtuales Emulator soporta hasta 4 unidades de disco virtual. Por defecto hay un floppy_0 archivo que es una imagen de un disquete real (el tamaño del archivo es exactamente 1,474,560 bytes). Para agregar más unidades de disquete selecciona [Crear una nueva unidad de disquete virtual] FROM [unidad] Menú. Cada vez que agregue un emulador crea un disquete floppy_1, floppy_2, y floppy_3 archivos. Crear imágenes de disquetes son IBM/vacío formateado MS-DOS imágenes de disco. Sólo se admiten 4 unidades de disquete (0..3)! Para eliminar una unidad de disquete debe cerrar el emulador, elimine el archivo requerido manualmente y reiniciar el emulador. Puede determinar el número de unidades de disquete adjunto usando INT 11h esta función devuelve registro AX con BIOS lista de equipos. Los bits 7 y 6 definen el número de unidades de disquete (menos 1): Los bits 7-6 de AX: 00 disco único.

01 dos

disquetes. 10

Tres disquetes.

11 Cuatro discos.

Empieza a contar el emulador desde unidades de disquete conectadas a partir de la primera, en el caso de archivo floppy_1 no existe deja la casilla e ignora floppy_2 _3 disquetes y archivos. Para escribir y leer desde una unidad de disquete, puede utilizar la función INT 13h, consulte list of supported interrupts para obtener más información.

Emulador puede emular diminuto sistema operativo, check out operating system tutorial.

18) Tabla de memoria global 8086 CPU puede acceder hasta a 1 MB de memoria de acceso aleatorio (RAM). Esto es más que suficiente para cualquier tipo de cálculos (si se utilizan apropiadamente). tabla de memoria del emulador (y típico de IBM PC tabla de memoria): Dirección física del área de memoria en hexadecimal

Breve descripción

00000 - 00400 el

Los vectores de interrupción. El emulador carga este archivo: C:\emu8086\INT_VECT en la dirección física 000000.

00400 El - 00500

Área de información del sistema. Utilizamos un truco para establecer algunos parámetros mediante la carga de un diminuto última parte (21 bytes) de INT_VECT en esa zona (el tamaño del archivo es de 1.045 o 415h bytes, de modo que cuando está cargada de memoria tarda desde 00000 a 00415h). Este bloque de memoria se actualiza mediante el emulador cuando los cambios de configuración, consulte la system information area tabla.

00500 - A0000

Un área de memoria libre. Un bloque de 654,080 bytes. Aquí puede cargar sus programas.

A0000 - B1000

Memoria de vídeo VGA, monocromo, y otros adaptadores. Es utilizada por el modo Vídeo 13h de la INT 10h.

B1000 - B8000

Reservados. No utilizado por el emulador.

B8000 - C0000

32 kb de memoria de vídeo para color graphics adapter (CGA). El emulador utiliza este área de memoria para mantener 8 páginas de memoria de vídeo. La pantalla del emulador se pueden cambiar de tamaño, por lo menos memoria es necesaria para cada página, aunque el emulador siempre utiliza 1000h (4096 bytes) para cada página (véase INT 10h / AH=05h en the list of supported interrupts).

C0000 - F4000

Reservados.

F4000 - 10FFEF

ROM BIOS y extensiones. El emulador carga el BIOS ROM_ file en la dirección física 0F4000h. Las direcciones de la tabla de interrupción de memoria apunta a esta área para hacer una emulación de las funciones de interrupción.

Tabla de vectores de interrupción (memoria de 00000h a 00400h) Dirección número INT en la dirección del vector de interrupción en hexadecimal sub-programa del BIOS 00 00x4 = 00 F400:0170 - CPU-generado, dividir el error. 04 04x4 = 10 F400:0180 - CPU-generado, en detectado el desbordamiento. 10

10x4 = 40 F400:0190 - funciones de vídeo.

11

11x4 = 44 F400:01D0 - Get BIOS

12

12x4 = 48 F400:01A0 - obtener el tamaño de la memoria.

13

13x4 = 4C F400:01B0 - Funciones de discos.

15

15x4 = 54 F400:01E0 - Funciones del BIOS.

16

16x4 = 58 F400:01C0 - Funciones de teclado.

17

17x4 = 5C F400:0400 - impresora.

19

lista de equipos.

19x4 = 64 FFFF:0000 - reinicio.

1A 1AX4 = 68 F400:0160 - funciones de tiempo. 1E 1Ex4 = 78 F400:AFC7 - vector de parámetros del controlador de disquete. 20

20x4 = 80 F400:0150 - función DOS: cerrar el programa.

21

21x4 = 84 F400:0200 - dos funciones.

33 33x4 = CC F400:0300 - Funciones del ratón. Todos los otros ??x4 = ?? F400:0100 - interrupción predeterminada ramal. Una llamada a la BIOS sub-sistema está desmontado como DI DEL BIOS (Sistema Básico de Entrada/Salida - No interrumpir). Para codificar esta instrucción de 4 bytes, FFFF opcode prefijo se usa. Por ejemplo: FFFFCD10 se utiliza para hacer que el emulador para ejecutar el número de interrupción 10h. En la dirección F400:0100 existe este código de máquina (FFFFCDFF se descodifican como int 0FFh, es utilizado para generar un mensaje de error predeterminado, a menos que usted haga su propia falta de interrupción para sustitución de funciones).

Área de información del sistema (memoria de 00400h a 00500h)

Dirección (hex)

Tamaño

Descripción BIOS lista de equipos.

0040h:0010

WORD

Campos de bits para el BIOS detecta el hardware instalado: bit(s) Descripción 15-14 número de dispositivos paralelos. 13 reservados. 12 puerto de juegos instalados. 11-15 número de dispositivos serie. 8 reservados. 7-6 número de unidades de disquete (menos 1): 00 Solo disquete; 01 Dos disquetes; 10 tres disquetes; 11 cuatro disquetes. El modo de vídeo inicial de 5-4: 00 EGA, VGA,PGA, u otros con la placa de video onboard BIOS; 01 40x25 CGA color. 10 80x25 CGA color predeterminado (el emulador). 11 Texto mono 80x25. 3 reservados. 2 del ratón PS/2 está instalado. 1 coprocesador matemático instalado. 0 Cuando arranca desde disquete.

0040h:0013

WORD

Kilobytes de memoria contigua empezando en dirección absoluta 00000h. Esta palabra también se devuelve en AX por INT 12h. Este valor se establece en: 0280h (640KB).

0040h:004A

WORD

Número de columnas en la pantalla. Valor predeterminado: 0032h (50 columnas).

0040h:004E

WORD

Dirección de inicio de la página de vídeo actual en la memoria de vídeo (después del 0B800:0000). Valor predeterminado: 0000h.

0040h:0050

8 Palabras

Contiene la posición de fila y columna para los cursores en cada uno de ocho páginas de vídeo. Valor predeterminado: 0000h (de las 8 palabras).

0040h:0062

BYTE

Número de página de vídeo actual. Valor predeterminado: 00h (primera página).

0040h:0084

BYTE

Filas en pantalla menos uno. Valor predeterminado: 13h (19+1=20 columnas).

19) Los puertos de E/S y las interrupciones de hardware El emulador no puede reproducir cualquier dispositivo de entrada/salida de la IBM PC original ®, sin embargo, teóricamente es posible crear la emulación del original IBM PC dispositivos. emu8086 admite dispositivos virtuales creadas por el usuario que se puede acceder desde el programa en lenguaje ensamblador utilizando instrucciones in y out. Los dispositivos que pueden ser creados por cualquier persona con experiencia en programación básica en cualquier nivel alto o bajo. El lenguaje de programación más sencillo dispositivo virtual en lenguaje ensamblador puede encontrarse en ejemplos: simple.asm

Puertos de entrada / salida Emu8086 admite dispositivos adicionales que pueden ser creados por cualquier persona con experiencia en programación básica en cualquier idioma dispositivo pueden estar escritas en cualquier idioma, tales como: java, visual basic, VC++, Delphi, C#, .net o en cualquier otro lenguaje de programación que permiten leer y escribir archivos directamente. Para obtener más información y código fuente de ejemplo mirar dentro de esta carpeta: C:\emu8086\Dispositivos\Developer\ La última versión del emulador no tiene reservados o fijo de puertos de E/S, las direcciones de entrada/salida de los dispositivos personalizados son de 0000 a 0FFFFh (de 0 a 65535), pero es importante que dos dispositivos que utilizan los mismos puertos no ejecutar simultáneamente para evitar conflictos de hardware. El puerto 100 corresponde a 100 bytes en este archivo: c:\emu8086.io , el puerto 0 a 0 byte a byte , puerto 101 101, etc...

Emulación de interrupciones de hardware

Las interrupciones de hardware externo puede ser desencadenada por microcontroladores y dispositivos periféricos externos o por el coprocesador matemático 8087. Las interrupciones de hardware están desactivados cuando se utiliza la bandera de interrupción (SI) está ajustado a 0. Cuando la bandera de interrupción se establece en 1, el emulador comprueba constantemente primeros 256 bytes del archivo c:\emu8086.hw si alguno de los bytes es el microprocesador nonezero transfiere el control a un manejador de interrupción que coincide con la activación byte offset en emu8086.hw archivo (0 a 255) de acuerdo a la tabla de vectores de interrupción (memoria 0000-0400h) y se restablece el byte en la UEM hw8086. A 00. Estas instrucciones pueden utilizarse para activar y desactivar las interrupciones de hardware: Cli - borrar la bandera de interrupción (deshabilitar las interrupciones de hardware). Its - establecer la bandera de interrupción (Activar interrupciones de hardware). Por defecto las interrupciones de hardware están habilitados y se desactivan automáticamente cuando la interrupción de software o hardware está en la mitad de la ejecución.

Ejemplos de dispositivos de E/S personalizados Listo dispositivos están disponibles desde el menú dispositivos virtuales del emulador. Semáforo - Puerto 4 (Word) Los semáforos están controladas mediante el envío de datos al puerto E/S 4. Hay 12 lámparas: 4 verdes, 4 amarillas y 4 rojas. Puede establecer el estado de cada lámpara, estableciendo su bit: 1 - La lámpara está encendida. 0 - La lámpara está apagada. Sólo 12 bits de baja de una palabra se usa (0 a 11), el último bit (12 a 15) no se utilizan.

Por ejemplo: MOV AX, 0000001011110100b 4, AX

Utilizamos amarillo dígitos hexadecimales en el título (para lograr la Vista compacta), aquí está una conversión: - Decimal Hex. A - 10 B - 11 C - 12 (sin usar). D - 13 (sin usar). E - 14 (sin usar). F - 15 (sin usar).

Primer operando de la instrucción es un número de puerto (4), el segundo operando es una palabra (AX) que se escribe en el puerto. primer operando debe ser inmediatamente un valor byte (0..255) o registro DX. Segundo operando debe ser un hacha o al solamente. Véase también el tráfico_luces.asm en c:\emu8086\Ejemplos.

Si es necesario, se pueden leer los datos del puerto utilizando en la instrucción, por ejemplo:

En AX, 4 Primer operando de la instrucción (AX) recibe el valor del puerto, el segundo operando (4) es un número de puerto. primer operando debe ser un hacha o al solamente. segundo operando debe ser inmediatamente un valor byte (0..255) o registro DX.

Motor paso a paso - Puerto 7 (byte). El motor es controlado por el envío de datos al puerto E/S 7. Motor de pasos está el motor eléctrico que puede ser precisamente controlado por señales desde un ordenador. El motor gira a través de un ángulo preciso cada vez que recibe una señal. Variando la velocidad a la que se producen pulsos de señal, el motor puede funcionar a diferentes velocidades o gira a través de un ángulo exacto y luego se detiene. Esta es una base del motor paso a paso de 3 fases, 3 imanes controlados por los bits 0, 1 y 2. otros bits (3..7) no se utilizan. Cuando el imán está trabajando se torna roja. La flecha de la esquina superior izquierda muestra la dirección del último motor mueva. Línea verde está aquí sólo para ver que es realmente girando.

Por ejemplo, el siguiente código hará tres en el sentido de las agujas del reloj la mitad-pasos: MOV AL, 001b ; inicializar. 7, al. MOV AL, 011b ; la mitad paso 1. 7, al. MOV AL, 010b ; la mitad paso 2. 7, al. MOV AL, 110b ; la mitad paso 3. 7, al. Si alguna vez has jugado con imanes comprenderás cómo funciona. Pruebe o vea los pasos_motor.asm en c:\emu8086\Ejemplos. Si es necesario, se pueden leer los datos del puerto utilizando en la instrucción, por ejemplo: En Alabama, 7 Motor de pasos conjuntos de bits superior del valor de byte en la lumbrera 7 cuando esté listo.

Robot - El puerto 9 (3 bytes).

El robot es controlado mediante el envío de datos al puerto E/S 9.

El primer byte (puerto 9) es un comando register. Establecer valores a este puerto para hacer robot hacer algo. Los valores admitidos: Valor decimal Valor binario

Acción

0

00000000

No hacer nada.

1

00000001

Mueva hacia adelante.

2

00000010

Gire a la izquierda.

3

00000011

Gire a la derecha.

4

00000100

Examinar. examina un objeto en la parte delantera con el sensor. Cuando el robot finaliza la tarea, el resultado se ajusta a los datos de registro y poco #0 del registro de estado está ajustado a 1.

5

00000101

Encender una lámpara.

6

00000110

Cortar una lámpara.

El segundo byte (puerto 10) es un registro de datos. Este registro se establece después de que el robot se completa el comando examinar: Valor decimal Valor binario

Significado

255

11111111

Wall

0

00000000

Nada

7

00000111

En lámpara conmutada

8

00001000

Luz de apagado

El tercer byte (puerto 11) es un registro de estado. Leer valores de este puerto para determinar el estado del robot. Cada bit tiene una propiedad específica: Poco Número

Descripción

#0 bits

Cero cuando no hay nuevos datos en el registro de datos, uno cuando Hay nuevos datos en el registro de datos.

#1 bits

Cero cuando el robot está listo para el siguiente comando, uno cuando el robot está ocupada realizando alguna tarea.

#2 bits

Cero cuando no hay ningún error en la última ejecución de comandos, uno cuando hay un error en la ejecución de comandos (cuando el robot no puede completar la tarea: mover, girar, examinar, encender/apagar la lámpara).

Ejemplo:

MOV AL, 1 ; avanzar. 9, al ; MOV AL, 3; gire a la derecha. 9, al ; MOV AL, 1 ; avanzar. 9, al ; MOV AL, 2; gire a la izquierda. 9, al ; MOV AL, 1 ; avanzar. 9, al ;

Tenga en cuenta que el robot es una criatura mecánica y tarda algún tiempo para completar una tarea. usted debe verificar siempre#1 bits del registro de estado antes de enviar los datos al puerto 9, de lo contrario, el robot rechazará su mando y "ocupado!" será mostrado. Ver robot.asm en c:\emu8086\Ejemplos.

Crear personalizados Robo-World Mapa Es posible cambiar el mapa predeterminado para el robot usando la caja de herramientas. Si hace clic en el botón del robot y coloque encima del robot robot existentes se girará 90 grados en el sentido de las agujas del reloj-Contador. Para mover manualmente el robot sólo tiene que colocarlo en otro lugar del mapa. Si hace clic en la lámpara y, a continuación, haga clic en el botón de conmutación en la Lámpara La lámpara estará desconectada, si la luz ya está desconectada será eliminado. Haga clic en un espacio vacío, se creará un nuevo conmutada en la lámpara. Colocación muro a lo largo de la pared existente elimina la pared.

La versión actual está limitado a un único robot solamente. si usted se olvida de colocar un robot en el mapa se ubicará en algunas coordenadas aleatorias. Cuando el robot está cerrado dispositivo el mapa se guarda automáticamente dentro de este archivo: c:\emu8086\dispositivos\robot_map.dat es posible tener varios mapas para renombrar y hacer frente este archivo antes de iniciar el dispositivo del robot. Clic con el botón secundario del mouse sobre el mapa trae un menú emergente que permite encender o apagar todas las luces a la vez.