UNIVERSIDAD AUTONOMA METROPOLITANA UNIDAD IZTAPALAPA
DOCUMENTACION DEL PROYECTO TERMINAL I1
"ENSAMBLADOR Y SIMULADOR DE UN MICROPROCESADOR"
ALUMNO: SERGUEI MENDOZA SOYLOVICH ASESOR: FRANCISCO OLVERA
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
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 ).
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 YACC1.4. myasm.c
-
programa principal del ensamblador 1.5. y0ut.c-
salida generada por YACC1.6.lout.c
-
salida generada por LEX2) 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 mouseAPENDICE B
1)
PASOS A SEGUIR PARA GENERAR EL ENSAMBLADORPara 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 linea1370
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 C2.2.
Cargar el project mysim.prj2.3.
Ejecutar la opcien de compilacitnAPENDICE 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
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
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
8. GRUPO DE JUMP, CALL Y RETURN 1. JP NN
2. JPC CC,NN 3. JR EE 4. JRC CC,EE
5. JP (IX)
/* 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);
" 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
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
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
#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
/* 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];
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-DECLEQUS : EQU
I
EQUS EQUEQU : ID
c-EQU c-hex {
eti.value=tokvall;
lab-mngr(eti.name,eti.value,&seguir); if(seguir==O)
myerror(nolines,l);
1
I
IDc-EQU c-d hex {
eti.value=tokvall ;
lab-mngr(eti.name,eti.value,&seguir); if(seguir==O)
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-DBI
ETlQc-hex
c-DEFS c-hex
c-hex
I
c-DEFSINSTS : INST
I
INSTS INSTINST : OPERACION
{
ini(linea);
pc+=bytes;
1
I
ETlQC 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
ETlQOPERACIONU {
ini(1inea); L 2 P
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
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
{
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-NEGI
c-CCF1
c-SCF1
c-DI1
c-IEII
c-HALTI
c-RETI
c-RETIOPERACIONU : c-PUSH
I
c-POPI
c-ADDI
c-ADCI
c,SUBI
c-SBC1
c-ANDI
c-ORI
c-XORI
c-INC1
c-DEC1
c-RLC1
c-RLI
c-RROPERACIONB : c-LD
I
c-ADWI
c-ACWI
c-SCWI
c--BITI
c-SETI
c-RESI
c-JPCI
c-JRCc-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 */ {
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
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;
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_AH11
l[2].c_tok==c_BL11
l[2].c_tok==c_BH) && (l[3].c_tok==c_AL11
I[3].c-tok==c-AH/I
1[3].c_tok==c_BL
11
1[3].c_tok==c_BH11
l[3].c_tok==c_lXD11
I[3].c-tok==c-lYD11
I[3].c-tok==c_lXIDII I[3].c-tok==c-lYID11
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-AHI(
1[3].c-tok==c-BL1)
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;
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
elsebreak;
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
elsebreak;
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_lNTV11
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-lNTV11
1[2].c-tok==c-OPR))switch(l[2].c-tok){ {
case c-OPR:
*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-hex11
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-hex11
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) {
*cod1 =Ox2b;
1
if((l[2].c_tok==c_AX
11
1[2].c_tok==c_BX11
1[2].c_tok==c_lX11
I[2].c_tok==c_SP) && (1[3].c_tok==c_dhex11
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_BX11
1[2].c_tok==c_lX
11
I[2].c_tok==c_SP) && (I[3].c_tok==c_APNN11
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_BX11
1[3].c-tok==c-lX11
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_lYD11
I[2].c_tok==c_IXIDII I[2].c-tok==c-lYID) && (I[3].c_tok==c_AL11
I(3].c-tok==c-AH11
1[3].c_tok==c_BL
(1
I[3].c_tok==c_BH))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){
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;
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){
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 ;
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:
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;
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;
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;
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
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
{
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
/* 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;
/* 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)
{
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 *Ielse
*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
/* 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
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) {
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
elsefclose(fi);
printf("Error al abrir %s.",nameo);
1
else
/* 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 *Imenu-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
#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
#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;
*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)
{
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();
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) {
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) */