Computing">
[go: up one dir, main page]

0% encontró este documento útil (0 votos)
35 vistas11 páginas

Assembler y Debug1

Descargar como doc, pdf o txt
Descargar como doc, pdf o txt
Descargar como doc, pdf o txt
Está en la página 1/ 11

Assembler

Debug:

El debug es un programa de DOS que permite ver el contenido de los registros, el


contenido de la memoria, e invocar un ensamblador.
Usando el Debug deben estar escritos los datos o variables en direcciones de memoria.

Ingreso de datos en Debug:

Esto se realiza mediante el comando e, "edit". Desde el prompt de DOS se ingresa e, la


dirección de memoria en hexadecimal y luego enter.

-e 5000
La instrucción –e muestra el contenido en memoria. En este caso se posiciona en la
dirección de memoria 5000 y muestra su contenido. En este caso la posición de
memoria 5000 posee el contenido 34.

:5000 34

Utilizando el punto se puede cambiar el valor agregando un nuevo valor después del
punto. Se pueden colocar dos dígitos en hexa equivalente a 1 byte en binario por cada
posición de memoria. Al colocar .11 posteriormente al valor se reemplazará el
contenido de la posición 5000 por el valor 11.

:5000 34.11

Si luego del punto se deja un espacio con la barra espaciadora muestra la siguiente
posición de memoria.
Si uno modifica un valor con el punto y luego da espacios también muestra los
contenidos de las siguientes posiciones de memoria y puede cambiarlos.

:0100 F1.01 67.00 69.20 00.10

Al ingresar un número se escribe primero la mitad derecha de cada número, la dirección


mas baja, de manera que XXYY queda YYXX.
Ejemplo:
-e 5000
:5000 00.10 00.20
quiere decir que en la posición más significativa 5001 tenemos el valor 20 y en la
menos significativa el valor 10.
Al pasar a un registro de 16 bits, tendremos el valor 2010.

La dirección puede ser elegida arbitrariamente, siempre que forme parte de la


instrucción que opere dicho dato.
Una instrucción ordena una operación mediante su código de operacion. Al código de
operación le sigue la dirección donde se encuentra el dato.

0100 es el desplazamiento a partir del principio del segmento.


Registros:

AX [ AH | AL ] = Acumulador
16 bits.
8 bits AH y 8 bits AL.
BX = Registro base, suele tener la posición de inicio de una tabla de valores.
CX = Registro contador.
DX = Registro de datos multiuso.

Los registros acumuladores son llamados AX, BX, CX y DX. El registro BX también
puede utilizarse como puntero para guardar direcciones que apunten a posiciones de
memoria.
Los registros AX, BX, CX y DX son de 16 bits, pero si se necesita operar con 8 bits
cada uno de estos registros se divide en dos registros de 8 bits, la parte alta y baja del
registro de 16 bits y se denominan con H y L.
Los registros SI y DI son registros punteros para manejar listas. SI es indice fuente y DI
indice destino.
Los registros SP y BP manejan Pilas.
DS, CS, SS, ES son registros de segmento de datos, de código, de stack y extra.
CS señala la dirección del segmento de código de programa que se esta ejecutando.
DS señala la dirección del segmento de datos del programa en ejecución.
SS señala la dirección del segmento donde esta la pila del programa
ES es un segmento auxiliar para señalar espacio extra o almacenar direcciones
intermedias momentáneamente.
Ejemplo de instrucciones

Si quisiéramos tener un dato que se encuentra en la posición 5000 en el registro AX


en un procesador x86 la instrucción sería en hexa A1 y la dirección 0050, con lo que
quedaría A10050.
A10050 en binario es 1010 0001 0000 0000 0101 0000.
Esta instrucción de 3 bytes ordena mover hacia el registro AX de 2 bytes una copia de
un número de 2 bytes localizable en la dirección de memoria que indican los últimos 2
bytes de la instrucción.

Una instrucción de carga o Load en Assembler.


Mov Ax, [5000]
El primer valor después del mov es el destino y posterior a la coma el origen.

Si quisieramos sumar el contenido de la posición de memoria 5000 al registro AX, el


código de operación es en hexa 0306 seguido por la dirección del dato 0050.
0306 0050 en binario sería 0000 0011 0000 0110 0000 0000 0101 0000.

Una Suma
Add AX, [5000]

Una instrucción de escritura o Store.


Mov [200A] , AX

Las instrucciones se ejecutan una a una.

Mov AH [2001] es 8 bits


Mov AX, [2001] es 16 bits

