Annotation of ADD_ver_10/AnalizadorOperandos16bits.c, revision 1.3

1.1       rico        1: /********************************************************************/
                      2: /*  AnalizadorOperandos16bits.c                                     */
                      3: /*                                                                  */
                      4: /*  Copyright (c) 1997-2006 Rafael Rico      (rafael.rico@uah.es)   */
                      5: /*                                                                  */
                      6: /*  This file is part of ADD version 5.10.                          */
                      7: /*                                                                  */
                      8: /*  ADD is free software; you can redistribute it and/or modify     */
                      9: /*  it under the terms of the GNU General Public License as         */
                     10: /*  published by the Free Software Foundation; either version 2 of  */
                     11: /*  the License, or (at your option) any later version.             */
                     12: /*                                                                  */
                     13: /*  ADD is distributed in the hope that it will be useful,          */
                     14: /*  but WITHOUT ANY WARRANTY; without even the implied warranty of  */
                     15: /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   */
                     16: /*  GNU General Public License for more details.                    */
                     17: /*                                                                  */
                     18: /*  You should have received a copy of the GNU General Public       */
                     19: /*  License along with ADD; if not, write to the Free Software      */
                     20: /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA        */
                     21: /*  02111-1307  USA                                                 */
                     22: /*                                                                  */
                     23: /*  --------------------------- History --------------------------- */
                     24: /*                                                                  */
                     25: /*  Revision 1.2. 01/2006                                           */
                     26: /*  Added GPL License and JavaDoc style documentation               */
                     27: /*                                                                  */
                     28: /*  Revision 1.1. 09/2005                                           */
                     29: /*  Initial Revision                                                */
                     30: /*                                                                  */
                     31: /********************************************************************/
                     32: 
                     33: /******************************************************************************/
1.3     ! rico       34: /* MÓDULO: AnalizadorOperandos16bits.c                                        */
        !            35: /*                                                                            */
        !            36: /* Este módulo analiza el uso de los operandos y construye una ficha de la    */
        !            37: /* instrucción clasificando los operandos por su uso.                         */
        !            38: /* También calcula el número total de ciclos.                                 */
1.1       rico       39: /******************************************************************************/
1.3     ! rico       40: /* Fecha: 13 de junio de 2005                                                 */
1.1       rico       41: /******************************************************************************/
                     42: 
                     43: #include <stdio.h>
                     44: #include <stdlib.h>
                     45: #include <string.h>
                     46: #include <ctype.h>
                     47: 
                     48: #include "defines.h"
                     49: #include "tipos.h"
                     50: #include "analizadoroperandos16bits.h"
                     51: 
                     52: /* bases de datos */
                     53: extern unsigned int num_nemonicos;
                     54: extern operacion *nemonicos;
                     55: extern unsigned int num_simbolos;
                     56: extern operando *simbolos;
                     57: 
                     58: 
                     59: 
1.3     ! rico       60: /* esta función convierte una cadena de operandos a una cadena normalizada */
        !            61: /* de posibles ubicaciones (sin desplazamientos ni valores inmediatos) */
1.1       rico       62: 
                     63: void NormalizarUbicacion(char *cadena)
                     64: {
                     65:     switch(cadena[0])
                     66:     {
                     67:         case '\0':    /* sin operando; aquí se supone que no debería entrar */
                     68:         break;
                     69: 
                     70:         case '[':    /* operando memoria */
                     71:         if(isxdigit(cadena[2])) strcpy(cadena, "[XXXX]");    /* es un desplazamiento absoluto */
                     72:         else
                     73:         {
1.3     ! rico       74:             if(cadena[3]==']') cadena[4]='\0';    /* termino la cadena justo después aunque */
        !            75:             else cadena[6]='\0';                /* pueda haber desplazamiento adicional */
1.1       rico       76:         }
1.3     ! rico       77:         break;
1.1       rico       78: 
                     79:         default:    /* registros o valores (inmediatos o direcciones físicas) */
                     80:         if(isxdigit(cadena[1]))    /* es un número hexadecimal */
                     81:         {
                     82:             switch(strlen(cadena))
                     83:             {
                     84:                 case 2:    /* inmediato de 1 byte */
                     85:                 strcpy(cadena, "INM8");
                     86:                 break;
                     87: 
                     88:                 case 4:    /* inmediato de 2 bytes */
                     89:                 strcpy(cadena, "INM16");
                     90:                 break;
                     91: 
                     92:                 case 9:    /* dirección física */
                     93:                 strcpy(cadena, "B:D");
                     94:                 break;
                     95:             }
                     96:         }
                     97:         break;
                     98:     }
                     99: }
                    100: 
                    101: 
