Annotation of ADD_ver_10/Source Code/Source Files/AnalizadorOperandos16bits.c, revision 1.2

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

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