Registros Extendidos: son de 32 bits y se implementaron a partir del Intel 80386.


EAx, EBx, ECx, EDx.
FLAGS SZVC

Los Flags son indicadores que pueden valer 1 o 0, es decir 1 bit y pueden ser utilizados
o no por la siguiente instrucción.
Estos indicadores constituyen el registro de estado y son esenciales para las
instrucciones e salto.

Bit Indicador de: Indicativo si bit 1 Indicativo si bit 0


CF  Acarreo  CY   ("Carry yes")  NC  ("No Carry")
PF  Paridad  PE   ("Parity Even") paridad  PO  ("Parity Odd") paridad
par impar
AF  Acarreo auxiliar  AC   ("Auxiliar Carry")  NA  ("No Auxiliar")
ZF  Cero  ZR   ("Zero")  NZ   ("No Zero")
SF  Signo  NG  ("Negative") negativo  PL   ("Plus") positivo
IF  Interrupción  EI    ("Enabled Interrupt")  DI  ("Disabled Interrupt")
activa desactivada
DF  Dirección  DN  ("Down")  decremento  UP  incremento
OF  Desbordamiento  OV  ("Overflow")  NV  ("No overflow")

Z vale 1, ZR si el resultado fue 0.


Z vale 0, NZ si el resultado no fue 0.

S vale 1, NG si el resultado es negativo.


S vale 0, PL si el resultado es positivo

V vale 1, OV si hubo overflow, se superó el nro máximo.


V vale 0, NV si no hubo overflow.

C vale 0, NC si no hay acarreo.


C vale 1, CY si hay acarreo.

Instrucciones de salto

Las instrucciones de salto permiten decidir cual es la próxima instrucción que se


ejecutará luego de ella entre dos instrucciones posibles, la que le sigue a continuación y
la otra cuya dirección de memoria ella indica. El salto tendrá lugar según el valor de uno
o más flags de un resultado anterior.

Instrucciones de salto para enteros:


JL < jump less
JLE <= jump less or equal
JG > jump greater
JGE >= jump greater or equal
JNZ =/ jump not Z
JZ = jump Z
JO jump if overflow
JNO jump if not overflow

Instrucciones de salto para Naturales o Caracteres:

JB Jump if below
JBE Jump Below or equal
JA Jump up
JAE Jump up or equal
JNZ Jump if not 0
JZ Jump if 0 o letras.

Instrucción de comparación

CMP AH, FF
CMP Ax, Bx
Luego de los comandos se presiona enter y en los casos que corresponde puede ponerse
un nuevo valor.

-r
Muestra el estado de todos los registros y el estado de los flags.

Ax=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000


DS=309D ES=309D SS=309D CS=309D IP=0200 NV UP EI PL NZ NA PE NC
309D:0200 A10050 MOV AX, [5000]

Los dos primeros renglones indican el estado de los registros de la CPU. El tercer
renglón se refiere a la memoria principal.
Luego muestra en el centro 1a instrucción y a la izquierda de esta el código máquina.

-r ax modifica el registro ax en forma interactiva. De la misma forma puedo modificar


cualquier registro.

-rf modifica las banderas o flags. Ejemplo: flag de carry NC , sin carry, si pongo -rf cy
y enter queda CY, es decir que hay carry.

-r ip
Examina donde esta apuntando el registro IP. Ej IP 0100:
Mediante este comando indica la primera instrucción a ejecutar.
Luego de los dos puntos se puede cambiar la dirección hacia adonde apunta el IP.
Se utiliza cuando escribo un programa para luego decirle al instruction pointer o
contador de programa adonde va a comenzar mi programa, ej -r ip enter e ingreso la
dirección 0100.

-d
Muestra exploración de la memoria como datos. -d 00:00. El primer par de ceros es el
segmento y el segundo par el offset o desplazamiento. Si estoy en el data segment
escribo los datos ahí.

-u
Muestra exploración de la memoria como código o instrucciones de programa. A partir
de u puedo poner el segmento de código, ej -u 073f enter y me muestra la memoria
como instrucciones. Si estoy en el code segment escribo el código ahí.
u 0100 10A muestra el código desde la direccion 0100 hasta la 10A.

-a
El comando a sirve para comenzar a escribir programas en assembler. A partir de a se
escribe la dirección de memoria a partir de la cual se quiere escribir el programa. En
general los programas .com comienzan a partir de la dirección 0100.

