5
votes

I know dereferencing a null pointer is undefined - but I would like to know what happens on a specific target - an MSP430.

I don't have a board to load this on in front of me to test this out right now.

What would happen if I did this (or similar)?

int * foo = NULL;
(*foo)++; //Crash?

Location 0x0 is in the SFR range and is reserved.

Would it generate a PUC/POR? Or would it silently "work"?

The assembly generated is

;int * foo = NULL;
clr.w   R15
;(*foo)++;
inc.w   R15

So location 0x0 is literally being incremented by 1.

When I run this in the simulator I see the value at address 0x0 go from 0 to 1. I get no warnings in the debug log and the program exits normally.

I am using the IAR EW430 compiler/assembler/simulator.

1
Just so its clear, you're asking for observed behavior of undefined behavior; a tall order. This question wouldn't be here if you had the actual hardware in your mits, is that right? And even then, wouldn't it be dependent on whether an overriding interrupt hook were installed at the time of the infraction, which would be dependent on the specific moment of said-same? (or do you have complete control over all of the above?). - WhozCraig
@WhozCraig that's correct. In a nut shell I am asking if the msp430 will violently shut down when 0x0 is read from or written to or does it perniciously keep working. I can't seem to figure out what that address would contain anyway. There is an interrupt you can setup that will fire when "vacant" memory outside of the normal range is accessed, from which you can do some logging about the event but I don't think that is an option here. More or less I am asking about a big unruly legacy code base that does not use asserts or otherwise check pointer parameters in interfaces. - Nick
address 0,1 are the interrupt enable bits. Therefore incrementing address 0 from value 0 to value 1 will enable one of the interrupts. The program will keep right on running. @Nick, have you not read the architecture sheet for the msp430? The architecture specification can be found at: <transfer.cizgi.com.tr/nsaral/mcu-turkey/MSP430_egitim/…> - user3629249
Since the behavior of dereferencing a null pointer is undefined (by the C standard), a C compiler won't necessarily generate code that accesses memory at address 0x0, even if accessing that location is well defined by the CPU. (But apparently, with your code and whatever compiler and settings you're using, it happens to do so.) - Keith Thompson
@user3629249 No I had not seen that particular document before. I looked through the 5 series family user guide and saw "00000h-000FFh - Reserved for system extension" In the memory map. I should have done more homework though, because I am interested in this answer for the 5 series but also the 1 series. I am working with legacy code for both. - Nick

1 Answers

6
votes

Not only writing and reading the address 0x0 will not cause a crash or a reboot, it actually a completely legal operation that is often used by MSP430 applications.

The initial portion or MSP430 memory map is reserved for I/O ports and control registers: http://en.wikipedia.org/wiki/TI_MSP430#MSP430_address_space

In particular, the control registers at 0x0 and subsequent addresses are:

 #define IE1_                  0x0000    /* Interrupt Enable 1 */
 #define IE2_                  0x0001    /* Interrupt Enable 2 */
 #define IFG1_                 0x0002    /* Interrupt Flag 1 */
 #define IFG2_                 0x0003    /* Interrupt Flag 2 */

So for example writing zero to that memory address by dereferencing a uint8_t * or uint16_t * pointer is going to disable interrupts. Writing zero by dereferencing an uint32_t * it is also going to clear the flags. Incrementing the value of these registers does not make a lot of sense, but should be completely legal.

At least this is the case on msp430 Series 1, Series 2 and Series 4. By checking the header files I was not able to find anything mapped to 0x0 on Series 5 (the interrupt control registers are mapped to region starting from 0x0100).

So if you want to catch places in code where the NULL pointer is dereferenced, you're completely on your own.