Annotation of ADD_ver_10/AnalizadorOperandos16bits.c, revision 1.2

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

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