elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  modos de direccionamiento
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: modos de direccionamiento  (Leído 3,861 veces)
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
modos de direccionamiento
« en: 16 Febrero 2014, 21:18 pm »

Saludos, tengo el siguiente codigo que dado un operando (una cadena) tiene que verificar que modo de direccionamiento es, puede ser inmediato,directo o indexado, yo ahora estoy verificando cuando un operando es indexado, esto es: que el primer caracter sea un corchete [, que el segundo caracter sea una d ó D, que el tercer caracter sea una coma, y ya que verificaste los primeros 3 el termino que va despues de la coma puede ser X,Y,SP,PC, o sea algo como:

[D,X], [D,Y], [D,SP], [D,PC]  

el problema lo tengo en la funcion direccionamientoIndexado() que se supone que me tiene que imprimir el termino que va despues de la coma, pero cuando los operandos son: [D,SP] o [D,PC] el segundo termino lo imprime como SSP en vez de SP y no entiendo por qué. EL codigo va leyendo desde la coma hasta el corcheta ] y lo que se encuentre entre estos dos los guarda en una cadena

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define INMEDIATO '#'
  5. #define DIRECTO '$'
  6. #define INDEXADO '['
  7.  
  8. void modoDireccionamiento(char *operando);
  9. void direccionamientoIndexado(char *operando);
  10. int esNumeroBase16(char caracter);
  11. int esLetraBase16(char caracter);
  12. int esOctal(char caracter);
  13. int esBinario(char caracter);
  14.  
  15. int main()
  16. {
  17.    char *operando = "[D,PC]";
  18.    modoDireccionamiento(operando);
  19.    return 0;
  20. }
  21.  
  22. void modoDireccionamiento(char *operando)
  23. {
  24.    int car,esInmediato,esDirecto,esIndexado,tam,i;
  25.    tam = strlen(operando);
  26.    car = operando[0];
  27.    switch(car)
  28.    {
  29.        case INMEDIATO:
  30.           esInmediato = 1;
  31.           car = operando[1];
  32.           switch(car)
  33.           {
  34.               case '\0':
  35.                  printf("Es un formato invalido para un modo de direccionamiento inmediato\n");
  36.                  break;
  37.               case '$':
  38.                  for(i = 2;((i < tam)&&(esInmediato));i++)
  39.                  {
  40.                      if((!esNumeroBase16(operando[i]))&&(!esLetraBase16(operando[i])))
  41.                         esInmediato = 0;
  42.                  }
  43.                  if(!esInmediato)
  44.                     printf("Se encontro un digito invalido para un numero de base 16");
  45.                  break;
  46.               case '@':
  47.                  for(i = 2;((i < tam)&&(esInmediato));i++)
  48.                  {
  49.                      if(!esOctal(operando[i]))
  50.                         esInmediato = 0;
  51.                  }
  52.                  if(!esInmediato)
  53.                     printf("Se encontro un digito invalido para un numero de base 8");
  54.                  break;
  55.               case '%':
  56.                  for(i = 2;((i < tam)&&(esInmediato));i++)
  57.                  {
  58.                      if(!esBinario(operando[i]))
  59.                         esInmediato = 0;
  60.                  }
  61.                  if(!esInmediato)
  62.                     printf("Se encontro un digito invalido para un numero de base 2");
  63.                  break;
  64.               default:
  65.                  printf("Error");
  66.           }
  67.           break;
  68.        case DIRECTO:
  69.           esDirecto = 1;
  70.           if(operando[1] == '\0')
  71.              printf("Es un formato invalido para un modo de direccionamiento directo\n");
  72.           else
  73.           {
  74.               for(i = 2;((i < tam)&&(esDirecto));i++)
  75.               {
  76.                   if((!esNumeroBase16(operando[i]))&&(!esLetraBase16(operando[i])))
  77.                      esDirecto = 0;
  78.               }
  79.               if(!esDirecto)
  80.                  printf("Se encontro un digito invalido para un numero de base 16");
  81.           }
  82.           break;
  83.        case INDEXADO:
  84.           esIndexado = 1;
  85.           car = operando[1];
  86.           switch(car)
  87.           {
  88.               case '\0':
  89.                  printf("Es un formato invalido para un modo de direccionamiento indexado\n");
  90.                  break;
  91.               case ',':
  92.                  printf("No puede haber una instruccion vacia antes de la coma");
  93.                  break;
  94.               case 'd':
  95.               case 'D':
  96.                  if(operando[2] == ',')
  97.                  {
  98.                      direccionamientoIndexado(operando);
  99.                         //esIndexado = 0;
  100.                  }
  101.                  //if(!esIndexado)
  102.                     //printf("Es un formato invalido para direccionamiento indexado");
  103.                  break;
  104.               default:
  105.                  printf("Error");
  106.           }
  107.           break;
  108.        default:
  109.           printf("Error: es un formato invalido para los modos de direccionamiento inmediato\n");
  110.    }
  111. }
  112.  
  113. int esNumeroBase16(char caracter)
  114. {
  115.    if(caracter >= '0' && caracter <= '9')
  116.       return 1;
  117.    else
  118.       return 0;
  119. }
  120.  
  121. int esLetraBase16(char caracter)
  122. {
  123.    if((caracter >= 'A' && caracter <= 'F')||(caracter >= 'a' && caracter <= 'f'))
  124.       return 1;
  125.    else
  126.       return 0;
  127. }
  128.  
  129. int esOctal(char caracter)
  130. {
  131.    if(caracter >= '0' && caracter <= '7')
  132.       return 1;
  133.    else
  134.       return 0;
  135. }
  136.  
  137. int esBinario(char caracter)
  138. {
  139.    if(caracter == '1' || caracter == '0')
  140.       return 1;
  141.    else
  142.       return 0;
  143. }
  144.  
  145. void direccionamientoIndexado(char *operando)
  146. {
  147.    int i;
  148.    char *cadena = NULL,c[2];
  149.    cadena = calloc(2,sizeof(char));
  150.    for(i = 3;operando[i] != ']';i++)
  151.    {
  152.        sprintf(c,"%c",operando[i]);
  153.        strcat(cadena,c);
  154.        printf("%s",cadena);
  155.    }
  156. }
  157.  

