Discussion Forum

what is the matter with the pointer?

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Nantian Gumo
Posted
15-Mar-2005 08:18 GMT
Toolset
C51
New! what is the matter with the pointer?
hello all!

*.h
void Baudrate(unsigned int *ptr,unsigned char Uart_num) large;

*.c

void main(void)
{
...
*ptr = 1152;
Baudrate(ptr,1);
...
}
In the routine ,the var Baud( Baud = *ptr; )is not 1152 but 0x00.When changing the defintion : void Baudrate(unsigned int pp,unsigned char Uart_num) large;,and be called : Baudrate(1152,1);,the routine run well.
What is the wrong?
Read-Only
Author
A.W. Neil
Posted
15-Mar-2005 09:15 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
Where's your definition of ptr?
Read-Only
Author
Nantian Gumo
Posted
15-Mar-2005 13:57 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
The pointer is defined in the main.c as "unsigned int *ptr;".
*.c:

void main(void)
{ ...
unsigned int *ptr;
...
*ptr = 1152;
Baudrate(ptr,1);
...
}
Read-Only
Author
Hans-Bernhard Broeker
Posted
15-Mar-2005 14:17 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
Please distill this down to a complete, self-contained, compilable example case. Nobody can diagnose what's going wrong from a loose collection of snippets ripped from their context like the one you've decided to show, so far.

For starters, your 'ptr' currently points nowhere. That's bad.

Furthermore the observed behaviour could easily happen if the source file containing your 'main' didn't actually #include the header containing the prototype for Baudrate(), or if the prototype were #ifdef'ed out of sight, or if the actual definition of Baudrate (in some other .c file?) didn't agree with the prototype declaration.
Read-Only
Author
Drew Davis
Posted
15-Mar-2005 18:23 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
As Hans says, ptr in main() is uninitialized. It could point anywhere, including an address where there is no RAM to store a value. Odds are, a garbage pointer happens to point to zero.

Perhaps the ellipsis hides the initialization.

There's no real reason to pass by reference in this case. Stylistically, I'd write

U16 GetBaudRate (U8 uartNumber);

This will also lead to smaller and faster code, particularly compared to using the 3-byte generic pointer to pass a 2-byte int.

The "large" qualifier on the function makes me wonder. If this keyword changes the default pointer type for the parameter, and the caller is using a different memory model, the parameter might be confused without an explicit cast. But I'm feeling too lazy to test this hypothesis right now.
Read-Only
Author
Oleg Sergeev
Posted
16-Mar-2005 07:10 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
hi,
here is a small example which could help you to see what is wrong. Please note that this is for "classic" C; for Keil please read notes below.
void main(void)
{

// Next line allocates memory where pointer is placed in.
// Depend on compiler it may take different number of bytes.
// Please note that this does not hold any value,
// This just reserves a couple of bytes for pointer
unsigned int *ptr;


// Next line initializes the pointer.
     ptr = 0x1111;
// Now the pointer points to the memory location 0x1111.


// Here we load value 0x2222 in memory at address 0x1111.
     *ptr = 0x2222;
// Depend on compiler and memory model
// this loads two or four (or?) bytes in
// sequential memory locations 0x1111, 0x1112, ...
}

Now about Keil.
Generally, it is very bad idea to use pointer to undefined data/memory types.
For example, when you type:
unsigned int *ptr;
then compiler does not know to which memory the pointer points in. Compiler then tries internal function C?ISTPTR which cannot recognize memory type and may (by my tests) truncate pointer/value and produce total wrong code even without any warning!
So the correct syntax should be:
unsigned int xdata *ptr;
unsigned int idata *ptr;
etc

With this way you notice compiler that the pointer points into xdata, idata etc memory segment. Now compiler has no problems and produces short, fast and correct code.
By the way, it is important that you understand syntax right. For example, next two lines produce total different code:
unsigned int xdata *ptr;
xdata unsigned int *ptr;
First line asks compiler to create a pointer which points into xdata memory. Second line just tells compiler that a pointer must be placed inside xdata memory.
Finally, to confuse you completely, answer what does next line do yourself:
idata unsigned int xdata *ptr;

Regards,
Oleg
Read-Only
Author
Stefan Duncanson
Posted
16-Mar-2005 09:34 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
"unsigned int xdata *ptr;
xdata unsigned int *ptr;"

I believe the second example is obsolete syntax supported for backward compatibility. The new way of doing things is:

char xdata * data ptr;

Which is a pointer located in data space pointing to a char in xdata space. I think this makes things a bit easier as you only have to remember that the qualifier to the left of the '*' specifies the location of the object being pointed to and the qualifier to the right of the '*' specifies the location of the pointer.

"Finally, to confuse you completely, answer what does next line do yourself:

idata unsigned int xdata *ptr;"

Yes, well, quite.
Read-Only
Author
Oleg Sergeev
Posted
16-Mar-2005 12:27 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
hi,

I just compiled next example:
#include <reg51.h>

void main(void)
{
idata char xdata *ptr;

	ptr = 0x11;
	*ptr = 0x22;
	while (1);
}
The result assembly code is:
; ptr = 0x11;
MOV      R0,#0x08
MOV      @R0,#0x00
INC      R0
MOV      @R0,#0x11
; *ptr = 0x22;
DEC      R0
MOV      A,@R0
MOV      R6,A
INC      R0
MOV      A,@R0
MOV      DPL,A
MOV      DPH,R6
MOV      A,#0x22
MOVX     @DPTR,A
This shows that pointer is placed inside idata memory and points to xdata memory.

Regards,
Oleg
Read-Only
Author
Stefan Duncanson
Posted
16-Mar-2005 13:45 GMT
Toolset
C51
New! RE: what is the matter with the pointer?
"This shows that pointer is placed inside idata memory and points to xdata memory."

Sorry, I should have explained that. I didn't realise it was a question. The correct syntax would be:

char xdata * idata ptr;

Next Thread | Thread List | Previous Thread Start a Thread | Settings