1.3     ! rico      102: /* esta función clasifica un operando explícito según su funcionalidad */
        !           103: /* las funciones de los operandos se dan en la base de datos de símbolos */
        !           104: /* se consideran independientes de la operación (lo cual no es cierto siempre) */
1.1       rico      105: 
                    106: void ClasificarOperandoExplicito(char *operando, char modo, fichainstruccion *tarjetaoperandos)
                    107: {
1.3     ! rico      108:     int id_simb;
        !           109:     char cadena[MAX_LINE];
        !           110:     char mensaje[MAX_LINE];
1.1       rico      111: 
1.3     ! rico      112:     strcpy(cadena, operando);
1.1       rico      113: 
1.3     ! rico      114:     if(cadena[0]!= '\0')
1.1       rico      115:     {
                    116:         NormalizarUbicacion(cadena);
                    117:         id_simb = BDBuscarCadena(TABLA_SIMBOLOS, CAMPO_SIMBOLO, cadena);
                    118: 
                    119:         if(id_simb == -1)
                    120:         {
                    121:             /* emito un error al fichero de log */ 
1.3     ! rico      122:             sprintf(mensaje, "[ClasificarOperandoExplicito] La cadena '%s' no se ha encontrado en Tabla Símbolos", cadena);
        !           123:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      124:         }
                    125: 
                    126:         /* relleno la tarjeta de operandos explícitos para el operando (cadena) */
1.3     ! rico      127:         /* según la funcionalidad dada por el campo tipo */
1.1       rico      128: 
                    129:         switch(simbolos[id_simb].tipo)
                    130:         {
                    131:             case DATOS:
                    132:             switch(modo)
                    133:             {
                    134:                 case LEIDOYESCRITO:    /* leido y escrito */
                    135:                 AgregarElementoLista(tarjetaoperandos->leidoexpldatos, simbolos[id_simb].simbolo);
                    136:                 AgregarElementoLista(tarjetaoperandos->leidoexpldatos, simbolos[id_simb].dependencias);
                    137:                 case ESCRITO:    /* escrito */
                    138:                 AgregarElementoLista(tarjetaoperandos->escritoexpldatos, simbolos[id_simb].simbolo);
                    139:                 AgregarElementoLista(tarjetaoperandos->escritoexpldatos, simbolos[id_simb].dependencias);
                    140:                 break;
                    141: 
                    142:                 case LEIDO:    /* leido */
                    143:                 AgregarElementoLista(tarjetaoperandos->leidoexpldatos, simbolos[id_simb].simbolo);
                    144:                 AgregarElementoLista(tarjetaoperandos->leidoexpldatos, simbolos[id_simb].dependencias);
                    145:                 break;
                    146: 
                    147:                 case NO_EXISTE:    /* no existe: emitir un error al fichero de log */
1.3     ! rico      148:                 sprintf(mensaje, "[ClasificarOperandoExplicito] El operando no existe");
        !           149:                 Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      150:                 break;
                    151:             }
                    152:             break;
                    153: 
                    154:             case PTR_MEM:
                    155:             switch(modo)
                    156:             {
                    157:                 case LEIDOYESCRITO:    /* leido y escrito */
                    158:                 AgregarElementoLista(tarjetaoperandos->leidoexpldir, simbolos[id_simb].simbolo);
                    159:                 case ESCRITO:    /* escrito */
                    160:                 AgregarElementoLista(tarjetaoperandos->escritoexpldir, simbolos[id_simb].simbolo);
                    161:                 break;
                    162: 
                    163:                 case LEIDO:    /* leido */
                    164:                 AgregarElementoLista(tarjetaoperandos->leidoexpldir, simbolos[id_simb].simbolo);
                    165:                 break;
                    166: 
                    167:                 case NO_EXISTE:    /* no existe: emitir un error al fichero de log */
1.3     ! rico      168:                 sprintf(mensaje, "[ClasificarOperandoExplicito] El operando no existe");
        !           169:                 Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      170:                 break;
                    171:             }
                    172:             break;
                    173: 
                    174:             case PTR_PILA:
                    175:             switch(modo)
                    176:             {
                    177:                 case LEIDOYESCRITO:    /* leido y escrito */
                    178:                 AgregarElementoLista(tarjetaoperandos->leidoexplpila, simbolos[id_simb].simbolo);
                    179:                 case ESCRITO:    /* escrito */
                    180:                 AgregarElementoLista(tarjetaoperandos->escritoexplpila, simbolos[id_simb].simbolo);
                    181:                 break;
                    182: 
                    183:                 case LEIDO:    /* leido */
                    184:                 AgregarElementoLista(tarjetaoperandos->leidoexplpila, simbolos[id_simb].simbolo);
                    185:                 break;
                    186: 
                    187:                 case NO_EXISTE:    /* no existe: emitir un error al fichero de log */
1.3     ! rico      188:                 sprintf(mensaje, "[ClasificarOperandoExplicito] El operando no existe");
        !           189:                 Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      190:                 break;
                    191:             }
                    192:             break;
                    193: 
                    194:             case BANDERAS:
                    195:             /* nunca se dan explícitamente pero pueden ser considerados explícitos a través del nemónico */
1.3     ! rico      196:             /* así se hará en la clasificación de implícitos */
1.1       rico      197:             break;
                    198: 
1.3     ! rico      199:             /* los 2 siguientes no representan realmente funciones */
1.1       rico      200: 
                    201:             case ACCESOS_MEM:    /* accesos a memoria */
                    202:             /* CÓMPUTO DE DIRECCIONES */
                    203:             /* BASE: registro de segmento */
                    204:             /* si hay prefijo de registro de segmento (longitud 2), ese es el leído */
                    205:             if(strlen(tarjetaoperandos->prefijo)==2)
1.3     ! rico      206:             {
        !           207:                 if(strcmp(tarjetaoperandos->prefijo, "SS") == 0) AgregarElementoLista(tarjetaoperandos->leidoexplpila, tarjetaoperandos->prefijo);
        !           208:                 else AgregarElementoLista(tarjetaoperandos->leidoexpldir, tarjetaoperandos->prefijo);
        !           209:             }
1.1       rico      210:             /* si no lo hay, agrego el indicado por defecto */
                    211:             else
                    212:             {
                    213:                 switch (simbolos[id_simb].segmento)
                    214:                 {
                    215:                     case CS:
                    216:                     AgregarElementoLista(tarjetaoperandos->leidoimpldir, "CS");
                    217:                     break;
                    218: 
                    219:                     case SS:
                    220:                     AgregarElementoLista(tarjetaoperandos->leidoimplpila, "SS");
                    221:                     break;
                    222: 
                    223:                     case DS:
                    224:                     AgregarElementoLista(tarjetaoperandos->leidoimpldir, "DS");
                    225:                     break;
                    226: 
                    227:                     case ES:
                    228:                     AgregarElementoLista(tarjetaoperandos->leidoimpldir, "ES");
                    229:                     break;
                    230:                 }
                    231:             }
                    232: 
                    233:             /* OFFSET: los registros involucrados en el cómputo de direcciones */
1.3     ! rico      234:             /* siempre son leídos; la función depende de la BASE */
        !           235:             if(strcmp(tarjetaoperandos->prefijo, "SS") == 0 ||
        !           236:                 simbolos[id_simb].segmento == SS)
        !           237:                 AgregarElementoLista(tarjetaoperandos->leidoexplpila, simbolos[id_simb].dependencias);
        !           238:             else AgregarElementoLista(tarjetaoperandos->leidoexpldir, simbolos[id_simb].dependencias);
1.1       rico      239: 
                    240:             /* DATO */
1.3     ! rico      241:             if(strcmp(tarjetaoperandos->prefijo, "SS") == 0 || simbolos[id_simb].segmento == SS)
        !           242:             {
        !           243:                 switch(modo)
        !           244:                 {
        !           245:                     case LEIDOYESCRITO:    /* leido y escrito */
        !           246:                     AgregarElementoLista(tarjetaoperandos->leidoexplpila, "PILA");
        !           247:                     case ESCRITO:    /* escrito */
        !           248:                     AgregarElementoLista(tarjetaoperandos->escritoexplpila, "PILA");
        !           249:                     break;
        !           250: 
        !           251:                     case LEIDO:    /* leido */
        !           252:                     AgregarElementoLista(tarjetaoperandos->leidoexplpila, "PILA");
        !           253:                     break;
        !           254: 
        !           255:                     case NO_EXISTE:    /* no existe: emitir un error al fichero de log */
        !           256:                     sprintf(mensaje, "[ClasificarOperandoExplicito] El operando no existe");
        !           257:                     Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           258:                     break;
        !           259:                 }
        !           260:             }
        !           261:             else
1.1       rico      262:             {
1.3     ! rico      263:                 switch(modo)
        !           264:                 {
        !           265:                     case LEIDOYESCRITO:    /* leido y escrito */
        !           266:                     AgregarElementoLista(tarjetaoperandos->leidoexpldatos, "MEM");
        !           267:                     case ESCRITO:    /* escrito */
        !           268:                     AgregarElementoLista(tarjetaoperandos->escritoexpldatos, "MEM");
        !           269:                     break;
        !           270: 
        !           271:                     case LEIDO:    /* leido */
        !           272:                     AgregarElementoLista(tarjetaoperandos->leidoexpldatos, "MEM");
        !           273:                     break;
        !           274: 
        !           275:                     case NO_EXISTE:    /* no existe: emitir un error al fichero de log */
        !           276:                     sprintf(mensaje, "[ClasificarOperandoExplicito] El operando no existe");
        !           277:                     Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           278:                     break;
        !           279:                 }
        !           280:                 break;
1.1       rico      281:             }
                    282:             break;
                    283: 
                    284:             case OTROS:
1.3     ! rico      285:             AgregarElementoLista(tarjetaoperandos->leidoexpldir, simbolos[id_simb].dependencias);
1.1       rico      286:             break;
                    287: 
                    288:             default:
1.3     ! rico      289:             /* emitir un error al fichero de log */
        !           290:             sprintf(mensaje, "[ClasificarOperandoExplicito] El tipo de símbolo no existe");
        !           291:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      292:             break;
                    293:         }
                    294:     }
                    295: }
                    296: 
                    297: 