si alguien me pudiera decir donde esta el error se lo agradeceria mucho


« Última modificación: 16 Febrero 2014, 21:19 pm por m@o_614 » En línea

erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: modos de direccionamiento
« Respuesta #1 en: 17 Febrero 2014, 01:10 am »

Hola debe ser cuando ejecutas strcat(cadena,c); a la primera vez le estas pasando en este caso 'P' que es lo que tiene la variable c en ese momento, pero cuando vuelva a ejecutarse strcat(cadena,c); en ese momento le estas pasando ahora "PC" que es lo que tiene la variable c despues, y por eso se repite 2 veces el primer caracter.

Corrijo: El error esta en que la primera vez se muestra lo que tiene la variable cadena en ese momento que es 'P', luego a la segunda iteracion le pasas a cadena la letra 'C', cuando muestres de nuevo el contenido de cadena se reflejara "PC", y por eso se ve que se repite la 'P' 2 veces, en todo caso la sentencia printf("%s",cadena); deberia ir fuera del ciclo for.


« Última modificación: 17 Febrero 2014, 01:20 am por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: modos de direccionamiento
« Respuesta #2 en: 17 Febrero 2014, 19:18 pm »

gracias erest0r por tu respuesta, ya cambie el printf que me estaba dando problemas ahora me queda una duda, para comparar cadenas tengo que usar strcmp pero si tengo que verificar si la cadena es "X","Y","SP" o "PC", no habra una manera de reducir el codigo en esa parte donde tengo los strcmps en el if??:

Código
  1. int direccionamientoIndexado(char *operando)
  2. {
  3.    int i;
  4.    char *cadena = NULL,c[2];
  5.    cadena = calloc(2,sizeof(char));
  6.    for(i = 3;operando[i] != ']';i++)
  7.    {
  8.        sprintf(c,"%c",operando[i]);
  9.        strcat(cadena,c);
  10.    }
  11.    printf("%s",cadena);
  12.    if((strcmp(cadena,"X") == 0)||(strcmp(cadena,"Y") == 0)||(strcmp(cadena,"SP") == 0)||(strcmp(cadena,"PC") == 0))
  13.       return 1;
  14.    else
  15.       return 0;
  16. }
  17.  

gracias
En línea

erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: modos de direccionamiento
« Respuesta #3 en: 18 Febrero 2014, 04:38 am »

Hola, ¿que te parece esta manera?

Código
  1. int direccionamientoIndexado(char *operando)
  2. {
  3.    int i;
  4.    char *cadena = NULL,c[2];
  5.    char index[4][3] = { "X", "Y", "SP", "PC" };
  6.    cadena = (char *)calloc(2,sizeof(char));
  7.    for(i = 3;operando[i] != ']';i++)
  8.    {
  9.        sprintf(c,"%c",operando[i]);
  10.        strcat(cadena,c);
  11.    }
  12.    printf("%s",cadena);
  13.  
  14.    for( i = 0; i < 4; i++ )
  15.    {
  16.        if( strcmp(cadena, index[i]) == 0 )
  17.            return 1;
  18.    }
  19.       return 0;
  20. }
  21.  

De esa forma el IF se hace mas corto, solo que se agrega una variable de cadena para compararla en cada iteracion con tu variable "cadena", si es igual a una de ellas retorna 1, sino retorna 0.
En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: modos de direccionamiento
« Respuesta #4 en: 18 Febrero 2014, 16:12 pm »

gracias erest0r, si de esa manera es mucho mejor, y asi ya no tengo que repetir tantos strcmp's en la línea del if. Una última pregunta, una vez que ya tengo concatenadas todas las letras que quiero en la cadena(con ayuda del strcat), tengo que agregarle al final el carácter de fin de cadena '\0'? para que no almacene basura
En línea

erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: modos de direccionamiento
« Respuesta #5 en: 18 Febrero 2014, 17:35 pm »

