This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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?

Parents
  • 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

Reply
  • 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

Children
  • "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.

  • 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

  • "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;