1.3     ! rico      298: /* esta función clasifica un operando implícito leído según su funcionalidad */
        !           299: /* las funciones de los operandos se dan en la base de datos de símbolos */
        !           300: /* se consideran independientes de la operación (lo cual no es cierto siempre) */
1.1       rico      301: 
                    302: void ClasificarOperandoImplicitoLeido(char *cadena, char tipo, fichainstruccion *tarjetaoperandos)
                    303: {
1.3     ! rico      304:     int id_simb;
        !           305:     char mensaje[MAX_LINE];
1.1       rico      306: 
1.3     ! rico      307:     id_simb = BDBuscarCadena(TABLA_SIMBOLOS, CAMPO_SIMBOLO, cadena);
1.1       rico      308: 
1.3     ! rico      309:     if(id_simb == -1)
1.1       rico      310:     {
1.3     ! rico      311:         /* emito un error al fichero de log */ 
        !           312:         sprintf(mensaje, "[ClasificarOperandoImplicitoLeido] La cadena '%s' no se ha encontrado en Tabla Símbolos", cadena);
        !           313:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      314:     }
                    315: 
                    316:     switch(simbolos[id_simb].tipo)
                    317:     {
1.3     ! rico      318:         case DATOS:
1.1       rico      319:         AgregarElementoLista(tarjetaoperandos->leidoimpldatos, simbolos[id_simb].simbolo);
                    320:         AgregarElementoLista(tarjetaoperandos->leidoimpldatos, simbolos[id_simb].dependencias);
                    321:         break;
                    322: 
                    323:         case PTR_MEM:
                    324:         AgregarElementoLista(tarjetaoperandos->leidoimpldir, simbolos[id_simb].simbolo);
                    325:         break;
                    326: 
                    327:         case PTR_PILA:
                    328:         AgregarElementoLista(tarjetaoperandos->leidoimplpila, simbolos[id_simb].simbolo);
                    329:         break;
                    330: 
                    331:         case BANDERAS:
                    332:         if(tipo == SALTO_CONDICIONAL || tipo == CONTROL)
1.3     ! rico      333:             /* los saltos condicionales y las operaciones sobre banderas */
        !           334:             /* pueden ser considerados explícitos a través del nemónico */
        !           335:             AgregarElementoLista(tarjetaoperandos->leidoexplestado, simbolos[id_simb].simbolo);
1.1       rico      336:         else AgregarElementoLista(tarjetaoperandos->leidoimplestado, simbolos[id_simb].simbolo);
                    337:         break;
                    338: 
1.3     ! rico      339:         default:    /* emitir un error al fichero de log */
        !           340:         sprintf(mensaje, "[ClasificarOperandoImplicitoLeido] El tipo de símbolo no existe");
        !           341:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           342:         break;
        !           343:     }
1.1       rico      344: }
                    345: 
                    346: 
