• No se han encontrado resultados

Y SIMULADOR DE UN MICROPROCESADOR"

N/A
N/A
Protected

Academic year: 2018

Share "Y SIMULADOR DE UN MICROPROCESADOR""

Copied!
83
0
0

Texto completo

(1)

UNIVERSIDAD AUTONOMA METROPOLITANA UNIDAD IZTAPALAPA

DOCUMENTACION DEL PROYECTO TERMINAL I1

"ENSAMBLADOR Y SIMULADOR DE UN MICROPROCESADOR"

ALUMNO: SERGUEI MENDOZA SOYLOVICH ASESOR: FRANCISCO OLVERA

(2)

INDICE:

INTRODUCCION

APENDICE A: LISTA DE ARCHIVOS QUE CONSTITUYEN EL PROYECTO APENDICE B: PASOS A SEGUIR PARA GENERAR EL ENSAMBLADOR Y EL

SIMULADOR

APENDICE C: GRAMATICA DEL ENSAMBLADOR

APENDICE D: LISTA DE INSTRUCCIONES DEL ENSAMBLADOR LISTADO esp1ex.c

(3)

Este proyecto fue realizado durante el trimestre 91-1 en la Universidad Autónoma Metropolitana, Unidad Iztapalapa. El proyecto fue dirigido por el Ing. Francisco Olvera y surgió como una oportunidad de conocer mejor la mecánica del funcionamiento de un procesador, a la vez que permitió obtener un mejor manejo de los generadores de analizadores sintácticos y léxicos, como lo son YACC y LEX. Asimismo, el manejo de programas con muchas líneas de código es un buen fogueo para un estudiante de computación, ya que permite la generación de una disciplina y una consciencia de la importancia de una buena documentación para el éxito final de un proyecto.

El proyecto consiste de dos partes : la primera, es un programa ensamblador que genera un seudocódigo objeto para un microprocesador hipotlético, utilizo el término de

"seudocódigo", porque en el archivo que genera el ensamblaclor , cada línea consiste del código fuente original, conlbinado con el código objeto que éste genera, esta técnica se empleó para poder tener disponibles al emulador los nombres simbólicos ;asignados a las variables y a las etiquetas: la segunda parte es un programa emulador que permite ejecutar paso a paso el código objeto generado por el ensamblador, desplegando el contenido de los registros y de la memoria del microprocesador y permitiendo modificar los mismos ( debido a esta última característica, este programa también se podría denominar como depurador ).

(4)

APENDICE A

LISTA DE ARCHIVOS QUE CONSTITUYEN EL PROYECTO:

1) El programa ensamblador consiste de los siguientes archivos:

1 .l. esp1ex.c

-

especificaciones para LEX 1.2. cod1ex.c

-

lista de cedigos para LEX 1.3. espyac.c

-

especificaciones para YACC

1.4. myasm.c

-

programa principal del ensamblador 1.5. y0ut.c

-

salida generada por YACC

1.6.lout.c

-

salida generada por LEX

2) El programa simulador del micoprocesador consiste de

los siguientes archivos:

2.1. mysim.c

-

programa principal del simulador 2.2. p0pup.h

-

rutinas de manejo de ventanas 2.3. m0use.h

-

rutinas de manejo del mouse

(5)

APENDICE B

1)

PASOS A SEGUIR PARA GENERAR EL ENSAMBLADOR

Para poder generar el ensamblador a partir de los archivos fuentes se siguieron los pasos que a continuacion se describen:

1 .l.

CAex esp1ex.c ( se genera como salida 1exyy.c )

1.2.

C>copy 1exyy.c 1out.c ( para evitar la sobreescritura de 1exyy.c )

1.3.

C>yacc espyacc.c ( se genera como salida ytab.c )

1.4.

C>copy ytab.c y0ut.c ( para evitar la sobreescritura de ytab.c )

1

S . C>edit y0ut.c ( borrar "#" em la linea

1370

aproximadamente )

1.6.

C>tc myasm.c ( se compila myasm.c y se genera myasm.exe )

2) PASOS A SEGUIR PARA GENERAR EL SlMULADOFl

2.1.

Entrar a Turbo C

2.2.

Cargar el project mysim.prj

2.3.

Ejecutar la opcien de compilacitn

(6)

APENDICE C

GRAMATICA DEL ENSAMBLADOR

PROG : DECLS PROG-DECL

I PROG-DECL

DECLS : DECL

I DECLS DECL

DECL : ID EQU HEX

I ID EQU DHEX

I ID DB HEX

I DB HEX

I ID DEFS HEX

I DEFS HEX

PROG-DECL: CUERPOSEND

CUERPOS: CUERPO

I CUERPOS CUERPO

I

CUERPO : ORG HEX INSTS

Y

INSTS : INST

I INSTS INST ,

INST : ET1 OPERACION

I OPERACION

I ET1 OPERACIONU OPERANDO I OPERACIONU OPERANDO

I ET1 OPERACIONB OPERANDO, OPIERANDO

(7)

APENDICE D

LISTA DE INSTRUCCIONES DEL ENSAMBLADOR:

NOTACION: RR= AL, AH, BL, BH DD= A X , BX, IX, SP QQ= A X , BX, IX, IF PP1= A X , BX, IY, SP PP2= AX, BX, IX, SP WW= A X , BX, IX, IY

l. GRUPO DE INSTRUCCIONES DE CARGA DE 8 BITS;

1. LD R,R 2. LD R,N 3. LD R,(IX+D) 4. LD R,(IY+D) 5. LD (IX+D),R 6. LD (IY+D),R 7. LD (IX+D),N 8. LD (IY+D),N 9. LD AL,(NN) 10. LD (NN),AL 11. LD AL,INTV 12. LD INTV,AL

2. GRUPO DE INSTRUCCIONES DE CARGA DE 16 BITS

1. LD DD,NN 2. LD IY,IX 3. LD DD,(NN) 4. LD (NN),DD 5. LD SP,IX 6. PUSH QQ

7. POP QQ

3. GRUPO DE INSTRUCCIONES ARITMETICAS Y LOGICAS

1. ADD RR 2.ADD N 3. ADD (IX+D) 4. ADD (IY+D) 5. ADC RR 6. SUB RR 7. SBC RR

8.AND RR

(8)

4. GRUPO DE INSTRUCCIONES GENERALES 1. DAA

2. CPL 3. NEG 4. CCF 5. SCF 6. NOP 7. HALT 8. DI 9. El

5. GRUPO DE INSTRUCCIONES ARITMETICAS DE 16 IBITS

l. ADW AX,BX 2. ACW AX,BX 3. SCW AX,BX 4. ADW IX,PPl 5. ADW IY,PP2 6 . INC WW

7. DEC WW

6. GRUPO DE ROTACION Y SHIR-

1. RLC RR 2. RLC (IX+D)

3. RLC (IY+D) 4. RL RR 5 . R R RR 6. RRC RR 7. SL RR 8.SR RR

7. GRUPO DE SET, RESET Y TEST BIT

(9)

8. GRUPO DE JUMP, CALL Y RETURN 1. JP NN

2. JPC CC,NN 3. JR EE 4. JRC CC,EE

5. JP (IX)

(10)

/* Especificaciones para LEX ( esp1ex.c ) */ extern int nolines=O;

