Switch ignora caso existente y salta a default, ignorando casos predefinidos.

Iniciado por harry_the_blogger, 26 Septiembre 2014, 21:07 PM

0 Miembros y 1 Visitante están viendo este tema.

harry_the_blogger

Hola amigos, tengo un problema. Primero que nada describiré lo que intento hacer: Estoy desarrollando un desensamblador, especificamente este trozo de codigo trata sobre identificar los prefijos que poseen las instrucciones, y guardar en un archivo el prefijo encontrado. Este es un trozo resumido del codigo, y es donde está el problema.

Por ejemplo: Si yo llamo a la funcion show_prefixe(output_file, prefix_cs_override), la funcion trabaja bien, y imprime dentro del fichero la palabra "CS" tal como corresponde según mi tabla.

La funcion trabaja bien con todos los prefijos, excepto con los tres primeros: LOCK, REP y REPNE. No sé porque cuando llamo la funcion con los valores respectivos de cada uno, imprime "UNDEF" (caso por default si no consigue ningun case para ese valor). No entiendo porque toma el caso por default, si existen casos respectivos para cada prefijo (LOCK, REP, y REPNE)

He estado dando vueltas, pero aún no consigo ayuda. Espero que ustedes me ayuden a descifrar este misterioso problema. Aqui va el codigo.


#include <stdio.h>

///Prefixes lock and repeat (group one)

#define prefix_lock 0xF0
#define prefix_repne 0xF2
#define prefix_rep 0xF3

///Prefixes segmet override (group two)
#define prefix_cs_override 0x2E
#define prefix_ss_override 0x36
#define prefix_ds_override 0x3E
#define prefix_es_override 0x26
#define prefix_fs_override 0x64
#define prefix_gs_override 0x65

///Branch hints goes here.

///Operand-size override (group three)
#define prefix_operand_size_override 0x66

///Address-size override (group four)
#define prefix_address_size_override 0x67



int show_prefixe(FILE *my_output, char prefix){
    switch(prefix){
        case prefix_lock:
            fprintf(my_output, "LOCK ");
            break;
        case prefix_repne:
            fprintf(my_output, "REPNE ");
            break;
        case prefix_rep:
            fprintf(my_output, "REP ");
            break;
        case prefix_ss_override:
            fprintf(my_output, "SS ");
            break;
        case prefix_cs_override:
            fprintf(my_output, "CS ");
            break;
        case prefix_ds_override:
            fprintf(my_output, "DS ");
            break;
        case prefix_es_override:
            fprintf(my_output, "ES ");
            break;
        case prefix_fs_override:
            fprintf(my_output, "FS ");
            break;
        case prefix_gs_override:
            fprintf(my_output, "GS ");
            break;
        case prefix_operand_size_override:
            fprintf(my_output, "OP ");
            break;
        case prefix_address_size_override:
            fprintf(my_output, "ADDR ");
            break;
        default:
            fprintf(my_output, "UNDEF ");
            break;
    }
}

int main()
{
    FILE *output;
    output = fopen("C:\\prefix.asm", "wb");
    show_prefixe(output, prefix_rep);
    fclose(output);
    return 0;
}



¿Será que el compilador tiene bugs? No sé, lo pregunto porque no estoy usando la ultima version, solo estoy usando la previa a la ultima. No sé realmente que ocurre.

Gracias de antemano por su ayuda.
Vista mi blog es enriquemesa.blogspot.com

rir3760

Lo primero: cuando tengas una duda o problema con un programa en C o C++ utiliza el foro apropiado: Programación C/C++.

----

El problema que mencionas se genera con la llamada:
///Prefixes lock and repeat (group one)

#define prefix_lock 0xF0
#define prefix_repne 0xF2
#define prefix_rep 0xF3

/* ... */

show_prefixe(output, prefix_rep); /* prefix_rep == 0xF3 == 243 */

La función "show_prefixe" la defines como una cuyo segundo parámetro es de tipo char y este es, usualmente, equivalente al tipo signed char con (de nuevo usualmente) ocho bits, complemento a dos para representar los negativos y un rango valido de -128 a 127.

¿Que pasa cuando un valor de tipo signed int como 0xF3 (decimal 243) se convierte al tipo signed char y esta fuera de su rango valido? Buena pregunta.

Para solucionar el problema en tu programa base solo tienes que cambiar el tipo del mentado parámetro a unsigned char, por supuesto en el programa original la lectura también debe realizarse de la misma forma (leyendo todos los caracteres como caracteres sin signo).

Un saludo
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

harry_the_blogger

Gracias rir3760!! No sabía que había mucha diferencia entre un char con signo o sin signo!! Entonces, ¿Será que si hago el mismo switch pero enteros con signo y otros con signo, puede que algunos valores los interprete mal?

Saludos. Gracias por tu ayuda.
Vista mi blog es enriquemesa.blogspot.com

cpu2

Cita de: harry_the_blogger en 27 Septiembre 2014, 04:51 AM
Gracias rir3760!! No sabía que había mucha diferencia entre un char con signo o sin signo!! Entonces, ¿Será que si hago el mismo switch pero enteros con signo y otros con signo, puede que algunos valores los interprete mal?

Saludos. Gracias por tu ayuda.

No hace falta que utilices variables int, ya que estas trabajando con enteros de 1 byte, y char reserva 1 byte en memoria asi que seria correcto. Un int seria para enteros con mas longitud.

Creo que no entendiste lo que explico el usuario @rir3760, voy a decirtelo con mis palabras.

Si tu declaras un char, puedes almacenar el int de 1 byte que quieras, pero si este pasa de 0x7f (127), se entendera de que este es negativo, se entiende? Vamos que si tienen el bit 7 en 1, representa que es negativo.

Con un unsigned char, representa que es de 0 a 255, eso significa que todos los numeros seran positivos, con un signed el mayor numero positivo que puedes tener es 127.

Como tu declaraste un char, y esos bytes tienen el bit 7 en 1, pues se reconoceran como numeros negativos, no como positivos.

0xF0 >>> 240 >>> -16
0xF2  >>>>> 242 >>> -14
0xF3  >>>>> 243 >>> -13


Un saludo.