0

I am trying to write an assembler for the RiSC CPU, Ridiculously simply computer - more information about this can be found here - Link to CPU information.

I have been programming in C for some time now and I am running into an issue. The first step of my assembler is to find all of the Labels and take note of their location, right now I am trying to create an array of simply the names of the labels, and a separate array containing the line of asm that they will point to.

I have the following function which parses a line of assembly code and finds the Labels:

int lcount=0;
int lineCount = 0;
char *  BuildLabels(char * line, FILE *in, char *Labels[], char *LabelVals[])
{
    char lineString = fgets(line,MAX_LENGTH,in);
    if(lineString!=NULL)
    {
        char * FirstToken = strtok(line," \t\n");
        if(FirstToken[0]!='#' || FirstToken != NULL)
        {
            if(FirstToken[strlen(FirstToken)-1]==':')
            {
                Labels[lcount] = FirstToken;
                LabelVals[lcount] = lineCount;
                printf("%s : %d\n",Labels[lcount],lcount);
                lcount++;
            }
          lineCount++;
        }
    return Labels[lcount];
   }else
       {
           return NULL;
       }
}

The function is being called by this segment of code in the main

char *Labels[NUM_LABELS];
char *LabelVals[NUM_LABELS];
while(BuildLabels(lineString,input,Labels,LabelVals)!=NULL)
{

}
printf("%s:%s\n",Labels[0],Labels[1]);
printf("Exiting Now...\n");

When I run this program I get the following output

Opening input...
Opening output...
start::0
done::1
count::2
neg1::3
startAddr::4
startAddr::startAddr:
Exiting Now...

Process returned 0 (0x0)   execution time : 0.009 s
Press any key to continue.

So..The arrays are changed in the function but they are not affected in the main? I expect the last line to be start::done: and not startAddr::startAddr.

I thought this was strange so I wrote the following function and it alters the strings in both the function being called and the main as expected when I try to print Labels[0] and Labels1

void Testing(char *Labels[])
{
    lcount = 0;
    Labels[lcount] = "Testing";
    lcount++;
    Labels[lcount] = "Double Testing";
}

When I call this function from the main and then try to print Labels[0] and Labels1 it prints out "Testing:Double Testing"

I'm not understanding why the previous function isn't working properly - also this is not homework, I want to learn more about compilers/assemblers as I'm used to working in Verilog/VHDL.

Any help is appreciated!

EDIT: This ended up being my solution, could someone possible explain to me why this works?

Labels[lcount] = malloc(strlen(FirstToken)+1);
strcpy(Labels[lcount],FirstToken);
1
  • Are lcount and linecount globally defined? Commented Nov 24, 2013 at 6:30

2 Answers 2

1

I am not sure this is your root problem but in this line

char lineString = fgets(line,MAX_LENGTH,in);  

You are trying to store an string to a char type variable.
Change it to

char *lineString; 

and allocate memory for lineString.

lineString = malloc(Size_You_want_to_allocate); //50 byte or 100 bytes or even more.  
lineString = fgets(line,MAX_LENGTH,in);   

Also change

if(lineString!=NULL)  

to

if(lineString!=NUL)
Sign up to request clarification or add additional context in comments.

4 Comments

How would I allocate the memory for something like that? I'm a little confused because I need that command to read in from the file stream
Edited my answer. If this is difficult for you then simply do this: char lineString[100] = fgets(line,MAX_LENGTH,in);.
Unfortunately it didn't work, when I change the code in the function to manually assign strings to the array values, e.g. if(lcount ==1){Labels[lcount] == "one"}..and the same code for 2,3,4, etc it works perfectly fine! So strange
Still no luck, that portion of the code seems to be working, it's assigning the values to the Labels[] array that is confusing me so much.
0

Most of your problem seems to come from the term "string", which you seem to have some confusion about. This is not surprising, because the concept of "string" in the C language is somewhat nebulous, and it can mean multiple different things.

A "string" can be a string literal like "foobar", which is a sequence of characters in static memory, terminated by a null character.

A "string" can also be a character array like char foobar[SIZE];, which declares an array that can be used to hold a null terminated sequence of characters.

Alternately, a "string" be a character pointer (char *) that points at either of the above kinds of strings.

In many situations, any of the above strings may be use interchangeably. In others, the difference between them is important.

So lets look at your code and see what it does. You have:

while(BuildLabels(lineString,input,Labels,LabelVals)!=NULL)

this calls the function BuildLabels in a loop. The declaration of BuildLabels is

char * BuildLabels(char * line, FILE *in, char *Labels[], char *LabelVals[])

So the first argument is a string in the third sense. You don't show the declaration of lineString, but based on the results you report, it's probably something like

char lineString[MAX_LENGTH];

a string in the second sense.

So you declare a character array to hold a string, and then pass a pointer to that (in a loop) to BuildLabels. So in each call line will be pointing at same string array, which means that at entry it will contain the data from the previous call, and will overwrite that data with its own data.

Within BuildLabels, you call fgets(line, which reads a line into that array (remember, the same array lineString which your passing a pointer to eash time), and then strtok(line, which splits the string in place into tokens. So then when you do

Labels[lcount] = FirstToken;

you're storing a pointer into that same array into the Labels array. Labels, being an array of pointers is an array of strings in the third sense, so doesn't actually hold the characters of the string, just a pointer to some other buffer. That buffer will then be overwritten by the next call to BuildLabels, thus changing the string that the pointer in the Labels array points at. So back in main, when you go and print Labels[0] and Labels[1], it prints the characters from the buffer of the last call to BuildLables, and not the characters that were in the buffer when you did the pointer assignment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.