I [A-Z] /* letra */ d [O-91 I* digit0 *I

h [O-9a-fl /* digito hexadecimal */

%o%

"AL" return(tok-no=c-AL); "AH" return(tok-no=c-AH); "BL" return(tok-no=c-BL); "BH" return(tok-no=c-BH);

" I Y " return(tok-no=c-lY); " A X return(tok-no=c-AX); "BX' return(tok-no=c-BX); " I X return(tok-no=c-IX); "SP" return(tok-no=c-SP);

"FLAGS" return(tok-no=c-FLAGS); "INTV return(tok-no=c-lNTV);

"LD" return(tok-no=c-LD);

"PUSH"return(tok"no=c-PUSH); "POP" return(tok-no=c-POP); "ADD" return(tok-no=c-ADD); "ADC" return(tok-no=c-ADC); "SUB" return(tok-no=c-SUB); "SBC" return(tok-no=c-SBC); " A N D return(tok-no=c-AND); "OR" return(tok-no=c-OR);

"XOR" return(tok-no=c-XOR); "INC" return(tok-no=c-INC); "DEC" return(tok-no=c-DEC); "DAA" return(tok-no=c-DAA); "CPL" return(tok-no=c-CPL); "NEG" return(tok-no=c-NEG); "CCF" return(tok-no=c-CCF); "SCF" return(tok-no=c-SCF); "HALT" return(tok-no=c-HALT); "DI" return(tok-no=c-DI);

"El" return(tok-no=c-El); "RLC" return(tok-no=c-RLC); "RL" return(tok-no=c-RL); "RR" return(tok-no=c-RR);

"RRC" return(tok-no=c-RRC); "SL" return(tok-no=c-SL); "SR" return(tok-no=c-SR); "Blf" return(tok-no=c-BIT); "SET" return(tok-no=c-SET); "RES" return(tok-no=c-RES); "JP" return(tok-no=c-JP);

(11)

" J R C return(tok-no=c-JRC); "ADW' return(tok-no=c-ADW); " A C W return(tok-no=c-ACW); " S C W return(tok-no=c-SCW);

"NZ" "Z" "NC"

"C" "S" "NS" "P" "N P"

return(tok-no=c-NZ); return(tok-no=c-Z); return(tok-no=c-NC); return(tok-no=c-C); return(tok-no=c-S); return(tok-no=c-NS); return(tok-no=c-P); return(tok-no=c-NP);

"ORG" return(tok-no=c-ORG); "END" return(tok-no=c-END); "EQU" return(tok-no=c-EQU); "DB" return(tok-no=c-DB); "DEFS" return(tok-no=c-DEFS);

{N{lIl{d))* {

strcpy(tokstr,yytext); return(tok-no=c-id);

1

{h){h) {

tokvall=tokval2=0; strcpy(tokstr,yytext); tokvall =conv-hex(tokstr);

return(tok-no=-hex); /* hex de 2 digitos */

1

v"o{h){h) {

tokvall =O;

strcpy(tokstr,yytext);

tokvall =conv-hex(tokstr)*256; tokvall +=conv_hex(tokstr+2);

return(tok-no=c-dhex); /* hex de 4 digitos */ "+" return(c-mas);

I, I S

return(c-menos);

return(c-pyc); return(c-2p); "(" return(c-p-a); '7" return(c-p-c);

" "+ ;

\n {

I t 11 return(c-coma);

VI. I t ,I. ,u

(12)

int chextoint(char *cp) /* convierte un digito hex a entero */ {

int aux=O;

if(*cp>='O' && *cp<='9') aux=*cp-'0';

aux=*cp-87; else

return(aux);

1

int conv-hex(char *cp) /* convierte un numero hex a entero */ {

int aux=O;

aux=chextoint(cp)*l6; aux+=chextoint(cp+l); return(aux);

}

YYwraPO {

1

(13)

I* archivo cod1ex.x : codigos de salida para lex *I

#define c-AL 257 #define c-AH 258 #define c-BL 259 #define c-BH 260 #define c-lY 261

#define c-AX 262 #define c-BX 263 #define c-lX 264

#define c-SP 265 #define c-FLAGS 266 #define c-INTV 267

/* definiciones de condiciones de salto *I

#define c-NZ 268 #define c-Z 269 #define c-NC 270 #define c-C 271 #define c-S 272 #define c-NS 273 #define c-P 274 #define c-NP 275

I* definiciones de codigos de operaciones *I

#define c-LD 276 #define c-PUSH 277

#define c-POP 278

#define c-ADD 279 #define c-ADC 280 #define c-SUB 281 #define c-SBC 282 #define c-AND 283 #define c-OR 284 #define c-XOR 285 #define c-INC 286 #define c-DEC 287 #define c-DAA 288 #define c-CPL 289 #define c-NEG 290 #define c-CCF 291 #define c-SCF 292 #define c-HALT 293 #define c-DI 294 #define c-El 295

(14)

#define c-JP 305 #define c-JR 306 #define c-DJNZ 307 #define c-CALL308 #define c-RET 309 #define c-RETI 310 #define c-JPC 31 1 #define c-JRC 312

#define c-mas #define c-menos #define c-coma #define c-pyc #define c-p-a #define c-p-c #define c-id #define c-dec #define c-hex #define c-dhex #define c-2p #define c-ORG #define c-END #define c-DB #define c-DEFS #define c-EQU #define c-CR #define c-ADW #define c-ACW #define c-SCW

(15)

/* archivo espyacc.c :

/* DEFINICIONES #include <stdio.h> #define c-IXD 400 #define c-IYD 401 #define c-IXP 402 Mefine c-IYP 403

%{

especificaciones de entrada para yacc *I

*/

#define c-APNN 404

#define c-OPNR 405 /* Operando No Resuelto */ ##define c-OPR 406 /* Operando Resuelto */ #define c-APID 407

#define c-IXID 408 #define c-IYID 409

struct line-node{

int c-tok; /* codigo de token */

char nombre[lO]; /* si es etiqueta, leyenda */ int valor; /* si es numero, valor */

1;

int byte?; int byte2; int byte3; int status? ; int status2; int status3; int num; int pcounter;

struct code-line *next;

struct code-line{ /* codigo generado por una linea de ensamblador */

1:

struct etistr{ /* cadena con la leyenda de un etiqueta */ char name[l O];

int value; >;

char name[l O];

int value;

struct lab-node *next; struct lab-node *prev;

struct lab-node{ /* nodo de la lista de etiquetas */

struct

struct

1;

ref-node{ /* nodo de la lista de referencias */ int ref;

struct ref-node *next;

1;

op-node{ /* nodo de la lista de operandos */ char name[l O];

(16)

1;

... I /* VARIABLES GLOBALES *I

struct lab-node *lab-head=NULL; I* lista de labels *I

struct op-node *op-head=NULL; /* lista de operandos "I

struct line-node linea[4]; I* una linea consiste a lo mas de 4 elem */ struct etistr eti;

int tok-no; I* codigo del token *I

int tokvall ,tokval2; int nolines=O; char tokstr[50];

struct code-line *first-line=NULL; I* lista de codigo *I

int seguir; int va1,stat;

int pc=O; I* program counter *I

int bytes=O; /* cuantos bytes incrementar el PC */

... I

%)

%Start PROG

%token c-AL c-AH c-BL c-BH c-lY c-AX c-BX c-lX c-SP c-.FLAGS c-INTV c-NZ c-Z c-NC c-C c-Sc-NS c-P c-NP c-LD c-PUSH c-POP c-ADD

c-ADC c-SUB c-SBC c-AND c-OR c-XOR c-INC c-DEC c-DAA c-CPL c-NEG c-CCF c-SCF c-HALT c-DI c-El c-RLC c-RL c-RR c-RRC c-SL c-SR

c-BIT c-SET c-RES c-JP c-JR c-DJNZ c-CALL c-RET c-RET1 c-JPC c-JRC c-mas c-menos c-coma c-pyc c-p-a c-p-c c-id c-dec c-hex c-dhex c-2p c-ORG c-END c-DB c-DEFS c-EQU c-CR c-ADWI c-ACW c-SCW %%

PROG : EQUS PROG-DECL

I

PROG-DECL

EQUS : EQU

I

EQUS EQU

EQU : ID

c-EQU c-hex {

eti.value=tokvall;

lab-mngr(eti.name,eti.value,&seguir); if(seguir==O)

myerror(nolines,l);

1

I

ID

c-EQU c-d hex {

eti.value=tokvall ;

lab-mngr(eti.name,eti.value,&seguir); if(seguir==O)

(17)

ID : c-id {

strcpy(eti.name,tokstr);

PROG-DECL: CUERPOS C-END

CUERPOS

I

CUERPO

DEFSINS :

I

DEFS :

I

CUERPO

CUERPOS CUERPO

c-ORG c-hex

{

pc=tokvall ;

1

DEFSINS

DEFS INSTS INSTS

DEF DEFS DEF

DEF : ETlQ

c-DB c-hex {

eti.value=pc;

lab-mngr(eti.name,eti.value,&seguir);

if(seguir==O)

myerror(nolines,l);

1

I

c-DB

I

ETlQ

c-hex

c-DEFS c-hex

c-hex

I

c-DEFS

INSTS : INST

I

INSTS INST

INST : OPERACION

{

ini(linea);

(18)

pc+=bytes;

1

I

ETlQ

C 2 P

OPERACION {

ini(linea); eti.value=pc;

lab-mngr(eti.name,eti.value,&seguir); if(seguir==O)

else

{

myerror(nolines,l);

linea[l].c-tok=tok-no; gen-cod(linea,&bytes); pc+=bytes;

1

1

I

OPERACIONU {

ini(linea);

linea[l].c-tok=tok-no;

}

OPERANDO {

if(tok-no==c-id) /* si es identificador */

{

strcpy(eti.name,tokstr);

op-mngr(eti.name,nolines,&val,&stat);

if(stat) /* si esta en la lista *I

{

linea[2].c-tok=c-OPR; linea[2].valor=val; gen-cod(linea,&bytes); pc+=bytes;

1

else I* no esta */

{

linea[2].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes;

1

1

{

else /* no es un identificador */

linea[2].c-tok=tok-no; linea[2].valor=tokvall;

strcpy(linea[2].nombre,tokstr);

gen-cod(linea,&bytes); pc+=bytes;

I

ETlQ

OPERACIONU {

ini(1inea); L 2 P

(19)

lab-mngr(eti.name,eti.value,&segulir); if(seguir==O)

linea[l].c-tok=tok-no; myerror(nolines,l);

1

{ OPERANDO

if(tok-no==c-id) I* si es identificador *I

{

strcpy(eti.name,tokstr);

op-mngr(eti.name,nolines,&val,&stat);

if(stat) I*

si

esta en la lista *I {

linea[2].c-tok=c-OPR; linea[2].valor=val; gen-cod(linea,&bytes); pc+=bytes;

1

else I* no esta *I {

linea[2].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes;

1

1

{

else I* no es un identificador *I

linea[2].c-tok=tok-no; linea[2].valor=tokvall;

gen-cod(linea,&bytes); pc+=bytes;

strcpy(linea[2].nombre,tokstr);

1

1

IOPERACIONB {

ini(linea);

linea[l].c-tok=tok-no;

1

OPERANDO {

{

if(tok-no==c-id) I* si es identificadolr *I

strcpy(eti.name,tokstr);

op-mngr(eti.name,nolines,&val,&stat);

if(stat) I* si esta en la lista *I {

linea[2].c-tok=c-OPR; linea[2].valor=val;

1

else I* no esta *I

{

1

linea[2].c-tok=c-OPNR;

1

{

else I* no es un identificador *I

(20)

I

linea[2].valor=tokvall;

strcpy(linea[2].nombre,tokstr);

1

1

c-coma

OPERANDO {

if(tok-no==c-id) I* si es identificador *I

{

strcpy(eti.name,tokstr);

op-mngr(eti.name,nolines,&val,&stat);

if(stat) I* si esta en la lista *I

linea[3].c-tok=c-OPR; linea[3].valor=val; gen-cod(linea,&bytes); pc+=bytes;

else I* no esta *I

{

1

{

linea[3].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+= bytes;

1

1

{

else I* no es un identificador *I

linea[3].c_tok=tok-n0; linea[3].valor=tokvail;

strcpy(linea[3].nombre,tokstr);

gen-cod(linea,&bytes); pc+=bytes;

1

IETIQ

C 2 P

OPERACIONB C

ini(linea);

eti.value=pc;

lab-mngr(eti.name,eti.value,&seguir); if(seguir==O)

linea[l].c-tok=tok-no; myerror(nolines,l);

1

OPERANDO {

if(tok-no==c-id) I* si es identificador *I

{

strcpy(eti.name,tokstr);

op-mngr(eti.name,nolines,&val,&stat);

if(stat) I*

si

esta en la lista *I

{

Iinea[2].c_tok=c_OPR; linea[2].valor=val;

1

(21)

{

1

linea[2].c-tok=c-OPNR;

1

else /* no es un identificador *I {

linea[2].c-tok=tok-no; linea[2].valor=tokvall;

strcpy(linea[2].nombre,tokstr);

1

1

c-coma

OPERANDO {

if(tok-no==c-id) I* si es identificador *I {

strcpy(eti.name,tokstr);

op-mngr(eti.name,nolines,&val,&stat);

if(stat) I* si esta en la lista *I

{

Iinea[3].c_tok=c_OPR; linea[3].valor=val; gen-cod(linea,&bytes); pc+=bytes;

else I* no esta *I

1

{

linea[3].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes;

1

1

{

else I* no es un identificador *I

linea[3].c-tok=tok-no; linea[3].valor=tokvall;

strcpy(linea[3].nombre,tokstr); gen-cod(linea,&bytes);

pc+=bytes;

1

1

ETlQ : c-id {

strcpy(eti.name,tokstr);

1

OPERACION : c-CPL

I

c-NEG

I

c-CCF

1

c-SCF

1

c-DI

1

c-IEI

I

c-HALT

I

c-RET

I

c-RETI

OPERACIONU : c-PUSH

I

c-POP

I

c-ADD

I

c-ADC

I

c,SUB

I

c-SBC

1

c-AND

I

c-OR

I

c-XOR

I

c-INC

1

c-DEC

1

c-RLC

1

c-RL

I

c-RR

(22)

OPERACIONB : c-LD

I

c-ADW

I

c-ACW

I

c-SCW

I

c--BIT

I

c-SET

I

c-RES

I

c-JPC

I

c-JRC

c-p-a c-lX c-p-c { tok-no=c-lXP; } c-p-a c-lY c-p-c { tok-no=c-lYP; } c-p-a c-dhex c-p-c { tok-no=c-APNN; } c-p-a c-id c-p-c { tok-no=c-id; }

c-p-a c-lX SIGNO c-hex c-p-c { tok-no=c-lXD; }

c-p-a c-lX SIGNO c-id c-p-c { tok-no=c-lXID; } c-p-a c-lY SIGNO c-id c-p-c { tok-no=c-lYID; } c-p-a c-lY SIGNO c-hex c-p-c { tok-no=c-lYD; }

SIGNO : c-mas

I

c-menos

... / /* manejo de listas */

... /

/* generacion de url nodo para la lista de codigo */ struct code-line *new-code-lineO

{

struct code-line *aux;

aux=(struct code-line *)malloc(sizeof(struct code-line)); aux->bytel =O;

aux->byte2=0; aux->byte3=0; aux->status1 =O; aux->status2=0; aux->status3=0; aux->num=O; aux->pcounter=O; aux->next=NULL;

1

/* agregar codigo generado a la lista de codigo */

add-code(int b l ,int b2,int b3,int s l ,int s2,int s3,int num,int cp) {

struct code-line *auxl ,*aux2,*aux3;

if (first-line==NULL) /* primera linea de codigo */ {

(23)

I

else {

I

I

first-line->status2=s2; first-line->status3=s3; first-line->num=num; first-line->pcounter=cp;

I* ya hay lineas de codigo *I

auxl =first-line;

while ( aux2=aux1 ->next )

aux2=new_code_lineo; aux2->bytel = b l ; aux2->byte2=b2; aux2->byte3=b3; aux2->statusl = s l ; aux2->status2=s2; aux2->status3=s3; aux2->num=num; aux2->pcounter=cp; auxl->next=aux2;

auxl=aux2 ; I* auxl is the last node*/

I* imprimir la lista de codigo *I

print-codeo {

struct code-line *aux; aux=first-line;

while(aux) {

printf("1ine %d , PC %x :",aux->num,aux->pcounter); if(aux-xtatusl) printf("%x ",aux->bytel);

if(aux->status2) printf("%x ",aux->byte2); if(aux->status3) printf("%x ",aux->byte3); printf("\n");

aux=aux->next;

I

1

I* manejo de errores *I

myerror(int lineajnt error-no) {

switch(error-no){ case 1:

printf("Error: break;

printf("Error: break; case 2:

I

exit(1);

I

operandos incorrectos en linea %d\n",linea);

referencia incorrecta en linea %d\n",linlea);

I* inicializar la estructura para una linea *I

(24)

int i;

for(i=O;i<4;i++)

{

1

linaux[i].c-tok=O;

/* funcion auxiliar para generar el codigo de una operacion */

add-op(int *code,int cod-op)

{

switch(cod-op){

case c-AX: *code=*codelOxO; break; case c-BX: *code=*codelOxl; break; case c-IX: *code=*codelOx2; break; case c-FLAGS: *code=*codelOx3; break; default: myerror(nolines,l); break;

1

1

... I

/* generacion de codigo para instrucciones sin operandos*l

... I

codigo-op(struct line-node 1[4],int *codl)

{

switch(l[l].c-tok){

case c-CPL: *codl=Ox99; break; case c-NEG: *cod1 =Ox9a; break; case c-CCF: *codl=Ox9b; break; case c-SCF: *codl=Ox9c; break; case c-DI: *codl=Ox9e; break; case c-El. *codl=Ox9f; break; case c-HALT: *cod1 =Ox9d; break;

case c-RET: *cod1 =0xe9; break;

case c-RETI: *codl=Oxea; break;

1

1

/* funcion auxiliar para generar el codigo de una operacion *I

add-rr(int *code,int cod-op)

{

switch(cod-op){

case c-AL: *code=*codelOxO; break;

case c-AH: *code=*codelOxl ; break;

case c-BL: *code=*codelOx2; break; case c-BH: *code=*codelOx3; break; default: myerror(nolines,l); break;

1

/* funcion auxiliar para generar el codigo de una operacion */

add_rr2(int *code,int cod-op)

{

switch(cod-op){

case c-AL: *code=*codelOxO; break;

(25)

case c-BL: *code=*code)Ox2; break; case c-BH: *code=*codelOx3; break;

1

1

/* funcion auxiliar para generar el codigo de una operacion *I

addwrr3(int *code,int cod-op) {

switch(cod-op){

case c-AL: *code=*codelOxO; break; case c-AH: *code=*codelOx4; break; case c-BL: *code=*codelOx8; break; case c-BH: *code=*codelOxc; break;

1

... I I* generacion de codigo para instrucciones de dos operandos *I ... I

codigo-opb(struct line-node 1[4],int *cod1 ,int *cod2,int *cod3,

{

int *SI, int *s2, int *s3)

int auxint=O; int s=O; int c=O; *S1 =1;

switch(l[l].c-tok){ /* main switch *I

case c-LD:

if((l[2].c-tok==c-AL

11

I[2].c_tok==c_AH

11

l[2].c_tok==c_BL

11

l[2].c_tok==c_BH) && (l[3].c_tok==c_AL

11

I[3].c-tok==c-AH

/I

1[3].c_tok==c_BL

11

1[3].c_tok==c_BH

11

l[3].c_tok==c_lXD

11

I[3].c-tok==c-lYD

11

I[3].c-tok==c_lXIDII I[3].c-tok==c-lYID

11

1[3].c-tok==c_hex))

{

*cod1 =O;

*codl=add-rr3(codl,1[2].c-tok);

if(I[3].c_tok==c_AL

11

I[3].c-tok==c-AH

I(

1[3].c-tok==c-BL

1)

I[3].c_tok==c_BH)

*codl=add-rr2(codl,1[3].c-tok);

{

1

{ else

switch(l[3].c-tok){

case c-hex: *cod1 =Ox1 O;

*codl=add-rr2(codl,1[2].c-tok);

*cod2=1[3].valor; *s2= 1 ;

break; case c-IXD: *cod1 =Ox1 4;

(26)
(27)

I

break; case c-IYD: *cod1 =Ox1 8;

*codl=add-rr2(codl,1[2].c-tok); *cod2=1[3].valor; *s2= 1 ;

break; case c-IXID:

if(busca-lab(l[3].nombre,&auxint))

/* si esta en la lista */ {

*cod1 =Ox1 4;

*codl=add-rr2(codl,1[2].c-tok);

*cod2=auxint; *s2= 1 ;

1

else

break;

myerror(nolines,2);

case c-IYID:

if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ {

*cod1 =Ox1 8;

*cod2=auxint; *s2= 1 ;

*codl=add~rr2(codl,1[2].c~tok);

1

else

break;

myerror(nolines,2);

} I* switch local */ } /* else */

if(l[2].c-tok==c-AL && (I[3].c-tok==c-APNN

1)

I[3].c_tok==c_lNTV

11

I[3].c-tok==c-OPR))

switch(l[3].c-tok){ } I* if3 *I

{

case c-OPR:

case c-APNN: *codl=Ox26; *cod2=1[3].valor & Oxff; *cod3=(1[3].valor >>8) & Oxff; *s2= 1 ;

*s3=1; break;

case c-INTV: *codl=Ox28; break;

1

if(I[3].c_tok==c_AL && (I[2].c-tok==c-APNN

11

1[2].c-tok==c-lNTV

11

1[2].c-tok==c-OPR))

switch(l[2].c-tok){ {

case c-OPR:

(28)

*cod3=(1[2].valor >>8) & Oxff; *s2= 1 ;

*s3= 1 ; break;

case c-INTV: *cod1 =Ox29; break;

I

I

if((1[2].c-tok==c-lXD

11

1[2].c_tok== c-IXID) && (1[3].c-tok==c-hex

11

I[3].c_tok==c_OPR)) {

*cod1 =Ox24;

*cod2=1[2].valor; if(l[2].c-tok==c-lXID) {

if(busca-lab(l[2].nombre,&auxint)) /* si esta en la lista */

{

1

*cod2=auxint;

else

myerror(nolines,2);

I

*cod3=1[3].valor; *s2=*s3=1;

1

if((1[2].c-tok==c-lYD

11

1[2].c_tok== c-IYID) && (1[3].c-tok==c-hex

11

I[3].c_tok==c_OPR))

*cod1 =Ox25; *cod2=1[2].valor; if(l[2].c-tok==c-lYlD) {

{

if(busca-lab(l[2].nombre,&auxint)) /* si esta en la lista */

*cod2=auxint;

I

else

myerror(nolines,2);

I

*cod3=1[3].valor; *s2=*s3=1;

1

if(1[2].c-tok==c-lY && 1[3].c-tok==c_lX) {

I

if(l[2].c_tok==c_SP && I[3].c_tok==c_lX) {

(29)

*cod1 =Ox2b;

1

if((l[2].c_tok==c_AX

11

1[2].c_tok==c_BX

11

1[2].c_tok==c_lX

11

I[2].c_tok==c_SP) && (1[3].c_tok==c_dhex

11

I[3].c_tok==c_OPR))

switch(l[2].c-tok){ {

case c_AX:*codl=Ox2c;break; case c_BX:*codl=Ox2d;break; case c_lX:*codl =Ox2e;break; case c_SP:*codl=Ox2f;break;

1

*cod2=1[3].valor & Oxff;

*cod3=(1[3].valor >>8) & Oxff;

*s2= 1 ;

*s3= 1 ;

1

if((1[2].c;_tok==c_AX

11

1[2].c_tok==c_BX

11

1[2].c_tok==c_lX

11

I[2].c_tok==c_SP) && (I[3].c_tok==c_APNN

11

I[3].c_tok==c_OPR))

switch(l[2].c-tok){ {

case c_AX:*codl=Ox30;break; case c_BX:*codl=Ox3l;break; case c-lX:*codl =Ox32;break; case c_SP:*codl=Ox33;break;

1

*cod2=1[3].valor & Oxff;

*cod3=(1[3].valor >>8) & Oxff; *s2= 1 ;

*s3= 1 ;

1

if((l[3].c_tok==c_AX

I/

I[3].c_tok==c_BX

11

1[3].c-tok==c-lX

11

I[3].c_tok==c_SP) && (I[2].c_tok==c_APNN

(1

1[2].c_tok==c_OPR))

switch(l[3].c-tok){ {

case c_AX:*codl=Ox34;break; case c-BX:*codl =Ox35;break; case c_IX:*codl=Ox36;break; case c_SP:*codl=Ox37;break;

1

*cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1 ;

*s3=1;

1

if((1[2].c_tok==c_lXD

11

I[2].c_tok==c_lYD

11

I[2].c_tok==c_IXIDII I[2].c-tok==c-lYID) && (I[3].c_tok==c_AL

11

I(3].c-tok==c-AH

11

1[3].c_tok==c_BL

(1

I[3].c_tok==c_BH))

(30)

case c-IXD: *cod1 =Ox1 c;

*codl=add-rr(cod1,1[3].c-tok);

*cod2=1[2].valor; *s2=1;

break;

case c-lXID:if(busca-lab(1[2].nombre,&auxint))

/* si esta en la lista */

{

*cod1 =Ox1 c;

*codl=add-rr2(codl,1[3].c-tok); *cod2=auxint;

*s2= 1 ;

1

else

break;

*cod1 =add-rr(codl,1[3].c-tok); *cod2=1[2].valor;

*s2= 1 ;

break;

case c-lYID:if(busca-lab(1[2].nombre,&auxint))

/*

si

esta en la lista */

{

myerror(nolines,2);

case c-IYD: *codl=Ox20;

*cod1 =Ox20;

*codl=add-rr2(codl,1[3].c-tok);

*cod2=auxint;

*s2= 1 ;

1

else

break;

} /* switch de ultimas opciones*/

myerror(nolines,2);

}break;

case c-ADW: switch(l[2].c-tok){

case c-AX: if(l[3].c-tok==c-BX)

*cod 1 =OxbO;

myerror(nolines,l); else

break;

case c-IX: switch(l[3].c-tok){

case c-AX: *codl=OxaO;break; case c-BX: *codl=Oxal ;break; case c-IY: *codl=Oxa2;break; case c-SP: *codl=Oxa3;break;

default: myerror(nolines,l);break;

1

break;

case c-IY: switch(l[3].c-tok){

(31)

1

break;

1

break;

case c-ACW: if((1[2].c-tok==c-AX) &&(1[3].c_tok==c_BX)) *cod1 =Oxbl ;

myerror(nolines,l); else

break:

case c-SCW: if((I[2].c_tok==c_AX) &&(l[3].c-tok==c-BX)) *cod1 =0xb2;

myerror(nolines,l); else

break;

case c-BIT:if( (1[2].c-tok==c-hex

11

1[2].c-tok==c-OPR)&& (1[2].valor>=O) && (1[2].valor<=7)) {

*cod2=1[2].valor; *s2= 1 ;

switch(l[3].c-tok){

case c-AL: *codl=OxcO;break; case c-AH: *codl=Oxcl ;break; case c-BL: *codl=Oxc2;break; case c-BH: *codl=Oxc3;break; case c-IXD: *cod1 =Oxc4;

*cod3=1[3].valor; *s3=1;

break;

*cod3=1[3].valor; *s3=1;

break;

case c-IYD: *cod1 =Oxc5;

case c-IXID:

if(busca-lab(l[3].nombre,&auxint))

/*

si

esta en la lista */ {

*cod1 =Oxc4; *cod3=auxint; *s3=1;

1

else

break;

myerror(nolines,2);

case c-IYID:

if(busca-lab(l[3].nombre,&auxint))

/*

si

esta en la lista */ {

*cod1 =Oxc5; *cod3=auxint; *s3= 1 ;

1

else

break;

(32)

1

else

break;

myerror(nolines,2);

case c-SET:if( (1[2].c-tok==c-hex

11

1[2].c-tok==c-OPR)&& (1[2].valor>=O) && (1[2].valor<=7))

{

*cod2=1[2].valor; *s2= 1 ;

switch(l[3].c-tok){

case c-AL: *codl=Oxc8;break; case c-AH: *codl=Oxc9;break; case c-BL: *codl=Oxca;break; case c-BH: *codl=Oxcb;break; case c-IXD: *cod1 =Oxc6;

*cod3=1[3].valor; *s3=1;

break;

*cod3=1[3].valor; *s3= 1 ;

break;

case c-IYD: *cod1 =Oxc7;

case c-IXID:

if(busca-lab(l[3].nombre,&auxint))

/* si esta en la lista */ {

*cod1 =Oxc6; *cod3=auxint; *s3=1;

1

else

break;

myerror(nolines,2);

case c-IYID:

if(busca-lab(l[3].nombre,&auxint))

/* si esta en la lista */ {

*cod 1 =Oxc7; *cod3=auxint; *s3= 1 ;

1

else

break;

myerror(nolines,2);

1

1

else

break;

myerror(nolines,2);

case c-RES:if( (1[2].c-tok==c-hex

11

1[2].c-tok==c-OPR)&& (1[2].valor>=O) && (1[2].valor<=7))

c

*cod2=1[2].valor; *s2= 1 ;

switch(l[3].c-tok){

(33)

case c-AH: *codl=Oxcd;break; case c-BL: *codl=Oxce;break; case c-BH: *codl=Oxcf;break;

case c-IXD: *cod1 =Oxel ;

*cod3=1(3).valor;

*s3= 1 ;

break;

*cod3=1[3].valor;

*s3= 1 ;

break;

case c-IYD: *codl=Oxe2;

case c-IXID:

if(busca-lab(l[3].nornbre,&auxint))

/*

si

esta en la lista */

{

*cod1 =Oxel ;

*cod3=auxint; *s3=1;

1

else

break;

myerror(nolines,2);

case c-IYID:

if(busca-lab(l[3].nombre,&auxint))

/* si esta en la lista */

{

*cod1 =0xe2; *cod3=auxint; "s3=1;

1

else

break; myerror(nolines,2);

1

1

else

break; myerror(nolines,2);

case c-JPC:switch(l[2].c-tok){

case c-NZ: *codl=OxdO;break;

case c-2: *cod 1 =Oxd 1 ;break;

case c-NC: *codl=Oxd2; break;

case c-C: *codl=Oxd3;break;

case c-S: *codl=Oxd4;break; case c-NS: *codl=Oxd5;break; case c-P: *codl=Oxd6;break; case c-NP: *codl=Oxd7;break;

default: myerror(nolines,2);break;

1

switch(l[3].c-tok){ case c-dhex:

case c-OPR: *cod2=1[3].valor & Oxff;

*cod3=(1[3].valor >>8) & Oxff;

*s2= 1 ;

*s3= 1 ;

(34)

I* status =2 -> no resuelto *I

case c-OPNR: *cod2=0; *s2=2;

*s3=2; break; *cod3=0;

default: myerror(nolines,2);break; }break;

case c-JRC:break;

... I /* codigo para instrucciones de un operando *I

... I

codigo-opu(struct line-node 1[4],int *cod1 ,int *cod2,int *cod3,int *sl ,int *s2,int *s3) {

int sigue=l ; int auxint=O;

*S1 =1; I* default: byte 1 valido,

los

demas no */ *s2=0;

*s3=0;

switch(l[l].c-tok){

case c-PUSH : *cod1 =Ox38; add-op(codl,1[2].c-tok); break; case c-POP : *codl=Ox3c; add_op(codl,I[2].c_tok); break; case c-ADD : *codl=Ox40;

switch(l[2].c-tok){ case c-OPR:

case c-hex:*codl =Ox44; *cod2=1[2].valor; *s2= 1 ;

sigue=O; break;

case c-lXD:*codl =Ox45; *cod2=1[2].valor; *s2= 1 ;

sigue=O; break;

case c_lYD:*codl=Ox46; *cod2=1[2].valor; *s2= 1 ;

sigue=O; break;

case c-lXID:if(busca-lab(1[2].nombre,&auxint)) /* si esta en la lista *I

{

*cod1 =Ox45; *cod2=auxint; *s2= 1 ; sigue=O;

1

else

break:

(35)

case c~lYID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */

{

*cod1 =Ox46; *cod2=auxint; *s2= 1 ; sigue=O;

1

else

break;

myerror(nolines,2):

1

if(sigue)

break;

add-rr(cod1,1[2].c-tok);

case c-ADC : *codl=0x48;add~rr(cod1,1[2].c~tok); break; case c-SUB : *cod1=0x4c;add~rr(cod1,1[2].c~tok); break; case c-SBC : *cod1

=0x50;add~rr(codl,1[2].c~tok);

break; case c-AND : *codl=Ox54;add_rr(codl ,1[2].c_tok); break; case c-OR : *codl=0x58;add~rr(codl,1[2].c~tok); break; case c-XOR : *codl=Ox5c;add-rr(codl ,I[2].c-tok); break; case c-INC : *codl=Ox60;

switch(l[2].c-tok){

case c-AX: *cod?=Oxa8;sigue=O;break; case c-BX: *cod1 =Oxa9;sigue=O;break; case c-IX:

*codl=Oxaa:sigue=O;break;

case c-IY:

*codl=Oxab;sigue=O;break;

case c-lXD:*codl =Ox47; *cod2=1[2].valor; *s2= 1 ;

sigue=O; break;

case c_lYD:*codl=Ox68; *cod2=1[2].valor;

*s2=

1 ;

sigue=O; break;

case c-lXID:if(busca-lab(1[2].nombre,&auxint)) /*

si

esta en la lista */

{

*cod1 =Ox47; *cod2=auxint;

*s2= 1 ;

sigue=O;

1

else

break:

case c~lYID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */

myerror(nolines,2);

{

*cod1 =Ox68; *cod2=auxint; *s2= 1 ; sigue=O;

(36)

case c-lYID:if(busca-lab(1[2].nombre,&auxint))

*cod1 =Ox46; *cod2=auxint;

*s2= 1 ;

sigue=O;

1

else

myerror(nolines,2);

if(sigue)

break; add-rr(cod1,1[2].c-tok);

case c-ADC :

*codl=0x48;add~rr(codl,1[2].c~tok);

break;

case c-SUB :

*codl=0x4c;add~rr(codl,1[2].c~tok);

break;

case c-SBC : *codl=0x50;add~rr(codl,1[2].c~tok); break;

case c-AND :

*codl=0x54;add~rr(codl,1[2].c~tok);

break;

case c-OR : *cod1 =Ox58;add_rr(codl ,1[2].c_tok); break;

case c-XOR : *codl=Ox5c;~dd-rr(codl ,I[2].c-tok); break;

case c-INC : *cod1 =Ox60;

switch(l[2].c-tok){

case c-AX: *cod1 =Oxa8;sigue=O;break; case c-BX: *cod1 =Oxa9;sigue=O;break; case c-IX: *codl=Oxaa;sigue=O;break; case c-IY: *codl=Oxab;sigue=O;break; case c-lXD:*codl =Ox47;

*cod2=1[2].valor;

*s2= 1 ;

sigue=O; break;

case c-lYD:*codl =Ox68; *cod2=1[2].valor;

*s2= 1 ;

sigue=O; break;

case c~lXID:if(busca~lab(1[2].nombre,&auxint))

/* si esta en la lista */

c

*cod1 =Ox47; *cod2=auxint; *s2=1; sigue=O;

1

else

break;

case c~lYID:if(busca~lab(1[2].nombre,&auxint))

/* si esta en la lista */

{

myerror(nolines,2);

*cod 1 ~ 0 x 6 8 ; *cod2=auxint;

*s2= 1 ;

sigue=O;

(37)

else

break;

myerror(nolines,2);

1

if(sigue)

break:

add-rr(cod1,1[2].c-tok);

case c-DEC : *cod1 ~ 0 x 6 4 ;

switch(l[2].c-tok){

case c-AX: *cod1 =Oxac;sigue=O;break; case c-BX: *cod1 =Oxad;sigue=O;break; case c-IX: *cod1 =Oxae;sigue=O;break; case c-IY: *cod1 =Oxaf;sigue=O;break; case c-lXD:*codl =Ox69;

*cod2=1[2].valor;

*s2= 1 ;

sigue=O; break;

case c-lYD:*codl =Ox6a; *cod2=1[2].valor;

*s2= 1 ;

sigue=O; break;

case c-lXID:if(busca-lab(l[2].nombre,&auxint))

/* si esta en la lista */

{

*cod1 =Ox69; *cod2=auxint;

*s2= 1 ;

sigue=O;

1

else

break;

case c~lYID:if(busca~lab(1[2].nombre,&auxint))

/* si esta en la lista */

myerror(nolines,2);

{

*cod1 =Ox6a; *cod2=auxint;

*s2= 1 ;

sigue=O;

1

else

break;

myerror(nolines,2);

1

if(sigue)

break: add-rr(cod1,1[2].c-tok);

case c-RLC : *cod1 =0x80;add~rr(codl,1[2].c~tok); break;

case c-RL : *cod1 =Ox84;add-rr(codl,1[2].c-tok); break;

case c-RR : *codl=0x88;add~rr(codl,1[2].c~tok); break;

case c-RRC : *codl=0x8c;add~rr(codl,l[2].c~tok); break;

(38)

case c-SR : *codl=0x94;add~rr(codl,1[2].c~tok); break; case c-JP : *codl=Oxe3;

switch(l[2].c-tok){ case c-dhex:

case c-OPR: *cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1 ;

*s3= 1 ; break;

/* status =2 -> no resuelto */ case c-OPNR: *cod2=0;

*s2=2; *cod3=0; *s3=2; break;

case c-IXP: *codl=Oxe5;break; case c-IYP: *codl=Oxe6;break;

1

break; case c-JR :

case c-DJNZ: *cod1 =0xe7; switch(l[2].c-tok){

case c-OPR: *cod2=1[2].valor & Oxff;

*cod3=(1[2].valor >>8) & Oxff; *s2= 1 ;

*s3=1; break;

/* status =2 -> no resuelto *I

case c-OPNR: *cod2=0; *s2=2; *cod3=0; *s3=2; break;

1

break;

case c-CALL: *cod1 =0xe8; switch(l[2].c-tok){ case c-dhex:

case c-OPR: *cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1 ;

*s3=1; break;

/* status =2 -> no resuelto */ case c-OPNR: *cod2=0;

*s2=2; *cod3=0; *s3=2; break;

default: myerror(nolines,l); break; }break;

1

1

(39)

gen-cod(struct line-node 1[4],int 'bytes) {

int i;

int bcl=O,bc2=O,bc3=0; /* bytes de codigo */

int s l =O,s2=O,s3=0; /* status de los bytes de codigo */ int valid=O;

*bytes = 1; /* default: un byte de codigo */ if(l[l].c-tok && 1[2].c_tok && I[3].c_tok) {

codigo-opb(l,&bcl ,&bc2,&bc3,&sl ,&s2,&s3); add-code(bc1 ,bc2,bc3,sl ,s2,s3,nolines,pc); if(s1 && S2 && s3)

*bytes=3; else

if(s1 && s2) *bytes=2;

1

else {

if(l[l].c-tok && I[2].c-tok ) {

codigo-opu(l,&bcl ,&bc2,&bc3,&sl ,&s2,&s3); add-code(bc1 ,bc2,bc3,sl ,s2,~3,nolines,pc); if(s1 && S2 && s3)

*bytes=3; else

if(s1 && s2) *bytes=2;

1

{ else

if(l[l].c-tok ) {

codigo-op(l,&bcl);

add-code(bcl,O,O,l ,O,O,nolines,pc);

1

1

1

1

... / /* genera un nuevo nodo para la lista de etiquetas */

struct lab-node *new-lab-nodeO {

struct lab-node *aux;

aux=(struct lab-node *)rnalloc(sizeof(struct lab-node)); aux->next=NULL;

aux->prev=NULL; return(aux);

1

(40)

{

struct op-node *aux;

aux=(struct op-node *)malloc(sizeof(struct op-node)); aux->next-op=NULL;

aux->prev-op=NULL; aux->next-ref=NULL;

1

I* genera un nuevo nodo para la lista de referencias *I

struct ref-node *new-ref-nodeO {

struct ref-node *aux;

aux=(struct ref-ptr *)malloc(sizeof(struct ref-node)); aux->next=NULL;

1

... I

I* agrega un nuevo nodo a la lista de etiquetas *I

agrega-lab(char name[lO],int valor) {

struct lab-node *aux-lab1 ,*aux_lab2;

if(1ab-head==NULL) I* si la lista esta vacia *I {

lab-head=new-lab-nodeO; strcpy(lab-head->name,name); lab-head->value=valor;

else I* ya hay algo *I

aux-labl=lab-head;

while ( aux-lab2=aux-labl->next )

aux-lab2=new-lab-nodeO; strcpy(au~-lab2->name,name); aux-lab2->value=valor;

aux-lab2->prev=aux-labl; aux-labl->next=aux-lab2;

1

{

aux-labl=aux-lab2 ; I* aux-lab1 is the last node*/

1

1

I* realiza una busqueda sobre la lista de etiquetas *I

int busca-lab(char name[l O],int *valor) {

struct lab-node *auxl ; auxl =lab-head;

while( (strcmp(aux1->name,name)!=O)&& auxl )

if(strcmp(aux1->name,name)==O) auxl =auxl ->next;

{

*valor=auxl->value; return(1);

1

else

(41)

/* realiza una busqueda sobre la lista de operandos *I

struct op-node *busca-op(char name[l O])

{

struct op-node *auxl ;

auxl =op-head;

while( (strcmp(aux1->name,name)!=O)&& auxl )

auxl =auxl ->next-op;

if(strcmp(aux1->name,name)==O)

{

1

{

return(aux1);

else

auxl =NULL; return(aux1);

1

1

/* agrega un nuevo nodo a la lista de referencias *I

agrega-ref(struct op-node *op,int re9

struct ref-node 'auxl ,*aux2; auxl =op->next-ref;

while ( aux2=auxl->next )

aux2=new-ref-nodeO; aux2->ref=ref; auxl->next=aux2:

auxl=aux2 ; I* auxl is the last node*/

/* agrega un nuevo nodo a la lista de operandos *I

agrega-op(char name[lO],int re9

{

int sigue=l ;

struct op-node *auxl ,*aux2;

if(op-head==NULL) /* si la lista esta vacia */

op-head=new-op-nodeO; strcpy(op-head->name,name);

op-head->next-ref=new-ref-nodeO;

op-head->next-ref->ref=ref;

/* ya hay algo */

auxl =busca-op(name);

if(aux1) /* si ya esta en la lista op*/

agrega-ref(aux1 ,ref);

else /* lista no vacia, pero no esta op */

{

auxl =op-head;

while ( aux2=auxl-~next~op )

aux2=new-op-nodeO; strcpy(aux2->name,name); aux2->next-ref=new-ref_nodeO;

(42)

/* busca una linea de codigo a partir del numero de linea */ struct code-line *busca-cl(int numero)

{

struct code-line *aux; aux=first-line; while(aux) {

if(aux->num==numero) return(aux);

aux=aux->next;

1

return(aux);

1

/* modifica una linea de codigo ya generada *I

mod-codigo(int code-line,int new-value) {

struct code-line *aux; aux=busca-cl(code-line);

if(aux) /* si existe ese numero de linea */ {

if(aux->status2==2 ) {

aux->byte2=new-value 8, Oxff; aux->byte3=(new-value>>8) 8, Oxff; aux->st~4us2=1;

aux->status3=1;

else

myerror(nolines,2);

1

/* resuelve el valor de una referencia */ resolve-ref(char name[lO],int valor) {

struct op-node *auxop; struct ref-node *auxref; auxop=busca-op(name); if (auxop==NULL)

return(1);

/*myerror(nolines,2);*/ auxref=auxop->next-ref; while(auxref)

{

(43)

1

... I

I* manejo de la lista de operandos *I

op-mngr(char name-op[l O],int ref,int *valor,int *status) {

if(busca-lab(name-op,valor)) /* si esta op, regresa valor *I

else I* si no, agregalo a la lista de op *I

*status=l ;

{

agrega-op(name-op,ref); *status=O;

1

1

I* manejo de la lista de etiquetas *I

lab-mngr(char name-lab[lO],int valor,int *status)

{

if(busca-lab(name-lab,valor)) I*

si

esta, genera error *I

else

*status=O;

{

agrega-lab(name-lab,valor); resolve-ref(name-lab,valor); *status=l ;

1

1

/* imprime etiquetas y sus valores en arch *I

void print-lab(FILE *arch) {

struct lab-node *aux; aux=lab-head;

fprintf(arch," NOMBRE\t\tVALOR\n"); while(aux)

{

fprintf(arch," %s\t\to/~04x\n",aux-~name,aux-~value); aux=aux->next;

1

}

I* manejo de errores de yacc *I

yyerror(char *cad ) {

printf("ERR0R

. %S

on line %d\n",cad,noiines); return(1);

1

(44)

/* archivo myasm.c : ensamblador, espera recibir los nombres de los archivos de entrada (ensamblador) y de salida(codigo objeto), genera un tercer archivo.sym con la lista de simbolos resueltos. Llama a yyparseo y yylexo */

#include <stdio.h> #include <dos.h> #include "yout.c" #include "cod1ex.c" #include "1out.c"

... /* lista de funciones */

YyparseO; /* llamada al analizador sintactico */ print-lab(fsym); /* se imprime la lista de simbolos */ gen-lst(namei,nameo); /* se imprime la lista de codigo *I

...

gen-lst(char filename[40],char oname[40]) {

FILE *filei,*fileo; char cadena[80]; int

¡=O;

struct code-line *aux; aux=first-line;

if((filei=fopen(filename,"r"))==NULL) /* se abre el archivo de entrada*/ {

1

{ . .

else

printf("Error al abrir el archivo %s\n",filename);

/* se abre el archivo de salida */ if((fileo=fopen(oname,"w"))==NULL) {

1

else {

printf("Error al abrir el archivo %s\n",oname);

while(*fgets(cadena,80,filei)!=NULL) {

fprintf(fileo,"%03d. 'I,¡); /* imprime num de linea */ if(aux-mum==¡ && aux)

{

/* imprime el contador del programa */ fprintf(fileo,"%04x: ",aux->pcounter); /* imprime los bytes de codigo */

if(aux-xtatusl) fprintf(fileo,"%02x ",aux->bytel); if(aux->status2) fprintf(fiIeo,"%02x ",aux->byte2); if(aux->status3) fprintf(fiIeo,"%02x ",aux->byte3); aux=aux->next;

1

(45)

i++;

1

fclose(fi1ei); fclose(fi1eo);

1

1

1

void main(int argc,char *argv[]) {

FILE *fi,*fo,*fsym; int i;

char *charp,*charp2; char namei[l4]; char nameo[l4]; char namesym[l4];

if(argc==l) /* error, no se dio argumento */ {

printf("MYASM : Error, no se ha dado nombre de archivo."); exit(1);

1

{

if(argc==2) /*solo se dio el nombre del archivo de entrada*/

strcpy(namei,argv[l]); strcpy(nameo,namei);

/* se genera el nombre del archivo de codigo */ charp=strchr(nameo,'.');

charp++; *charp='\O'; strcat(nameo,"lst");

/* se genera el nombre del archivo de simbolos resueltos */ strcpy(nan;esym,namei);

charp=strchr(namesym,'.'); charp++;

*charp='\O';

strcat(namesym,"sym");

1

{

if(argc>=3) /* se dieron nombres de archivos de entrada y salida */

strcpy(namei,argv[l]); strcpy(nameo,argv[2]); strcpy(namesym,namei);

charp=strchr(namesym,'.'); charp++;

*charp='\O';

strcat(namesym,"sym");

/* se genera el nombre del archivo de simbolos resueltos */

1

{

if((fi=fopen(namei,"r"))!=NULL)

if((fo=fopen(nameo,"w"))!=NULL) {

(46)

printf("Archivos abiertos exitosamente.\n"); fclose(f0);

yyin=fi;

fclose(yyin);

print-lab(fsym); /* se imprime la lista de simbolos */ yyparse0; /* llamada al analizador sintactico */

fclose(fsym);

gen-lst(namei,nameo); /* se imprime la lista de codigo */

1

else

fclose(fo);

printf("Error al abrir %s.",namesym);

1

else

fclose(fi);

printf("Error al abrir %s.",nameo);

1

else

(47)

/* archivo miosimf.c : simulador del microprocesador *I

...

lista de funciones:

asigna(int codigo,int to,int d-to,int v-to,

int next0 I* obtiene el siguiente byte del codigo *I

int next-w0 I* obtiene el siguiente word del codigo *I

decodif(int instr, struct op *outp) dec-carga(int instr,struct op *Sal) dec-arit(int instr,struct op *Sal) dec-rot(int instr,struct op *sal) dec-call(int instr,struct op *sal) gen-flags(int *banderas) regen-flags(int banderas) zflag(int valor)

ejec(struct op oper) int cap-num(n,x,y)

struct image-node *new-image-nodeO

agrega-image(char text[80],int valori,int valorpc) struct image-node *busca-image(int newpc)

int firstpco I* busca en la lista-imagen del archivo . k t el primer PC *I

revisa2p(char *auxp)

fimage(char filename[40]) I* genera la lista-imagen del archivo filename */ /* muestra 64 bytes de la memoria a partir de la direccion *orig

print-mem(int *orig)

show-reg0 I* muestra el status de los registros en la ventana activada */ show-reg20

altera-reg0 /* altera los valores de los registros *I

int chextoint(char *cp) int conv-hex(char *cp)

int conv-dec(char *charp,int tamano)

separa(char cadena[80],int *newline, int *newpc, int *bytel, int *byte2, int *byte3,int *status) altera-memo I* altera

los

valores de la memoria *I

menu-memo mem2(int *dir)

menu") /* perrrde generar una interrupcion si estan habilitadas *I I* le pide al usuario el nombre de un archivo . k t y revisa qque exista *I

print-arch(char filename[30],int *filestat)

I* menu inicial del simulador, mientras error y no-ESC => sigue */ print-ini(char name[40],int *fileerr)

print-image0

I* imprime un renglon de la lista-imagen del archivo en la ventana print-reng(struct image-node *aux)

print-opt0 /* opciones del simulador *I

void gen-symbols(char namei[l4])

int from,int d-fromjnt v-from,struct op *salida)

en la ventana que este activa *I

activada *I

Fin de la lista de funciones.

I . . .

I

(48)

#include <conio.h> #include "p0pup.h" #include "mouse.h" #include <alloc.h> #include <stdio.h> #include <ctype.h>

I* definiciones de entidades direccionables *I

#define AL

O

#define AH 1 #define BL 2 #define BH 3 #define IY

5

#define AX 20 #define BX 21 #define IX 22 #define SP 23 #define FLAGS 24 #define IXD 10 #define IYD 11 #define AP1-NN 12 #define AP2-NN

15

#define N 13

#define W 14 I* word *I

#define INTV 8 #define M 9

I* definiciones de codigos de operaciones *I

#define LD 1

#define PUSH 2 #define POP 3 #define ADD 4 #define ADC 5 #define SUB 6

#define SBC 7 #define AND 8

#define OR 9

#define XOR 1 O #define INC 11

#define DEC 12

#define DAA 13

#define CPL 14

#define NEG 15

#define CCF 16

#define SCF 17

#define HALT 18

#define DI 19

#define El 20

#define RLC 21

#define RL 22 #define RR 23 #define RRC 24

#define SL 25

(49)

#define BIT #define SET #define RES #define JP #define JR #define DJNZ #define CALL #define RET #define RETI #define JPC #define JRC #define ADW #define ACW #define SCW

27 28 29 3c 31 32 33 34 35 36 37 38 39 40

/* definiciones de condiciones de salto */

#define N 2

O

#define 2 1

#define NC 2

#define C 3

#define S 4

#define NS 5

#define P 6

#define NP 7

#define MAXMEM Ox100

... /

typedef struct op{ /* operacion por realizar */

int codigo;

int destino;

int desp-destino; /* desp destino */

int v-destino; /* valor destino */

int fuente;

int desp-fuente; /* desplazamiento origen*/

int v-fuente; /* valor origen */

1;

union acc{

int axbx[2]; /* O) AX , 1) BX */

char ab11[4]; /* O AL, 1 AH, 2 BL, 3 BH */ }accs;

/* informacion sobre un renglon de un archivo .Ist */ struct ¡magemnode{

int lineno; /* # de renglon dentro del archivo */ int linepc; /* PC de la instruccion por ejecutar */

char info[80]; /* cadena con [etiqueta] instruccion */ struct image-node *next;

1;

(50)

*I

int CF=O,SF=O,ZF=O,IFF=O,PF=O; /* FLAGS *I

int reg[4]={0,0,0,0}; /*registros: IX, IY, SP, IP */

char reg-intv; /*registros: FLAGS, INTV */

int reg-flags=O;

int intflag=O; /* bandera de interrupciones */

int no-halt=l; /* bandera de halt */

int mem[MAXMEM]; /* arreglo de memoria *I

int pcglob=O; /* PC del simulador *I

struct image-node *image-head=NULL;

...

modulo de decodificacion de instrucciones

* * *

. . .

asigna(int codigo,int to,int d-to,int v-to,

int from,int d-from,int v-from,struct op *salida)

{

salida-xodigo = codigo;

salida->fuente = from;

salida->desp-fuente = d-from;

salida->v-fuente = v-from;

salida->destino = to;

salida->desp-destino = d-to;

salida->v-destino = v-to;

}

... /

int next0 /* obtiene el siguiente byte del codigo */

{

1

return(mem[pcglob++]);

int next-w0 /* obtiene el siguiente word del codigo */

int intaux,intaux2; int auxl ,aux2; auxl =next(); aux2=nextO;

intaux=aux2; /* high */

intaux=intauxcc$;

auxl= auxl & OxOOff; /* low */

intaux=intauxlauxl; return(intaux);

... ,I

decodif(int instr, struct op *outp)

{

(51)

case O: dec-carga(instr,outp); break; case 1 : dec-arit(instr,outp); break; case Oxfffe: dec-rot(instr,outp); break; case Oxffff: dec-call(instr,outp); break;

1

1

...

/ dec-carga(int instr,struct op *sal)

{

int maskl=0x0006,mask2=0x0003; int auxl ,aux2,auxint;

if (instr>=OxO && instrc=OxF) /* LD r,r' */ {

auxl = (instr&maskl)>>2 ; aux2 = instr&mask2;

asigna(LD,auxl ,O,O,aux2,0,0,sal);

if (instr>=Oxl O && instr<=Ox13) /* LD r,n *I

1

{

auxl = next(); aux2 = instr&mask2;

asigna(LD,aux2,0,0,N,O,auxl ,sal);

1

{

if (instr>=Oxl4 && instrc=Oxl7) /* LD r,(lX+d) */

auxl = next(); aux2 = insrr&mask2;

asigna(LD,aux2,0,0,IXD,auxl ,O,sal);

1

{

if (instr>=Oxl8 && instrc=Oxl b) /* LD r,(lY+d) */

auxl = next(); aux2 = instr&mask2;

asigna(LD,aux2,0,0,IYD,auxl ,O,sal);

1

{

if (instr>=Oxlc && instrc=Oxlf) /* LD (IX+d),r */ auxl = next();

aux2 = instr&mask2;

asigna(LD,IXD,auxl ,O,aux2,0,0,sal);

1

{

if (instr>=Ox20 && instrc=Ox23) /* LD (IY+d),r */ auxl = next();

aux2 = instr&mask2;

asigna(LD,IYD,auxl ,O,aux2,0,0,sal);

1

switch(instr){

case 0x24: auxl = nexto; /* LD (IX+d),n */ aux2 = next();

asigna(LD,IXD,auxl ,O,N,O,aux2,sal); break;

case 0x25: auxl = nexto; /* LD (IY+d),n */ aux2 = next();

(52)

case 0x26: aux2 = next-w0; /* LD AL,(nn) */ asigna(LD,AL,O,O,AP1~NN,aux2,0,sal); break;

asigna(LD,APl-NN,auxl ,O,AL,O,O,sal); break;

break;

case 0x27: auxl = next-w0; /* LD (nn),AL */

case 0x28: asigna(LD,AL,O,O,INTV,O,O,sal); /* LD AL,INTV */

case 0x29: asigna(LD,INTV,O,O,AL,O,O,sal); /* LD INT'V,AL */

1

if (instr>=Ox2c && instr<=Ox2f) /* LD dd,nn */ {

aux2 = next-w0; /* dd= AX,BX,IX,SP */

auxl = instr&mask2; auxl =auxl+20;

asigna(LD,auxl ,O,O,W,O,aux2,sal);

1

if (instr>=Ox30 && instr<=Ox33) I* LD dd,(nn) */ {

aux2 = next-w0; auxl = instr&mask2; auxl =auxl+20;

asigna(LD,auxl ,O,O,AP2-NN,aux2,0,sal);

1

if (instr>=Ox34 && instr<=Ox37) /* LD (nn),dd */ {

auxl = next-w0;

aux2 = instr&mask2 + 20;

asigna(LD,AP2-NN,auxl ,O,aux2,0,0,sal);

1

switch(instr){

case Ox2a: asigna(LD,IY,O,O,IX,O,O,sal); /* LD IY,IX

case Ox2b: asigna(LD,SP,O,O,IX,O,O,sal); /* LD SP,IX */ break;

break;

1

{ /* qq=AX,BX,IX,FLAGS

*I

if (instr>=Ox38 && instrc=Ox3b) /* PUSH qq */

auxl = (instr&mask2) + 20;

if (auxl==23) auxl++; /* as¡ auxl es FLAGS */ asigna(PUSH,O,O,O,auxl ,O,O,sal);

1

{

if (instr>=Ox3c && instr<=Ox3f) I* POP qq *I

auxl

= (instr&mask2)

+

20;

if (auxl==23) auxl++; /* asi auxl.es FLAGS */ asigna(POP,auxl ,O,O,O,O,O,sal);

1

1

...

I'

dec-arit(int instr,struct op *sal) {

(53)

int auxl ,aux2;

if (instr>=Ox40 && instr<=Ox43) /*ADD r */

{

aux2 = instr&mask2;

asigna(ADD,AL,O,O,aux2,O,O,sal);

1

{

if (instr>=Ox48 && instr<=Ox4b) /* ADC r */

aux2 = instr&mask2;

asigna(ADC,AL,O,O,aux2,O,O,sal);

1

if (instr>=Ox4c && instr<=Ox4f) /*SUB r */

{

aux2 = insfr&mask2;

asigna(SUB,AL,O,O,auxZ,O,O,sal);

1

if (instr>=Ox50 && instr<=Ox53) /* SBC r */

{

aux2 = instr&mask2;

asigna(SBC,AL,O,O,aux2,O,O,sal);

1

if (instr>=Ox54 && instr<=Ox57) /*AND r */

{

aux2 = instr&mask2;

asigna(AND,AL,O,O,auxZ,O,O,sal);

1

{

if (instr>=Ox58 && instr<=Ox5b) /* OR r */

aux2 = instr&mask2;

asigna(OR,AL,O,O,aux2,O,O,sal);

1

{

if (instr>=Ox5c && instr<=Ox5f) /* XOR r */

aux2 = instr&mask2;

asigna(XOR,AL,O,O,aux2,O,O,sal);

1

{

if (instr>=Ox60 && instr<=Ox63) /* INC r */

aux2 = instr&mask2;

asigna(lNC,aux2,0,0,aux2,O,O,sal);

1

{

if (instr>=Ox64 && instr<=Ox67) /* DEC r */

aux2 = instr&mask2;

asigna(DEC,aux2,0,0,aux2,O,O,sal);

1

switch(instr){

case 0x44: auxl = next(); /*ADD n */

asigna(ADD,AL,O,O,N,O,auxl ,sal);

break;

dsigna(ADD,AL,O,O,IXD,aux2,0,sal);

break;

asigna(ADD,AL,O,O,IYD,aux2,0,sal);

case 0x45: aux2 = next(); I* ADD (IX+d) */

Referencias

Documento similar

Las páginas nicho no son más que una página web sobre un tema muy específico, mediante la que puedes generar ingresos pasivos gracias al marketing de afiliados?. No necesitas ser

Asimismo una reflexión calmada sobre las intrincadas relaciones existentes en el péndulo que va del ODM 1 al ODM 8, debería conducirnos a observar por qué las formas mediante las

Primeros ecos de la Revolución griega en España: Alberto Lista y el filohelenismo liberal conservador español 369 Dimitris Miguel Morfakidis Motos.. Palabras de clausura

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

[r]

La &#34;Fuente Correspondiente&#34; de un trabajo en código objeto se refiere a todo código fuente necesario para generar, instalar, y (en el caso de trabajos ejecutables)

o esperar la resolución expresa&#34; (artículo 94 de la Ley de procedimiento administrativo). Luego si opta por esperar la resolución expresa, todo queda supeditado a que se

¿Qué hace falta para ser un héroe clásico en..