views:

95

answers:

2

I'm having difficulty using reinterpret_cast. Lets just say right off the bat that I'm not married ot reinterpret_cast. Feel free to suggest major changes. Before I show you my code I'll let you know what I'm trying to do.

I'm trying to get a filename from a vector full of data being used by a MIPS I processor I designed. Basically what I do is compile a binary from a test program for my processor, dump all the hex's from the binary into a vector in my c++ program, convert all of those hex's to decimal integers and store them in a DataMemory vector which is the data memory unit for my processor. I also have instruction memory. So When my processor runs a SYSCALL instruction such as "Open File" my C++ operating system emulator receives a pointer to the beginning of the filename in my data memory. So keep in mind that data memory is full of ints, strings, globals, locals, all sorts of stuff. When I'm told where the filename starts I do the following:

Convert the whole decimal integer element that is being pointed to to its ASCII character representation, and then search from left to right to see if the string terminates, if not then just load each character consecutively into a "filename" string. Do this until termination of the string in memory and then store filename in a table. My difficulty is generating filename from my memory.

Here is an example of what I'm trying to do:

C++ Syntax (Toggle Plain Text)

   1.Index Vector     NewVector   ASCII    filename
   2.0     240faef0   128123792   'abc7'   'a'
   3.0     240faef0   128123792   'abc7'   'ab'
   4.0     240faef0   128123792   'abc7'   'abc'
   5.0     240faef0   128123792   'abc7'   'abc7'
   6.1     1234567a   243225      'k2s0'   'abc7k'
   7.1     1234567a   243225      'k2s0'   'abc7k2'
   8.1     1234567a   243225      'k2s0'   'abc7k2s'
   9.            //EXIT LOOP//
  10.1     1234567a   243225      'k2s0'   'abc7k2s'

Here is the code that I've written so far to get filename (I'm just applying this to element 1000 of my DataMemory vector to test functionality. 1000 is arbitrary.): C++ Syntax (Toggle Plain Text)

   1.int i = 0;
   2.int step = 1000;//top->a0;
   3.string filename;
   4.char *temp = reinterpret_cast<char*>( DataMemory[1000] );//convert to char
   5.cout << "a0:" << top->a0 << endl;//pointer supplied
   6.cout << "Data:" << DataMemory[top->a0] << endl;//my vector at pointed to location
   7.cout << "Data(1000):" << DataMemory[1000] << endl;//the element I'm testing
   8.cout << "Characters:" << &temp << endl;//my temporary char array
   9.
  10.while(&temp[i]!=0)
  11.{
  12.     filename+=temp[i];//add most recent non-terminated character to string
  13.     i++;
  14.     if(i==4)//when 4 characters have been added..
  15.     {
  16.          i=0;
  17.          step+=1;//restart loop at the next element in DataMemory
  18.          temp = reinterpret_cast<char*>( DataMemory[step] );
  19.     }
  20. }
  21. cout << "Filename:" << filename << endl;

So the issue is that when I do the conversion of my decimal element to a char array I assume that 8 hex #'s will give me 4 characters. Why isn't this this case? Here is my output:

C++ Syntax (Toggle Plain Text)

   1.a0:0
   2.Data:0
   3.Data(1000):4428576
   4.Characters:0x7fff5fbff128
   5.Segmentation fault
A: 
Krumelur
Dan Snyder
The DataMemory structure is a bit confusing. Just think of it as everything in a program that isn't instructions, including stack, heap, and static data. I took those sections of a binary file and loaded them into my DataMemory vector. Now my processor has access to all of the static data required and it has a place to put results. At steady state I just have a bunch of constants and filenames and addresses in my data vector to be used later by the program I will run on my processor.
Dan Snyder
I think that Maybe I made the problem seem bigger than it is. Here is what I'm trying to do:HEX(41424344) = DEC(1094861636) = ASCII('A','B','C','D')I have the HEX to DEC part down fine but I can't quite figure out how to do the second part. I've tried using reinterpret_cast with many issues. Any Simple solutions to this problem?
Dan Snyder
I see what you mean. But then, isn't the problem that you *dereference* the DataMemory (line 18), and then cast it into a *pointer* to a char? What about something like temp = reinterpret_cast<char*>( DataMemory+step ); ?
Krumelur
Or, on second thought, is DataMemory some kind of pointer array?
Krumelur
A: 

Sorry, but the code is mess. If you want to print raw data, then you need to realize that the nul-char is actually zero, which is a very common value in raw data.

Printing a raw string will therefore most likely end prematurely, because a nul-char will be found.

As already mentioned, the test should probably be while(temp[i] != 0) and not while(&temp[i] != 0) which will never be false because address of any memory location (outside of kernel) is != 0.

Let_Me_Be
That's perfectly okay. This isn't really my specialty so any help is appreciated. I'll follow the previous advice to change my test. Also, it's assumed that the MIPS ISA will take care of terminating the string at the correct location. I guess the main section I'm stuck on is converting the decimal value contained in a single element to it's ASCII representation and inserting that into some sort of testable array. Is that possible?
Dan Snyder
Strings (C strings - char*) are terminated with the first nul-char. That's the standard definition. If you have a compiler that follows the C/C++ standards, he will interpret C strings in this manner (actually its the compilers job to make all platforms look identical from the code point of view).Well, ASCII representation of data, that isn't very clear. If you want to do ASCII mapping for printable data, then you have to filter out the non-printable - see `ctype.h` (in C) / `cctype` (in C++)
Let_Me_Be
I'm a bit confused by what you mean by "with the first nul-char". Say my string is "abcd" and in my vector, will it not be represented by 'a','b','c','d','/0' ?
Dan Snyder
From the code it seems, that you are not trying to print just some plaintext. It seems like integers and other raw data. If you are printing just plaintext (filename), then I really don't get the DataMemory variable (and why are you reinterpret casting it).Maybe you should provide more information.
Let_Me_Be
Well, DataMemory is the memory for my MIPS processor. What this means is that it contains not only compile time information generated by a compiler (say we need to use "PI" in a program, so the compiler will place this constant in a register (or a vector element) in my case. The same thing holds for filenames. If the program requires access to a file such as stdout or something like that, the filename must be available for the syscal to access said file. The compiler will place "stdout" in DataMemory at startup. This means DataMemory could have [instruction][constant][filename][instruction]
Dan Snyder
I still don't understand what DataMemory is (what type?), but anyway, drop the reinterpret cast and simply do `char value = static_cast<char>(DataMemory[value_location]);` Do this while `value` is printable -> `isprint` from `cctype` / `ctype.h`
Let_Me_Be