Está en la página 1de 14

PRÁCTICA No.

SUBPROGRAMAS PARA REEMPLAZAR LAS INSTRUCCIONES DEL


MICROPROCESADOR 8086 NO SOPORTDOS POR EL SIMULADOR MSX88 Y SU
ENSAMBLADOR

Nombres: Jorge Oswaldo Ibarra Arango 1161294


Gabriel Santiago Becerra Ortiz 1161300
José Luis Carrizales Ortega 1161216

1. OBJETIVOS

1.1. Objetivo General

Construir un subprograma (subrutina) que realice las mismas funciones que una instrucción
de desplazamiento y rotación de bits no soportada por el simulador MSX88 y su
ensamblador.

1.2. Objetivos Específicos

 Elaborar un programa que realice las mismas funciones que una instrucción de
desplazamiento y rotación de bits.
 Hacer la documentación del programa: función, entradas, salidas, registros que afecta,
entre otros.
 Construir un subprograma o subrutina que reemplace la instrucción dentro de un programa
principal.

2. JUSTIFICACIÓN

La versión 3.0 MSX88 y su ensamblador fueron diseñados y construidos para simular un


microprocesador y los procesos que se realizan dentro del mismo para ejecutar una
instrucción y un programa. Como tal, se implementaron gran parte de las instrucciones del
microprocesador 8086 excepto, entre otras, aquellas que realizan desplazamientos de bits a
izquierda y derecha a través de un registro de propósito general incluida la bandera de
acarreo (CF).

3. EQUIPOS Y MATERIALES NECESARIOS

 MSX88 versión portable


 Editor de texto básico
 Pendrive o flash drive
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 1 de 14
 Cartilla de instrucciones del 8086

4. MARCO TEÓRICO

Desde su creación, el simulador MSX88 siempre tuvo como objetivo ser una herramienta
aplicada a la enseñanza de la electrónica y nunca la de ser un emulador de un
microprocesador tipo iAPx86; es por ello que su ensamblador está restringido a un grupo
básico de instrucciones, pero tal como dice el autor, “esta circunstancia da pie a interesantes
ejercicios de rediseño de dicho código” [1].

Un ejemplo de este tipo de ejercicios es el presentado en la página de SlidePlayer.es [2] para


reemplazar otra instrucción no soportada como el MUL.

Tal es el caso de las nueve instrucciones de desplazamiento y rotación [3]:

SAR Shift arithmetic right


SHR Shift logical right
SAL Shift arithmetic left
SHL Shift logical left
SHRD Shift right double
SHLD Shift left double
ROR Rotate right
ROL Rotate left
RCR Rotate through carry right
RCL Rotate through carry left

5. TRABAJO PREVIO:

Estudiar al detalle la función que realiza la instrucción de desplazamiento y rotación


seleccionada, su interacción con las banderas de Carry y Zero (CF y ZF) y la inserción o
eliminación de bits.

6. DESARROLLO DE LA PRÁCTICA

Se plantea un programa para convertir un número binario natural a código binario Gray. El
ejemplo se muestra a continuación:

ORG 2000H
MOV AL, 065h
MOV BL, AL
SHR BL, 01h
XOR AL,BL
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 2 de 14
HLT
END

En el momento de hacer la compilación, el MSX 88 arroja el siguiente error:

Y según el respectivo listado que arroja el MSX88 se debe a un error en la instrucción:

Listado Fuente: bin2gray.LST


Programa Fuente en: bin2gray.asm
Fecha: Fri Apr 03 11:57:01 2020

ÚDir.ÚCodigo máquina Linea¿ ÚCodigo en lenguaje ensamble

1 ORG 2000H
2000 B0 65 2 MOV AL, 065h
2002 8A D8 3 MOV BL, AL
4 SHR BL, 01h
Error: (null).
2004 32 C3 5 XOR AL, BL
2006 F4 6 HLT
7 END
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 3 de 14
Lo que corrobora que la instrucción no está soportada por el ensamblador.

Modificamos el programa para obtener el mismo objetivo:

ORG 2000H
mov al, 065h

mov bl, al ; se respalda el número binario a convertir


