Babbleshack
Babbleshack

Reputation: 341

Bus Error when trying to pass int to pointer

I am trying to build a simple assembly emulator. I am trying to create the set function; the function will take 2 parameters (String arrays) arg1 & arg2. it will then compare the strings against an array of strings, which is an index for an arraylist of function pointers.

The problem I am having is when I try to set the value of the register. I have tried many variants of the line:

*register_ptr[i] = *(int*)(atoi(arg2));

with no success; is there something I am not understanding?

The code will hopefully be more clear:

int opcode_set(char* opcode, char *arg1, char *arg2)
    {
      int i, j;
      //printf("%d\n", (int)arg2);
      for(i=0;i<4;i++)
      {
        if(!strcmp(arg1, register_str[i]))
        {
          for(j=0;j<4;j++)
          {
            if(!strcmp(arg2, register_str[i]))
            {
              *register_ptr[i] = *(int*)register_ptr[j];
            }
            else
            {
              *register_ptr[i] = *(int*)(atoi(arg2));

            }
          }
        }
      }
      //printf("%d", *register_ptr[i] );
      INSP++; /* NOP does not do anything except moving the instruction pointer to the next instruction */
      return (0); 
    } 

EDIT: declarations for register_str & register_ptr:

 const char *register_str[] = {"REGA", "REGB", "REGC", "REGX"};
 int *register_ptr[]={&REGA, &REGB, &REGC, &REGX};

I use two arrays in order to decide which opcode, an array of strings, and an array of function pointers, I index through the strings and use the same index location to call the function:

int exec_instruction(char *instruction){
int i; //used for indexing 

/* the line below may be useful for debugging to see the current instruction*/
/*printf("executing line: %s", instruction);*/

/* three variables could be used to extract opcode and 
 arguments from the variable instruction */
char *opcode = NULL;
char *arg1 = NULL;
char *arg2 = NULL ;
char *copy = NULL;

/* we need here some functionality to extract opcode, 
 arg1 and arg2 from the string instruction*/
copy = strdup(instruction);
opcode = strtok(copy," \n\r");
arg1 = strtok(NULL," \n\r");
arg2 = strtok(NULL," \n\r");


/* Now we have to call the right function corresponding 
 to the right opcode For example: */
for(i = 0; i < 10; i++)
{
  if(!strcmp(opcode_str[i], opcode))
    (*opcode_func[i])(opcode,arg1,arg2);
}

/* for demonstration purpose we execute NOP independent of input
 this line must go in your implementation */
(*opcode_func[0])("NOP",NULL,NULL);

/* return value should be 0 if execution was ok otherwise -1*/
return(0);
}

The two arrays I was speaking about:

    const char *opcode_str[] = {"NOP", "SET", "AND", "OR", "ADD", "SUB", "SHL", "SHR", "JMP", "PRT"};

    opcode_function opcode_func[] = { &opcode_nop, &opcode_set, &opcode_and, &opcode_or, &opcode_add, &opcode_sub, &opcode_shl, &opcode_shr, &opcode_jmp, &opcode_prt };

Upvotes: 0

Views: 366

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754450

Given the declaration for register_ptr, the lines:

          *register_ptr[i] = *(int*)register_ptr[j];
        }
        else
        {
          *register_ptr[i] = *(int*)(atoi(arg2));

are both wrong (one harmlessly, one less harmlessly). The first doesn't need the cast; you could perfectly well write:

          *register_ptr[i] = *register_ptr[j];

The second really doesn't need any casting either, but it doesn't need the level of indirection either:

          *register_ptr[i] = atoi(arg2);

This assigns the integer returned by atoi(arg2) to the memory pointed at by register_ptr[i], which is presumably one of REGA, REGB, REGC or REGX. As written, you are treating the value in arg2 as an address in your simulator's memory space and reading the value that's there, with all sorts of (probably) unwanted consequences (such as core dumps).

Upvotes: 2

Related Questions