1.3     ! rico      347: /* esta función clasifica un operando implícito escrito según su funcionalidad */
        !           348: /* las funciones de los operandos se dan en la base de datos de símbolos */
        !           349: /* se consideran independientes de la operación (lo cual no es cierto siempre) */
1.1       rico      350: 
                    351: void ClasificarOperandoImplicitoEscrito(char *cadena, char tipo, fichainstruccion *tarjetaoperandos)
                    352: {
1.3     ! rico      353:     int id_simb;
        !           354:     char mensaje[MAX_LINE];
1.1       rico      355: 
1.3     ! rico      356:     id_simb = BDBuscarCadena(TABLA_SIMBOLOS, CAMPO_SIMBOLO, cadena);
1.1       rico      357:         
                    358:     if(id_simb == -1)
                    359:     {  
1.3     ! rico      360:         /* emito un error al fichero de log */ 
        !           361:         sprintf(mensaje, "[ClasificarOperandoImplicitoEscrito] La cadena '%s' no se ha encontrado en Tabla Símbolos", cadena);
        !           362:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      363:     }
                    364: 
                    365:     switch(simbolos[id_simb].tipo)
                    366:     {
1.3     ! rico      367:         case DATOS:
1.1       rico      368:         AgregarElementoLista(tarjetaoperandos->escritoimpldatos, simbolos[id_simb].simbolo);
                    369:         AgregarElementoLista(tarjetaoperandos->escritoimpldatos, simbolos[id_simb].dependencias);
                    370:         break;
                    371: 
1.3     ! rico      372:         case PTR_MEM:
1.1       rico      373:         AgregarElementoLista(tarjetaoperandos->escritoimpldir, simbolos[id_simb].simbolo);
                    374:         break;
                    375: 
                    376:         case PTR_PILA:
                    377:         AgregarElementoLista(tarjetaoperandos->escritoimplpila, simbolos[id_simb].simbolo);
                    378:         break;
                    379: 
1.3     ! rico      380:         case BANDERAS:
1.1       rico      381:         if(tipo == SALTO_CONDICIONAL || tipo == CONTROL)
1.3     ! rico      382:             /* los saltos condicionales y las operaciones sobre banderas */
        !           383:             /* pueden ser considerados explícitos a través del nemónico */
1.1       rico      384:             AgregarElementoLista(tarjetaoperandos->escritoexplestado, simbolos[id_simb].simbolo);
                    385:         else AgregarElementoLista(tarjetaoperandos->escritoimplestado, simbolos[id_simb].simbolo);
                    386:         break;
                    387: 
1.3     ! rico      388:         default:    /* emitir un error al fichero de log */
        !           389:         sprintf(mensaje, "[ClasificarOperandoImplicitoEscrito] El tipo de símbolo no existe");
        !           390:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           391:         break;
        !           392:     }
1.1       rico      393: }
                    394: 
                    395: 