mov ah, 00h ; clareamos el registro AH para alojar el resultado allí.
mov cl, 07h ; el algoritmo consiste en sumar el número expresado en 16 bits
l1: add ax, ax ; registro AX consigo mismo, igual que multiplicar X 2 o
dec cl ; lo mismo que desplazar a la izquierda todo el número binario,
jnz l1 ; de hacerlo ocho veces el binario se traslada al registro AH,
mov al, bl ; desplazar siete veces es similar a tener el número original
mov bl, ah ; desplazado a la derecha una posición en el registro AH.

xor al, bl ; se construye el binario gray y se almacena en el AL.


hlt
END

Logramos obtener el resultado previsto: AL= 57H

Pero si necesitáramos utilizar varias veces la instrucción SHR BL, 01H dentro de un
programa de mayor tamaño, su extensión crecería aún más porque serían necesarias ocho
instrucciones, en este caso, para reemplazar la instrucción requerida. Para resolver el
problema acudimos a elaborar por única vez un programa al que llamaremos subrutina
(función, procedimiento o subprograma en otros lenguajes de alto nivel), que para el
ensamblador del MSX88 tiene unas reglas básicas de construcción que las veremos en
seguida:

1. A partir del programa principal trasladamos las instrucciones de la subrutina al


principio del texto. En ese espacio en blanco que deja este movimiento escribimos la
instrucción CALL.
2. Como se requiere una directiva de ORG, utilizamos una en una dirección posterior y
alejada de la dirección que por defecto debemos darle al programa principal. De existir
varias subrutinas es necesario tener en cuenta que deben estar suficientemente
separadas para que no se traslapen. En nuestro caso ORG 3000H.
3. Le colocamos a la primera instrucción de la subrutina una etiqueta que en adelante
servirá para identificarla y acceder a ella desde el programa principal. Si se quiere se
pueden cambiar las etiquetas de salto para ordenar mejor el texto; de todas formas no
deben existir dos etiquetas con el mismo nombre en todo el programa porque
producirá un error en la compilación.
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 4 de 14
4. Al final de la subrutina se adicional la instrucción RET; esto permitirá que la ejecución
del programa retorne a la instrucción siguiente a la instrucción que la llamó, el CALL
que colocamos en el punto 1, o sea que después resuelta la instrucción RET, la
siguiente instrucción que se ejecuta, en este ejemplo, es xor al, bl.
5. La instrucción CALL obliga al programa a realizar un salto, por lo tanto esta instrucción
debe tener una etiqueta que direccione el programa hacia la subrutina, en nuestro
caso sub1.

Finalmente nuestro programa queda así:

ORG 3000H
sub1: mov ah, 00h ;\
mov cl, 07h ;|
s1: add ax, ax ;\
dec cl ; | shr bl, 01h
jnz s1 ;/
mov al, bl ;|
mov bl, ah ;/
ret

ORG 2000H
mov al, 065h
mov bl, al

call sub1

xor al, bl
hlt
END

Documentemos la subrutina:

Nombre: sub1
Función: Desplaza el contenido del registro BL bit por bit una posición a la derecha. La
subrutina no lleva el bit de menor peso a la bandera de Carry pero si inserta un bit 0 en el bit
de mayor peso del registro.
Entrada: Número binario natural entre 00000000B y 11111111B en los registros AL y BL.
Salida: Número binario natural desplazado a la derecha un bit entre 00000000B y 01111111B
en el registro BL.
Registros que usa: AX, BL, CL y FR.
Subrutinas que llama: ninguna.
Como conclusión esta subrutina no reemplaza completamente la instrucción SHR BL, 01h
pero si funciona para los propósitos de nuestro programa.

Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 5 de 14
Cada grupo debe hacer lo propio con la instrucción que hayan seleccionado, solo se puede
repetir una sola instrucción por grupo.

SAR Shift arithmetic right


SAL Shift arithmetic left
SHL Shift logical left
SHRD Shift right double
SHLD Shift left double
ROR Rotate right
ROL Rotate left
RCR Rotate through carry right
RCL Rotate through carry left

La subrutina debe hacer parte de un programa principal y debe funcionar para cualquier valor
de entrada de código binario natural de ocho bits (00000000B – 11111111B)

7. EVALUACIÓN

a. Hacer un listado de las instrucciones del microprocesador 8086 no soportadas por el


simulador MSX88 y su ensamblador.

Instrucciones de transferencia de datos (No afecta flags):

 XCHG: reg, {reg|mem} Intercambia ambos valores.


 XLAT: Realiza una operación de traducción de un código de un byte a otro código
