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.

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

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

Children
No data