1.3     ! rico      396: /* esta función desensambla una instrucción a partir de una secuencia de bytes */
        !           397: /* extrae información a partir del nemónico */
        !           398: /* clasifica el uso de los operandos explícitos según su función */
        !           399: /* clasifica el uso de los operandos implícitos según su función */
1.1       rico      400: 
                    401: void AnalizarOperandosIA16(unsigned char secuencia[12], fichainstruccion *tarjetaoperandos)
                    402: {
                    403:     /* El argumento de la función es un array con 2 posibles */
                    404:     /* formatos de instrucción: la que hay que desensamblar  */
                    405:     /* y la siguiente para poder saber si se salta o no      */
                    406:     /* ¡OJO! En realidad cada formato debería tener 7 bytes  */
                    407:     /* para prevenir el uso de prefijos                      */
                    408: 
                    409:     unsigned char formato[6];
                    410:     int i, j;
                    411:     struct desensamblado instruccion;  /* reservo memoria para una estructura de tipo desensamblado */
                    412:     int id_nemo;
                    413:     char cadena[MAX_LINE];    /* esto es un array de caracteres; cadena[x] es un puntero */
                    414:     char *elemento;           /* es un puntero a char; no es igual a cadena[x] para la función strtok */
1.3     ! rico      415:     char mensaje[MAX_LINE];
1.1       rico      416: 
                    417:     /* inicio la tarjeta de operandos */
1.3     ! rico      418:     IniciarTarjeta(tarjetaoperandos);
1.1       rico      419: 
                    420:     /* cargo la primera instrucción desde la secuencia */
                    421: 
                    422:     for(i=0; i<6; i++) formato[i] = secuencia[i];
                    423: 
                    424:     /* desensamblo la instrucción */
                    425:     DecodificarInstruccion086(formato, &instruccion);
                    426: 
                    427:     /* analizo la estructura desensamblada */
                    428:     /* PRIMERO: busco el nemónico en la BD */
                    429: 
                    430:     id_nemo = BDBuscarCadena(TABLA_NEMONICOS, CAMPO_NEMONICO, instruccion.nemonico);
                    431: 
                    432:     if(id_nemo == -1)
                    433:     {
                    434:         /* emito un error al fichero de log */ 
1.3     ! rico      435:         sprintf(mensaje, "[AnalizarOperandosIA16] La cadena '%s' no se ha encontrado en Tabla Nemónicos", instruccion.nemonico);
        !           436:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      437:     }
                    438: 
                    439:     /* salvo la información en la estructura de la ficha de instrucción */
                    440:     strcpy(tarjetaoperandos->nemonico, instruccion.nemonico);
                    441:     strcpy(tarjetaoperandos->op1, instruccion.op1);
                    442:     strcpy(tarjetaoperandos->op2, instruccion.op2);
                    443:     for (i=0; i<instruccion.longitud; i++)
                    444:     {
                    445:         cadena[0] = '\0';   /* inicio la cadena auxiliar */
                    446:         sprintf (cadena, "%02X", (unsigned char) formato[i]);
                    447:         /* si no le digo 'unsigned char' lo toma de 4 bytes */
                    448:         strcat(tarjetaoperandos->hexadecimal, cadena);
                    449:     }
                    450:     tarjetaoperandos->longitud = instruccion.longitud;
                    451: 
                    452:     /* ya puedo reutilizar la estructura de desensamblado de instrucción */
                    453:     /* porque la he salvado en la tarjeta de operandos */
                    454: 
                    455:     switch(nemonicos[id_nemo].tipo)
                    456:     {
                    457:         case SALTO_CONDICIONAL:     /* salto condicional */
                    458:         /* hay que saber si el salto se ha tomado o no */
                    459:         /* si la siguiente instrucción en la traza coincide con la */
                    460:         /* que aparece de forma residual en la cadena formato */
                    461:         /* a partir del último byte decodificado del salto entonces */
                    462:         /* el salto no se ha tomado ya que lo residual es consecutivo */
                    463: 
                    464:         /* cargo la siguiente instrucción desde la secuencia */
                    465: 
                    466:         for(i=0; i<BYTES_POR_INSTRUCCION; i++) formato[i] = secuencia[i+BYTES_POR_INSTRUCCION];
                    467: 
                    468:         /* desensamblo la instrucción */
                    469:         DecodificarInstruccion086(formato, &instruccion);
                    470: 
                    471:         /* compruebo si las codificaciones binarias son iguales */
                    472:         for(i=tarjetaoperandos->longitud, j = 0; i<BYTES_POR_INSTRUCCION-tarjetaoperandos->longitud && j<instruccion.longitud; i++, j++)
                    473:         {
                    474:             if (secuencia[i] != secuencia[BYTES_POR_INSTRUCCION+j]) break;
                    475:         }
                    476:         /* si salgo del bucle sin break entonces son iguales y NO hay salto */
                    477:         if(i==BYTES_POR_INSTRUCCION-tarjetaoperandos->longitud || j==instruccion.longitud) tarjetaoperandos->salto = NOTOMADO;
                    478:         /* si salgo con break la siguiente instrucción en la traza no es la */
                    479:         /* siguiente en la secuencia: el salto SI se toma */
                    480:         else tarjetaoperandos->salto = TOMADO;
                    481:         break;
                    482: 
                    483:         
                    484:         case PREFIJO:     /* prefijo */
                    485:         case PREFIJO_SEG:     /* prefijo registro de segmento */
                    486:         tarjetaoperandos->salto = 1;    /* no es instrucción de salto */
                    487: 
                    488:         /* guardo el prefijo */
                    489:         strcpy(tarjetaoperandos->prefijo, instruccion.nemonico);
                    490: 
                    491:         /* decodifico lo que queda de instrucción */
                    492:         /* OJO, el 7º byte se ha tomado de la siguiente instrucción */
                    493:         for(i=0; i<6; i++) formato[i] = secuencia[i+1];
                    494: 
                    495:         /* desensamblo la instrucción */
                    496:         DecodificarInstruccion086(formato, &instruccion);
                    497: 
                    498: 
                    499:         /* salvo la información en la estructura de la ficha de instrucción */
                    500:         strcpy(tarjetaoperandos->nemonico, instruccion.nemonico);
                    501:         strcpy(tarjetaoperandos->op1, instruccion.op1);
                    502:         strcpy(tarjetaoperandos->op2, instruccion.op2);
                    503:         /* anexo el formato al prefijo -primer byte hexadecimal- */
                    504:         for (i=0; i<instruccion.longitud; i++)
                    505:         {
                    506:             cadena[0] = '\0';   /* inicio la cadena auxiliar */
                    507:             sprintf (cadena, "%02X", (unsigned char) formato[i]);
                    508:             /* si no le digo 'unsigned char' lo toma de 4 bytes */
                    509:             strcat(tarjetaoperandos->hexadecimal, cadena);
                    510:         }
                    511:         tarjetaoperandos->longitud += instruccion.longitud;
                    512: 
                    513:         /* extraigo el índice del registro de la base de datos */
                    514:         id_nemo = BDBuscarCadena(TABLA_NEMONICOS, CAMPO_NEMONICO, instruccion.nemonico);
                    515: 
                    516:         if(id_nemo == -1)
                    517:         {
                    518:             /* emito un error al fichero de log */ 
1.3     ! rico      519:             sprintf(mensaje, "[AnalizarOperandosIA16] La cadena '%s' no se ha encontrado en Tabla Nemónicos", instruccion.nemonico);
        !           520:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
1.1       rico      521:         }
                    522:         break;
                    523: 
                    524:         case TRANSFERENCIA:     /* transferencia */
                    525:         case ARITMETICA:     /* aritmética */
                    526:         case LOGICA:     /* lógica */
                    527:         case CADENAS:     /* cadenas */
                    528:         case CONTROL:     /* control */
                    529:         case SIN_TIPO:   /* sin tipo */
                    530:         tarjetaoperandos->salto = NO_SALTO;    /* no es instrucción de salto */
                    531:         break;
                    532: 
                    533:         case SALTO_INCONDICIONAL:     /* salto incondicional */
                    534:         tarjetaoperandos->salto = INCONDICIONAL;    /* instrucción de salto */
                    535:         break;
                    536:     }
                    537: 
                    538:     /* SEGUNDO: operandos explícitos */
                    539:     /* operando fuente (op2) */
1.3     ! rico      540:     ClasificarOperandoExplicito(tarjetaoperandos->op2, nemonicos[id_nemo].modo_op2, tarjetaoperandos);
1.1       rico      541:     
1.3     ! rico      542:     /* operando destino (op1) */
        !           543:     ClasificarOperandoExplicito(tarjetaoperandos->op1, nemonicos[id_nemo].modo_op1, tarjetaoperandos);
1.1       rico      544:     
                    545: 
                    546:     /* TERCERO: operandos implícitos */
                    547:     /* analizo la lista de implícitos leídos */
                    548:     /* copio la información de la BD para no modificarla */
1.3     ! rico      549:     strcpy(cadena, nemonicos[id_nemo].implicitos_leidos);
1.1       rico      550: 
1.3     ! rico      551:     elemento = strtok(cadena, ":");   /* el separador de elementos de la lista es ':' */
1.1       rico      552:     while(elemento != NULL)
                    553:     {
1.3     ! rico      554:         ClasificarOperandoImplicitoLeido(elemento, nemonicos[id_nemo].tipo, tarjetaoperandos);
        !           555:         
1.1       rico      556:         /* capturo el siguiente campo */
                    557:         elemento = strtok(NULL, ":");
                    558:     }
                    559: 
                    560:     /* analizo la lista de implícitos escritos */
                    561:     /* copio la información de la BD para no modificarla */
1.3     ! rico      562:     strcpy(cadena, nemonicos[id_nemo].implicitos_escritos);
1.1       rico      563:     
1.3     ! rico      564:     elemento = strtok(cadena, ":");    /* el separador de elementos de la lista es ':' */
1.1       rico      565:     while(elemento != NULL)
                    566:     {
1.3     ! rico      567:         ClasificarOperandoImplicitoEscrito(elemento, nemonicos[id_nemo].tipo, tarjetaoperandos);
1.1       rico      568: 
                    569:         /* capturo el siguiente campo */
                    570:         elemento = strtok(NULL, ":");
                    571:     }
                    572: }
                    573: 
                    574: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>