de un byte mediante una tabla. Operación: AL <- [BX+AL].
 LEA: reg, mem Almacena la dirección efectiva del operando de memoria en un
registro. Operación: reg <- dirección mem.
 LDS: reg,mem32 Operación: reg <- [mem], DS <- [mem+2]
 LES: reg,mem32 Operación: reg <- [mem], ES <- [mem+2]
 LAHF: Copia en el registro AH la imagen de los ocho bits menos significativos del
registro de indicadores. Operación: AH <- SF: ZF: X: AF: X: PF: X: CF.
 SAHF: Almacena en los ocho bits menos significativos del registro de indicadores el
valor del registro AH. Operación: SF: ZF: X: AF: X: PF: X: CF <- AH.

Instrucciones Aritméticas (Afectan los flags AF, CF, OF, PF, SF, ZF):

 DAA: Corrige el resultado de una suma de dos valores BCD empaquetados en el


registro AL (debe estar inmediatamente después de una instrucción ADD o ADC).
OF es indefinido después de la operación.
 DAS: Igual que DAA pero para resta (debe estar inmediatamente después de una
instrucción SUB o SBB).
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 6 de 14
 AAA: Lo mismo que DAA para números BCD desempaquetados.
 AAS: Lo mismo que DAS para números BCD desempaquetados.
 AAD: Convierte AH: AL en BCD desempaquetado a AL en binario. Operación: AL
<- AH * 0Ah + AL, AH <- 0. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan
indefinidos.
 AAM: Convierte AL en binario a AH: AL en BCD desempaquetado. Operación: AH
<- AL / 0Ah, AL <- AL mod 0Ah. Afecta PF, SF, ZF, mientras que AF, CF y OF
quedan indefinidos.
 MUL:

{reg8|mem8}. Realiza una multiplicación con operandos no signados de 8 por 8 bits.


Operación: AX <- AL * {reg8|mem8}. CF=OF=0 si AH = 0, CF=OF=1 en caso
contrario. AF, PF, SF, ZF quedan indefinidos.

{reg16|mem16}
Realiza una multiplicación con operandos no signados de 16 por 16 bits.
Operación: DX: AX <- AX * {reg16|mem16}. CF=OF=0 si DX = 0, CF=OF=1 en caso
contrario. AF, PF, SF, ZF quedan indefinidos.

 IMUL:

{reg8|mem8}. Realiza una multiplicación con operandos con signo de 8 por 8 bits.
Operación: AX <- AL * {reg8|mem8} realizando la multiplicación con signo. CF = OF
= 0 si el resultado entra en un byte, en caso contrario valdrán 1. AF, PF, SF, ZF
quedan indefinidos.

{reg16|mem16}
Realiza una multiplicación con operandos con signo de 16 por 16 bits.
Operación: DX: AX <- AX * {reg16|mem16} realizando la multiplicación con signo.
CF = OF = 0 si el resultado entra en dos bytes, en caso contrario valdrán 1. AF, PF,
SF, ZF quedan indefinidos.

 CBW: Extiende el signo de AL en AX. No se afectan los flags.


 CWD: Extiende el signo de AX en DX: AX. No se afectan flags.

Instrucciones Lógicas (Afectan AF, CF, OF, PF, SF, ZF):

 TEST: dest, src. Operación: dest and src. Sólo afecta flags.
 SHL/SAL: dest, {1|CL}. Realiza un desplazamiento lógico o aritmético a la
izquierda.
 SHR: dest, {1|CL}. Realiza un desplazamiento lógico a la derecha.
 SAR: dest, {1|CL}. Realiza un desplazamiento aritmético a la derecha.
 ROL: dest, {1|CL}. Realiza una rotación hacia la izquierda.
 ROR: dest, {1|CL}. Realiza una rotación hacia la derecha.
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 7 de 14
 RCL: dest, {1|CL}. Realiza una rotación hacia la izquierda usando el CF.
 RCR: dest, {1|CL}. Realiza una rotación hacia la derecha usando el CF.

En las siete instrucciones anteriores la cantidad de veces que se rota o desplaza puede ser
un bit o la cantidad de bits indicado en CL.

Instrucciones de manipulación de cadena:

 MOVSB:

Copiar un byte de la cadena fuente al destino.


Operación:
ES:[DI] <- DS:[SI] (un byte)
DI <- DI±1
SI <- SI±1

 MOVSW:

Copiar dos bytes de la cadena fuente al destino.


Operación:
ES:[DI] <- DS:[SI] (dos bytes)
DI <- DI±2
SI <- SI±2

 LODSB:

Poner en el acumulador un byte de la cadena fuente.


Operación:
AL <- DS: [SI] (un byte)
SI <- SI±1

 LODSW:

Poner en el acumulador dos bytes de la cadena fuente.


Operación:
AX <- DS:[SI] (dos bytes)
SI <- SI±2

 STOSB:

Almacenar en la cadena destino un byte del acumulador.


Operación:
ES:[DI] <- AL (un byte)
DI <- DI±1
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 8 de 14
 STOSW:

Almacenar en la cadena destino dos bytes del acumulador.


Operación:
ES:[DI] <- AX (dos bytes)
DI <- DI±2

 CMPSB:

Comparar un byte de la cadena fuente con el destino.


Operación:
DS:[SI] - ES:[DI] (Un byte, afecta sólo los flags)
DI <- DI±1
SI <- SI±1

 CMPSW:

Comparar dos bytes de la cadena fuente con el destino.


Operación:
DS:[SI] - ES:[DI] (Dos bytes, afecta sólo los flags)
DI <- DI±2
SI <- SI±2

 SCASB:

Comparar un byte del acumulador con la cadena destino.


Operación:
AL - ES:[DI] (Un byte, afecta sólo los flags)
DI <- DI±1

 SCASW:

Comparar dos bytes del acumulador con la cadena destino.


Operación:
AX - ES:[DI] (Dos byte, afecta sólo los flags)
DI <- DI±2

En todos los casos el signo + se toma si el indicador DF vale cero. Si vale 1 hay
que tomar el signo -.

Prefijo para las instrucciones MOVSB, MOVSW, LODSB, LODSW, STOSB,


STOSW:

Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 9 de 14
 REP: Repetir la instrucción CX veces.
Prefijos para las instrucciones CMPSB, CMPSW, SCASB, SCASW:

 REPZ/REPE: Repetir mientras sean iguales hasta un máximo de CX veces.

 REPNZ/REPNE: Repetir mientras que sean diferentes hasta un máximo de CX.

Instrucciones de Transferencia de Control (No afectan los flags):

 RETN: [inmed]. En el mismo segmento de código. Equivale a POP IP [:SP <- SP +


inmed].
 RETF: [inmed]. En otro segmento de código. Equivale a POP IP: POP CS [:SP <-
SP + inmed]

Saltos condicionales aritméticos (usar después de CMP):

Aritmética asignada (con números positivos, negativos y cero):

 JL: etiqueta/JNGE etiqueta. Saltar a etiqueta si es menor.


 JLE: etiqueta/JNG etiqueta. Saltar a etiqueta si es menor o igual.
 JE: etiqueta. Saltar a etiqueta si es igual.
 JNE: etiqueta. Saltar a etiqueta si es distinto.
 JGE: etiqueta/JNL etiqueta. Saltar a etiqueta si es mayor o igual.
 JG: etiqueta/JNLE etiqueta. Saltar a etiqueta si es mayor

Aritmética sin signo (con números positivos y cero):

 JB: etiqueta/JNAE etiqueta. Saltar a etiqueta si es menor.


 JBE: etiqueta/JNA etiqueta. Saltar a etiqueta si es menor o igual.
 JE: etiqueta. Saltar a etiqueta si es igual.
 JNE: etiqueta. Saltar a etiqueta si es distinto.
 JAE: etiqueta/JNB etiqueta. Saltar a etiqueta si es mayor o igual.
 JA: etiqueta/JNBE etiqueta. Saltar a etiqueta si es mayor.

Saltos condicionales según el valor de los indicadores:

 JP/JPE: label. Saltar si la paridad es par (PF = 1).


 JNP/JPO: label. Saltar si la paridad es impar (PF = 0).

Saltos condicionales que usa el registro CX como contador:


 LOOP: label. Operación: CX <- CX-1. Saltar a label si CX<>0.
 LOOPZ / LOOPE: label. Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 1.

Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 10 de 14
 LOOPNZ / LOOPNE: label. Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF =
0.
 JCXZ: label. Operación: Salta a label si CX = 0.

Instrucciones de Manejo de interrupciones:


 INTO: Interrupción condicional. Si OF = 1, hace INT 4.