Los corchetes indican datos en memoria. Un registro entre corchetes indica la direccion
de datos en memoria. Un número entre corchetes indica modo de direccionamiento
directo, se da la dirección para localizar en memoria el dato a procesar.
-a 0100
La a significa Assamble. Se posiciona en la dirección de memoria y comienza a
ensamblar.

: 0100 mov AH, [500]. Mover lo que esta en 500 a AH.


: 0103 add AH, [600]. Suma lo que esta en 600 en AH y deja el resultado en AH.
: 0107 sub AH, [700]. Resta lo que esta en AH lo que esta en 900 y deja el res en AH.\
: 010B Int 20 (o Ret). Pone a ejecutar una rutina que libera la memoria y da el control al
sistema. Ret no libera.

Int 20 devuelve el control al sistema operativo o command.com terminando el


programa en forma normal.
Fin de programa.

Formas de correr el programa

-p
Significa proceed. va paso a paso, no se mete en las subrutinas. Es la forma que
utilizaremos.

-t
Trace. Sigue paso a paso la ejecución del programa. Se mete en las subrutinas.

-g
Ejecuta hasta que termina en el int 20

-ret
se utiliza desde una llamada Call.

-n test.com
n le da un nombre al programa. el este caso se llamará test.com.

Para escribir un programa en disco hay que escribir en el registro CX el tamaño del
programa. Hay que verificar que el registro DX valga 0000. Por ejemplo, si el programa
tiene 11 bytes o B en hexa, escribo -r cx y enter. Cuando me pide ingresar el valor de
cx despues de los : pongo el tamaño del programa, en este caso b y luego enter.

-w
Escribe el programa en el directorio por defecto. luego al ejecutar el comando dir tendre
el archivo test.com.

Para cargar el programa en la memoria del debug desde el disco debo escribir para el
ejemplo:
-n test.com
-l enter (L de cargar o load).

Cuando quiero cambiar una instrucción ya escrita en un programa debo tener cuidado
del tamaño que ocupa dicha instrucción, ya que si es reemplazada por otra mas grande
me arruinará el programa. Antes de reemplazar una instrucción es bueno grabar el
programa.
Ejercicios:

Ejercicio 1: Escribir en Assembler las instrucciones necesarias para codificar la


operación R = P + P - Q en las direcciones 5010, 5000 y 5006 respectivamente.

-e 5000 00.03
-e 5006 00.05

-A 0200
:0200 MOV AX, [5000] llevar a AX una copia de P que esta en 5000-5001
:0203 ADD AX, [5000] Sumar a AX una copia de P.
:0207 SUB AX, [5006] restar a AX una copia de Q que esta en 5006-5007
:020B MOV [5010], AX transferir a 5010 y 5011 una copia de AX.
:020E

-e 5010 00.01

Los corchetes indican datos en memoria. Si una instrucción tiene un número entre
corchetes se dice que esta en modo de direccionamiento directo, se da la dirección para
localizar en memoria el dato a procesar.

Ejercicio 3: Escribir el producto R = M x N repitiendo N veces una suma.

-e B300 00.03 00.00


-e B310 00.04 00.00

MOV BX, [B300]


SUB AX, AX
ADD AX, BX
ADD AX, BX
ADD AX, BX
ADD AX, BX
MOV [B320], AX

la instrucción SUB AX, AX es utilizada para llevar el registro AX a 0. El modo de


direccionamiento es modo registro.

Uso de un lazo repetitivo con instruccion de salto condicional

:0100 MOV CX, [B310] Lleva a CX una copia de N que esta en B310 y B311.
:0104 MOV BX, [B300] lleva a BX una copia de M que esta en B300 y 301
:0108 SUB AX, AX Pone el acumulador AX en cero restandolo a si mismo.
:010A ADD AX, BX Sumar a AX el valor valor de M que esta en BX
:010C DEC CX Resta uno a CX, pueden cambiar los flags.
:010D JNZ 010A Si respecto al resultado anterior el flag Z=0 salta a 010 A
:010F MOV [B320], AX Lleva a B320 y 321 en memoria el valor de AX
:0112 INT 20 fin.

Ejercicio 4: Mejorar el ejercicio 3 con posibilidad de overflow

:0100 MOV CX, [B310] Lleva a CX una copia de N que esta en B310 y B311.
:0104 MOV BX, [B300] lleva a BX una copia de M que esta en B300 y 301
:0108 SUB AX, AX Pone el acumulador AX en cero restandolo a si mismo.
:010A ADD AX, BX Sumar a AX el valor valor de M que esta en BX
:010C JO 0130 Si el flag V = 1, saltar a :0130
:010E DEC CX Resta uno a CX, pueden cambiar los flags.
:010F JNZ 010A Si respecto al resultado anterior el flag Z=0 salta a 010 A
:0111 MOV [B320], AX Lleva a B320 y 321 en memoria el valor de AX
:0114 INT 20 fin.

