Search code examples
assemblyarmkeilarm7

Why does STR only work for addresses between 0x40000000 and 0x40003FFF?


Code:

dest EQU 0x40000000

AREA name, CODE, READONLY

ENTRY

MOV r0, #2  
LDR r1, =dest   
STR r0, [r1]    
stop B stop

END

This code writes the value of 2 to memory location 0x40000000. When I change this to 0x20000000, 2 fails to get written there. Same thing with 0x3FFFFFFF. When I set the memory location to 0x40003FFF, 2 gets printed onto that location, but when I change the address to 0x40004000, 2 fails to get printed there. Same thing for any address locations higher, like 0x50000000. So according to these outputs, it seems like STR only writes values onto a finite range of memory between 0x40000000 and 0x40003FFF.

Does anyone know why this is the case? Or is there something wrong with my code? I am using Keil uVision5, NXP LPC2140.


Solution

  • I couldn't find a datasheet for "LPC2140", but I found a datasheet for what appears to be a family of devices instead, and that the specific one you have could be LPC2142/2144. The datasheet, section 6.4, shows that SRAM is mapped to 0x40000000-0x40003FFF (assuming from what you've said that you have the 16 kB SRAM variant). That's the only address space you should be treating as general purpose RAM. Everything outside that range according to the datasheet looks scary and you should avoid it unless you fully know what you're doing.

    One thing you should also be cognizant of is unaligned access. STR writes a full word at once (4 bytes) and so the address should be aligned on a word boundary. 0x40003FFF is not aligned to a 4-byte boundary; you should have been writing to 0x40003FFC instead. If you just wanted to write a single byte to 0x40003FFF, you should have used STRB instead.