NONE
NONE

Reputation: 233

Seemingly random return values

I'm trying to make a simple assembler for a very simple MIPS processer. Unfortunately, C has been giving me a lot of trouble, specifically, strcasecmp has not been returning valid/correct results. The results are correct sometimes.. but usually not, and I can't grasp why in the world this would be the case. Beyond any suggestions for a fix, could someone explain why these errors are occurring?

NOTE I do not think the error is due to passing the register table. Same errors occur when register table is declared inside the convert register function

Thanks!!!

the function that should return the value corresponding to the register name. Note that RegisterTable is declared in main. I did this so I could iterate through and test every Register name in the table from main

int ConvertRegisterName(char * rname,REG_NAME_PAIR RegisterTable[32])
{
    int i;
    int j=0;
    for (i=1; i<32; i++,i++)
    {
        if (!(strcasecmp(RegisterTable[i].reg_number,rname) & strcasecmp(RegisterTable[i].reg_name,rname)))
        {
            j=i;
            return j;
            break;
        }
    }

    if(!j)
    {
        printf("Error with register name \n");
        return j;
    }
}

The main function

int main(int argc,char *argv[])
{
    REG_NAME_PAIR RegisterTable[32];
    RegisterTable[1].reg_name    = "at";
    RegisterTable[1].reg_number  = "$1";
    RegisterTable[2].reg_name    = "v0";
    RegisterTable[2].reg_number  = "$2";
    RegisterTable[3].reg_name    = "v1";
    RegisterTable[3].reg_number  = "$3";
    RegisterTable[4].reg_name    = "a0";
    RegisterTable[4].reg_number  = "$4";
    RegisterTable[5].reg_name    = "a1";
    RegisterTable[5].reg_number  = "$5";
    RegisterTable[6].reg_name    = "a2";
    RegisterTable[6].reg_number  = "$6";
    RegisterTable[7].reg_name    = "a3";
    RegisterTable[7].reg_number  = "$7";
    RegisterTable[8].reg_name    = "t0";
    RegisterTable[8].reg_number  = "$8";
    RegisterTable[9].reg_name    = "t1";
    RegisterTable[9].reg_number  = "$9";
    RegisterTable[10].reg_name   = "t2";
    RegisterTable[10].reg_number = "$10";
    RegisterTable[11].reg_name   = "t3";
    RegisterTable[11].reg_number = "$11";
    RegisterTable[12].reg_name   = "t4";
    RegisterTable[12].reg_number = "$12";
    RegisterTable[13].reg_name   = "t5";
    RegisterTable[13].reg_number = "$13";
    RegisterTable[14].reg_name   = "t6";
    RegisterTable[14].reg_number = "$14";
    RegisterTable[15].reg_name   = "t7";
    RegisterTable[15].reg_number = "$15";
    RegisterTable[16].reg_name   = "s0";
    RegisterTable[16].reg_number = "$16";
    RegisterTable[17].reg_name   = "s1";
    RegisterTable[17].reg_number = "$17";
    RegisterTable[18].reg_name   = "s2";
    RegisterTable[18].reg_number = "$18";
    RegisterTable[19].reg_name   = "s3";
    RegisterTable[19].reg_number = "$19";
    RegisterTable[20].reg_name   = "s4";
    RegisterTable[20].reg_number = "$20";
    RegisterTable[21].reg_name   = "s5";
    RegisterTable[21].reg_number = "$21";
    RegisterTable[22].reg_name   = "s6";
    RegisterTable[22].reg_number = "$22";
    RegisterTable[23].reg_name   = "s7";
    RegisterTable[23].reg_number = "$23";
    RegisterTable[24].reg_name   = "t8";
    RegisterTable[24].reg_number = "$24";
    RegisterTable[25].reg_name   = "t9";
    RegisterTable[25].reg_number = "$25";
    RegisterTable[26].reg_name   = "k0";
    RegisterTable[26].reg_number = "$26";
    RegisterTable[27].reg_name   = "k1";
    RegisterTable[27].reg_number = "$27";
    RegisterTable[28].reg_name   = "gp";
    RegisterTable[28].reg_number = "$28";
    RegisterTable[29].reg_name   = "sp";
    RegisterTable[29].reg_number = "$29";
    RegisterTable[30].reg_name   = "fp";
    RegisterTable[30].reg_number = "$30";
    RegisterTable[31].reg_name   = "ra";
    RegisterTable[31].reg_number = "$31";


    int i;
    for (i=1; i<32; i++)
    {
        printf("i is %d\n",i);
        printf("Register Name is %s \n" ,RegisterTable[i].reg_name);
        printf("this is the return value %d",ConvertRegisterName(RegisterTable[i].reg_name,RegisterTable));
        printf("\n");
        printf("Register Number %s\n",RegisterTable[i].reg_number);
        printf("this is the return value %d",ConvertRegisterName(RegisterTable[i].reg_number,RegisterTable));
        printf("\n");
        printf("\n");
    }
}

The REG_NAME_PAIR struct

typedef struct
{
    char *reg_name;
    char *reg_number;
} REG_NAME_PAIR;

Upvotes: 1

Views: 124

Answers (2)

ugoren
ugoren

Reputation: 16451

You seem to be using the & operator instead of &&.
& does bitwise and, not logical and. So for example:
0x01 & 0x02 == 0 - because no bit is set on both
0x01 && 0x02 == 1 - because both 0x01 and 0x02 evaluate to true.

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477514

The conversion function could probably be simplified and corrected to something like this:

int ConvertRegisterDesc(const char * token, REG_NAME_PAIR RegisterTable[])
{
    for (int i = 1; i != 32; ++i)
    {
        if (strcasecmp(RegisterTable[i].reg_number, token) == 0 ||
            strcasecmp(RegisterTable[i].reg_name,   token) == 0   )
        {
            return i;
        }
    }

   printf("Error with register name \n");
   return 0;
}

Now ConvertRegisterDesc("foo", RegisterTable) returns the index of an entry whose name or value is (a case variant of) "foo", and 0 if no such entry could be found.

Upvotes: 3

Related Questions