Page 1 of 1

Variable not asigning properly!

Posted: Sat Nov 11, 2006 8:22 am
by 0Scoder
Hi,
This problem is part of my current OS project - but since it is really not specific to OSdev, it made sense to post it here....

I have a pointer to an array of integers, the first value of which I wish to assign to a variable. For some strange reason (most likely my incompitent programming skills!) I am unable to do this!

Here's the code whittled down to avoid all the unimportant bits:

Code: Select all

void parse_request(void *place)
{
 ushort *u_place;	/*allows shorts to be read from the request*/
 ushort function;
	u_place = (ushort *)place;
	function = u_place[0];		/*read the function*/
 	if(function!=0x0001)_print("Request recieved, but with error in data (f)",0xCF,6);
}
I recieve the error message every time, except when I read directly from the array, like so:

Code: Select all

 	 if(u_place[0]!=0x0001)_print("Request recieved, but with error in data (f)",0xCF,6);
I have also checked the memory location in which the value (0x0001) should reside, and it checks out fine!

Can anyone explain to me what I am doing wrong?
Thanks in advance,
OScoder

Posted: Sat Nov 11, 2006 8:43 am
by gaf
Provided that "function" is a global variable there might be some problem with your linker-script. You could try what happends if you define the variable as local.

regards,
gaf

Posted: Sat Nov 11, 2006 12:09 pm
by 0Scoder
Provided that "function" is a global variable there might be some problem with your linker-script. You could try what happends if you define the variable as local.
Ah, it is local, just forgot to put it in my quote! Sorry - editing post now...

Posted: Sun Nov 19, 2006 4:15 am
by B.E
I can't see anything wrong with the code you provided, can I see the line that you call this function at.

Posted: Sun Nov 19, 2006 9:47 am
by 0Scoder
Ok, here's he code in full:

In Module 2 (where it happens):
=====================
function call:

Code: Select all

parse_request((void *)instream + 1 + 3);
function:

Code: Select all

void parse_request(void *place)
{
 uchar *c_place;	/*allows chars to be read from the request*/
 ushort *u_place;	/*allows shorts to be read from the request*/
 ushort function;	/*for reading the function number into*/
 uchar request[1];	/*request is two bytes at the moment*/
 /*Extract request from stream*/
	c_place = (uchar *)place;	/*initialise pointers*/
	u_place = (ushort *)place;
	function=u_place[0];		/*read the function*/
	if(u_place[1]!=1){_print("MM: Object request error",0xCF,4);return;} /*stop if the request length is wrong*/
	request[0]=c_place[4];
	request[1]=c_place[5];

 /*Process it*/
	if(request[0]=='a' && request[1]=='p' && function==0x0001)
	{
	  _print("Request  recieved",0xCF,4);
	}
	else
	{
	 if(request[0]!='a')_print("Request recieved, but with error in data (r0)",0xCF,4);
	 if(request[1]!='p')_print("Request recieved, but with error in data (r1)",0xCF,5);
 	 if(function!=0x0001)_print("Request recieved, but with error in data (f)",0xCF,6);
	 asm("ljmp 0xFFFFFFF"); /*crash - so as not to continue execution*/
	}
}
In Module 1 (the module that starts everything off):
=================================
Function call:

Code: Select all

	outstream=(unsigned short *)V_KERNEL_TO_MM_STREAM;
	request[0]='a';
	request[1]='p';
	parameters=0x7777;
	write_object_request(	(void *)outstream+4,
							0x0001,
							(unsigned char *)&request,
							(uchar *)&parameters,
							1,
							1);
	outstream[0]=4+4+6;
Filling Function:
==========

Code: Select all