A 0130
:0130 MOV AX, FFFF Llevar a AX una copia de la constante FFFF
:0133 MOV [B320],AX Llevar a B320 y B321 de memoria una copia de AX
:0136 INT 20 fin.

Manejo de Listas

Ejercicio 6: Sumar una lista de números enteros de 2 bytes. La cantidad se da en la


posición 1500 y el resultado de la suma se almacena en las direcciones 2000 y 2001.

-e 1500
03 cantidad de elementos que integran la lista.

-e 1000
Posición donde empieza la lista.

-a 100
0100: MOV Cl, [1500] Carga en el contador Cl la longitud de la lista.
0104: MOV SI, 1000 El puntero SI apunta al comienzo de la lista.
0107: SUB AX, AX Pone Ax en 0
0109: ADD AX, [SI] Suma a AX un nro de la lista apuntada por SI.
010B: ADD SI, 2 Suma 2 a SI. Ahora apunta a 1002.
010E: DEC Cl Decrementa Cl.
0110: JNZ 109 Mientras Z=0, vuelve a 109.
0112: MOV [2000], AX
0115: INT 20

-r ip
-g
-e 2000.

Mov Si, 2000 (apunta a 2000)


INC Si
Mov AH, [Si] (apunta a 2001)
Al contenido de la celda apuntada por Si lo va aponer en la parte alta de Ax. Trae solo 8
bits. En Si apunta a la dirección 2001.

Si fuera Mov AX, [Si]


Me va a poner Si en la parte baja y Si+1 (2002) en la parte alta. La menos significativa
en la posición mas baja de memoria
El contenido de 2002 en AH y el de 2001 en AL.

INC Si suma 1 a la dirección donde apunta Si.


ADD Si, 2 incrementa el puntero. Siempre que Si esta sin corchetes se refiere al
puntero. Cuando esta con corchetes indica el contenido.

Ejercicio 7: De una lista de naturales encontrar los que representan la letra e, contarlos
y guardar en otra lista las direcciones donde se encuentran.

:0100 MOV CL, [1500] Carga en CL la longitud de la lista.


:0104 MOV SI, 2000 SI apunta al comienzo de la lista.
:0107 MOV DI, 6000 DI apunta al comienzo de otra lista.
:010A SUB BL, BL Pone BL en cero.
:010C MOV AL, [SI] Lleva a AL un caracter de la lista apuntada por SI.
:010E CMP AL, 45 Compara el valor de AL con 45.
:0110 JNZ 0119 Si no son iguales (Z=0) saltar a 119
:0112 INC BL Incrementa BL
:0114 MOV [DI], SI Escribe el valor de SI en la lista apuntada por DI
:0116 ADD DI,2 Suma 2 al puntero DI
:0119 INC SI Incrementa SI
:011A DEC CL Decrementa CL
:011C JNZ 010C Mientras Z=0, vuelve a 010C.
:011E MOV [1600], BL Carga en 1600 el valor del contador.
:0122 INT 20 Fin.

Ejercicio 8: Se tiene una lista de numeros naturales de 1 byte cada uno que empieza en
la direccion 2000. Su longitud está en la dirección 1500. Encontrar el mayor de los
números de la lista y guardarlo en la direccion 3000.

:0100 MOV CL, [1500] Carga en CL la longitud de la lista que esta en 1500.
:0104 MOV SI, 2000 SI apunta al comienzo de la lista de datos.
:0107 MOV AL, [SI] Lleva el primer nro de la lista a AL, suponiendo mayor.
:0109 INC SI Incrementa el puntero SI para tomar el segundo nro.
:010A DEC CL Decrementa CL, pues ya se tomó el primer nro de la lista.
:010C CMP AL, [SI] Compara el nro supuesto mayor en AL con el sig de SI.
:010E JA 0112 Saltar a 0112 si el nro que está en AL está por arriba.
:0110 MOV AL, [SI] Carga en AL el nuevo nro mayor apuntado por SI.
:0112 INC SI Incrementa SI para apuntar al prox elemento.
:0113 DEC CL Decrementa CL.
:0115 JNZ 010C Mientras Z sea 0, volver a 010C.
:0117 MOV [3000], AL Carga en 3000 el número mayor.
:011A INT 20 Fin.

También podría gustarte