Instrucciones de Control del Procesador:

 CLC: CF <- 0.
 STC: CF <- 1.
 CMC: CF <- 1 - CF
 CLD: DF <- 0 (Dirección ascendente).
 STD: DF <- 1 (Dirección descendente).
 WAIT: Detiene la ejecución del procesador hasta que se active el pin TEST del
mismo.
 LOCK: Prefijo de instrucción que activa el pin LOCK del procesador.

b. Documentar la subrutina de acuerdo con la teoría vista en clase: Nombre, función,


entradas, salidas y registros que utiliza.

Planteamos un programa para convertir un número binario natural a código binario Gray,
para este caso es necesario elaborarlo con la instrucción ROR. El ejemplo se muestra a
continuación:

ORG 2000H

MOV AL, 065h


MOV BL, AL
ROR BL, 01h
SUB BL, 80h
XOR AL, BL
HLT
END

Como la instrucción no está soportada por el ensamblador, debemos utilizar las instrucciones
que soporta el MSX88, y elaborar un programa que elabore lo que en su caso haría la
instrucción ROR. El ejemplo se muestra a continuación:

Modificamos el programa para obtener el mismo objetivo:

Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 11 de 14
ORG 2000H

mov al, 057h


mov bl, al
mov ah, 00h
mov cl, 07h
s1: add ax, ax
dec cl
jnz s1
mov al, bl
mov bl, ah
mov cl, al
and cl, 01h
add bl, 080h
xor al,ah

hlt

Logramos obtener el resultado previsto: AL= 57H

Pero si necesitáramos utilizar varias veces la instrucción ROR BL, 01H dentro de un
programa de mayor tamaño, su extensión crecería aún más porque serían necesarias ocho
instrucciones, en este caso, para reemplazar la instrucción requerida. Para resolver el
problema acudimos a elaborar por única vez un programa al que llamaremos subrutina
(función, procedimiento o subprograma en otros lenguajes de alto nivel), que para el
ensamblador del MSX88 tiene unas reglas básicas de construcción que las veremos en
seguida:

Finalmente nuestro programa queda así:

ORG 3000h

sub1: mov ah, 00h


mov cl, 07h
s1: add ax, ax
dec cl
jnz s1
mov al, bl
mov bl, ah
mov cl, al
and cl, 01h

jz s2
Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 12 de 14
add bl, 080h
xor al,ah

s2: ret

ORG 2000H

mov al, 065h


mov bl, al

call sub1

hlt

END
END

Documentando la subrutina:

Nombre: sub1

Función: Genera la rotación bit por bit una posición la derecha, del bit menos significativo al
más significativo en el registro Ax (AH-AL). La subrutina no lleva el bit de menor peso a la
bandera de Carry.

Entrada: Funciona para cualquier valor de entrada de código binario natural de ocho bits
(00000000B – 11111111B)

Salida: Funciona rotando un binario natural a la derecha un bit entre 00000000B y


11111111B en el registro BL.

Registros que usa: AX (AH-AL), BL, CL y FR.

Subrutinas que llama: ninguna.

c. Observar los cambios que se presentan en los registros IP, SP, FR y las direcciones
de memoria apuntadas por el registro SP durante la ejecución del programa. Escriba
sus observaciones.

El registro SP varía cuando es llamada la subrutina y posteriormente cuando la subrutina


retorna el registro vuelve a la posición que estaba antes de ejecutarse la subrutina. El

Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 13 de 14
registro IP va variando a medida que se ejecuta el código, mostrando la dirección donde se
está realizando la instrucción ya sea antes, durante y después de ser llamada la subrutina.

8. BIBLIOGRAFÍA

[1] R. Martinez. “Msx88: Una herramienta para la enseñanza de la estructura y


funcionamiento de los ordenadores”. TAEE 94. I Congreso de Tecnologías Aplicadas a
la Enseñanza de la Electrónica. Madrid, 1994. Sesión D2. Microprocesadores y
sistemas basados en microprocesador.
[2] I. Belmonte de la Fuente. “Clase 6. Assembly – Simulador MSX88. Subrutinas”. 2019.
[Online] 2020. Disponible: https://slideplayer.es/slide/13691020/

[3] A. Intel. “Volumen 1: Basic Architecture” U.S.A. 1997. Software Developer´s Manual.

Arquitectura de Computadores – Autor Sergio Iván Quintero Ayala

Página 14 de 14

También podría gustarte