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

Invalid mspace

Hello,

I had this appear when I tried to compile my code in C.
WARNING C196: MSPACE PROBABLY INVALID

I do know that this occurs when we try to convert a constant to a pointer constant and hence yielding an invalid memory space. An example char *p = 0x91234.

However, I was trying to store a pointer memptr into memory space 0x463 and assigning the value of 0x464 into the memptr. The code is as follows.

 void *memptr = (void *) 0x463;
 memptr = 0x464;

Please please help. Thank you.

  • ASSEMBLY LISTING of your code above:

    ; SOURCE LINE # 1
    0000 7B00 MOV R3,#00H
    0002 7A04 MOV R2,#04H
    0004 7963 MOV R1,#063H
    0006 8B00 R MOV memptr,R3
    0008 8A00 R MOV memptr+01H,R2
    000A 8900 R MOV memptr+02H,R1

    ; SOURCE LINE # 2
    000C 7B00 MOV R3,#00H
    000E 7A04 MOV R2,#04H
    0010 7964 MOV R1,#064H
    0012 8B00 R MOV memptr,R3
    0014 8A00 R MOV memptr+01H,R2
    0016 8900 R MOV memptr+02H,R1

    Is that you want?
    ______________________________________
    void * xdata memptr _at_ 0x463;
    memptr = 0x464;

  • The 8051 has many separate address spaces (code, data, xdata, idata, etc). The C language expects there to be a single address space. To cope, Keil C has different sorts of pointers. An xdata* is not the same type as a code*. "Generic" pointers, without an explicit compile-time type, are tagged with an extra byte to indicate which memory space they actually point into.

    All this makes it extremely dangerous to do the all-too-common sort of munging about with integers and casting them into pointers. It's not one flat address space, and the binary representation of pointers is not really a simple integer offset. You have to know exactly what you're doing, and exactly how the compiler represents and treats pointers. Study the manual on this topic carefully.

    Take a look at the macros in absacc.h for a start.

    I'd suggest always declaring pointers with an explicit memory space type unless you really need the generic capability for some reason. Memory model makes a difference.

    In this particular case, I expect the compiler is warning you because 0x464 is too big to point into data space (which is only 128 bytes long), yet the tag byte of that value (0) would mean that the pointer does point into data space.

    I was trying to store a pointer memptr into memory space 0x463

    If it's actually important for you to control the address at which memptr appears, you can use _at_ (as suggested), or put the variable into its own segment and use linker options. If you just slam address 0x463, how do you know there's nothing else there already? But if you insist, you need a pointer to a pointer if you want to indirectly change where a pointer points.