I tried to write a simple program that can find the 1's complement of a number and store the result in memory.
This is my program:
;Find the one's complement (inverse) of a number TTL Ch4Ex2 - invert AREA Program, CODE, READONLY ENTRY Main LDR R1, Value ; Load the number to be complemented MVN R1, R1 ; take 1's complement of R1 STR R1, Result ; Store the result SWI &11 Value DCD &FF ; Value to be complemented Result DCD &ABCD1234 ; Storage for result END
When I ran the debugger, I used "Memory 1" window to check the content of Result. But the content of Result didn't change. It kept remained as 0xABCD1234. Can anybody tell me what did I do wrong here?
I am using Keil uVision4 and LPC2368 as my device.
Thank you, Khai
Hmm
* Cached memory enabled...? * Periodic windows update not enabled...?
Thanks Tamir. I enabled Periodic Windows Update, but it didn't fix the problem. Can you tell me how to enable cached memory? Thanks.
options for target->debug->cache option
not sure this is your problem, but you can try.
I enabled Cache Memory but still it didn't fix the problem. Maybe the way I declared my variable Result is wrong. Is there another way of declaring a variable beside using DCD directive?
You've specified the code and data as being within a READONLY area and then you're trying to write a value to something in that READONLY area.
Thanks IB Shy. I changed READONLY to READWRITE, but the compiler gave me the following error message:
Build target 'Target 1' assembling One_compl_main.asm... linking... proj.axf: Error: L6206E: Entry point (0x00000000) lies outside the image. Target not created
I don't understand why I am getting this message.
Normally, you would put the code in a READONLY area and the data in a READWRITE area.
Something like this:
;Find the one's complement (inverse) of a number TTL Ch4Ex2 - invert AREA Program, CODE, READONLY ENTRY Main LDR R0,=Value ; Load the number to be complemented LDR R1,[R0] ; MVN R1, R1 ;take 1's complement of R1 LDR R0,=Result ; Store the result STR R1, [R0] ; SWI &11 AREA Data, DATA Value DCD &FF ; Value to be complemented Result DCD &ABCD1234 ; Storage for result END
Sorry, I don't have the time to assemble this to fully check it. But I hope it's enough to give you the idea.
Thanks IB Shy. The code is compiled with no error. And the debugger's memory window also showed the change in the content of location Result. However, there is one problem. The contents of Value and Result are initialized to 0 instead of 0xFF and 0xABCD1234. Could you tell me why it happened like that?
Initialised data in the data segments would normally be filled with the initialisation values as part of the startup.
When using C, this would typically occur as part of the startup code prior to the call of main. On Keil's MDK it is usually done by some code automagically added by the linker - This data initialisation process is referred to as scatter loading.
Are you using your own startup code? If you are, then you must ensure that the initialisation values of data are set by that code.
No I didn't use any startup code. I guess maybe that's why the contents weren't initialized correctly. However I tried to manually initialize the contents by adding the following code at the beginning of the program that you gave me:
LDR R0,=Value MOV R1,#0xFF STR R1,[R0] LDR R0,=Result MOV R1,#0xABCD1234 STR R1,[R0]
But then I got an error message like this:
Build target 'Target 1' assembling One_compl_main.asm... One_compl_main.asm(14): error: A1510E: Immediate 0xABCD1234 cannot be represented by 0-255 and a rotation Target not created
Could you tell me why I got this error message? I thought registers in the ARM are 32-bit long. Why did it say "cannot be represented by 0-255"?
You need to look at your ARM reference guide for details on that one.
Esentially, the immediate data is contained within the instruction itself. The instruction and data fit into a 32 bit wide instruction - there are only a small proportion of those bits available for the immediate data.
The following should work:
LDR R0,=Value MOV R1,#0xFF ; You can leave alone (data fits into instruction) STR R1,[R0] LDR R0,=Result MOV R1,=0xABCD1234 ; Use a pseudo-op STR R1,[R0]