void write_object_request(	void *place,		/*where the request is written to*/
							unsigned short function,	/*function no. to activate*/
							unsigned char *request,		/*object requested (in object request format)*/
							unsigned char *parameters,	/*parameters to be passed*/
							unsigned short request_size,/*in bytes*/
							unsigned short parameters_size)	/**/
{
 unsigned char *c_place;	/*allows chars to be written to the request*/
 unsigned short *u_place;	/*allows shorts to be written to the request*/
 unsigned long i;
 /*Initialise pointers*/
	c_place = (unsigned char *)place;
	u_place = (unsigned short *)place;
 /*Write the function*/
	u_place[0]=function;
 /*Write the object request:*/
	u_place[1]=request_size;
	for(i=0; i<=(request_size); i++)
	 c_place[i+4]=request[i];
}
--------------------------------------------------
Explanation:
- The instream of module 2 and outstream of module 1 are identical memory locations.
- The memory location at which the data being written and read should contain: function number [2 bytes], object name length [2 bytes], object name [1 bytes * length].
- This has been checked and shown correct using the bochs debugger checking both physical and virtual memory locations.
- The two request bytes are read fine by module 2
- The function number is correct when read directly from the stream, as in the following code formulates correctly (shortend):

Code: Select all

if(u_place[0]!=0x0001) _print("error");
- However, the following (shortend) does not formulate correctly:

Code: Select all

function=u_place[0];
if(function!=0x0001) _print("error");
As you can understand, I am completely confuzled as to why this doesn't work!

Thanks,
OScoder

P.S The memory being read off contains the following:

Code: Select all

0x0001000100007061
EDIT:
Ugh, this really makes no sense, but the following code does not work either. I'm guessing that in one of the if stements I'm assigning something by accident, but how I cannot guess!:

Code: Select all

void parse_request(void *place)
{
 uchar *c_place;	/*allows chars to be read from the request*/
 ushort *u_place;	/*allows shorts to be read from the request*/
 uchar request[1];	/*request is two bytes at the moment*/
 /*Extract request from stream*/
	c_place = (uchar *)place;	/*initialise pointers*/
	u_place = (ushort *)place;
	if(u_place[1]!=1){_print("MM: Object request error",0xCF,4);return;} /*stop if the request length is wrong*/
	request[0]=c_place[4];
	request[1]=c_place[5];

 /*Process it*/
	if(request[0]=='a' && request[1]=='p' && u_place[0]==1)
	{
	  _print("Request  recieved",0xCF,4);
	}
	else
	{
	 if(request[0]!='a')_print("Request recieved, but with error in data (r0)",0xCF,4);
	 if(request[1]!='p')_print("Request recieved, but with error in data (r1)",0xCF,5);
 	 if(u_place[0]!=1)_print("Request recieved, but with error in data (f)",0xCF,6);
	 asm("ljmp 0xFFFFFFF");
	}
}

Posted: Sun Nov 19, 2006 5:48 pm
by B.E
OK, Your writting past the end of the array. So change this

Code: Select all

uchar request[1];   /*request is two bytes at the moment*/

To

Code: Select all

uchar request[2];   /*request is two bytes at the moment*/
Also about your coding style. I would recommand that you use a defined structure(i.e defining a type with the struct keyword), this will both increase readablity and also minimize mistakes like these.

Posted: Mon Nov 20, 2006 1:34 pm
by 0Scoder
Hi,
Thanks for the help - it runs perfectly now! (the array size was the problem). Maybe we should have a 'read before posting' thread that reminds people to look for common problems like this (I thought the array size started from 0)?
Also about your coding style. I would recommand that you use a defined structure(i.e defining a type with the struct keyword), this will both increase readablity and also minimize mistakes like these.
I'll try. In this situation the length of things is too variable, but I'll try to for the more fixed of things...

Thanks again,
OScoder

Posted: Mon Nov 20, 2006 2:14 pm
by Midas
0Scoder wrote: (I thought the array size started from 0)
The array indices are 0-based, yes. However, when you're declaring it, the size is the length of the array.

Code: Select all

int myarray[1]; // An 'array' of 1 int in length
myarray[0] = 2; // Okay
myarray[1] = 3; // Past the end of the array
So if I declare an array of size five (int myarray[5]) then the minimum index is 0 (myarray[0]), and the maximum 4 (myarray[4]).