Annotation of ADD_ver_10/AnalizadorOperandos16bits.c, revision 1.1

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

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