En tu caso no es necesario, ya que cuando creas el tamaño de "cadena" lo haces con funcion calloc, y ello lo inicializa con todas sus posiciones en '\0', aun asi, por lo general es recomendable que dejes al menos una posicion libre para finalizarle con '\0' y asi el programa pueda reconocer el fin de cadena, si lo hicieras con un malloc, te crea el arreglo con contenido basura y al mostrar lo que tiene "cadena" te mostrara lo que le asignaste mas toda esa informacion basura.
En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: modos de direccionamiento
« Respuesta #6 en: 18 Febrero 2014, 18:27 pm »

estoy verificando cuando un operando es indexado, esto es: que el primer caracter sea un corchete [, que el segundo caracter sea una d ó D, que el tercer caracter sea una coma, y ya que verificaste los primeros 3 el termino que va despues de la coma puede ser X,Y,SP,PC, o sea algo como:

[D,X], [D,Y], [D,SP], [D,PC]
Supongo eventualmente vas a estudiar el tema de maquinas de estado (lo usual para desarrollar tu programa). Llevas la materia de teoria de compiladores, ¿Correcto?

Una última pregunta, una vez que ya tengo concatenadas todas las letras que quiero en la cadena(con ayuda del strcat), tengo que agregarle al final el carácter de fin de cadena '\0'? para que no almacene basura
No ya que al utilizar sprintf y strcat son esas funciones las que agregan el '\0'. Lo que si debes hacer es incrementar el tamaño del bloque de memoria para almacenar ese caracter.

Y no deberias utilizar sprintf y strcat ya que puedes agregar los caracteres y el '\0' con un simple bucle.

----

Por ultimo en un caso tan limitado se puede utilizar la funcion sscanf para verificar si la cadena cumple con el formato esperado, de nuevo lo mejor es una maquina de estado pero si se trata de matar tiempo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int fn(char *p);
  5.  
  6. int main(void)
  7. {
  8.   char pal[][4] = {
  9.      "X]",
  10.      "X}",
  11.      "Y]",
  12.      "Z]",
  13.      "SP]",
  14.      "XY]",
  15.      "PC]",
  16.      "PC)"
  17.   };
  18.   int i;
  19.   int num_pals = (int) (sizeof pal / sizeof pal[0]);
  20.  
  21.   for (i = 0; i < num_pals; i++)
  22.      printf("%s ==> %s\n", pal[i], fn(pal[i]) ? "OK" : "ERROR");
  23.  
  24.   return EXIT_SUCCESS;
  25. }
  26.  
  27. int fn(char *p)
  28. {
  29.   char a[2];
  30.   char b[2];
  31.  
  32.   return sscanf(p, "%1[XY]%1[]]", a, b) == 2 || sscanf(p, "SP%1[]]", b) == 1 || sscanf(p, "PC%1[]]", b) == 1;
  33. }

Y la salida es:
Código:
$ ./main.exe
X] ==> OK
X} ==> ERROR
Y] ==> OK
Z] ==> ERROR
SP] ==> OK
XY] ==> ERROR
PC] ==> OK
PC) ==> ERROR

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: modos de direccionamiento
« Respuesta #7 en: 24 Febrero 2014, 02:50 am »

Saludos rir3760 no es para la materia de compiladores, esto es basicamente para crear un ensamblador para la materia de Programacion de sistemas, que es la antesala para compiladores, y el codigo sirve para verificar los diferentes modos de direccionamiento que puede tener, en este caso estoy verificando los indexados, los que estan entre corchetes, pero me queda una ultima duda, si por ejemplo tengo [D,SP   , aqui el operando esta todo bien excepto porque no tiene un corchete al final ']'. ¿Cómo puedo hacer que me verifique este error si en la función direccionamientoIndexado tengo que el for va a seguir iterando hasta que encuentre el ], pero en este caso no hay ningun corchete:

Código
  1. void direccionamientoIndexado(char *operando)
  2. {
  3.    int i;
  4.    char *cadena = NULL,c[2];
  5.    cadena = calloc(2,sizeof(char));
  6.    for(i = 3;operando[i] != ']';i++)
  7.    {
  8.        sprintf(c,"%c",operando[i]);
  9.        strcat(cadena,c);
  10.        printf("%s",cadena);
  11.    }
  12. }

de antemano gracias
« Última modificación: 24 Febrero 2014, 02:52 am por m@o_614 » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
modos de impresion
Diseño Gráfico
jota_dj 2 2,241 Último mensaje 30 Abril 2004, 07:20 am
por zuuoom
Direccionamiento indexado ASM
ASM
farresito 5 6,769 Último mensaje 20 Agosto 2010, 08:43 am
por Eternal Idol
Direccionamiento segmentado
ASM
franfis 0 3,935 Último mensaje 31 Octubre 2010, 01:13 am
por franfis
Direccionamiento ip.
Redes
NetJava 2 2,745 Último mensaje 5 Julio 2011, 22:13 pm
por NetJava
modos de direccionamiento indexado de 5/9/16 bits
Programación C/C++
m@o_614 3 2,687 Último mensaje 8 Marzo 2014, 09:50 am
por eferion
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines