5.9.9. Avoiding problems with MAP and # directives

Using MAP and # directives can help you to produce maintainable data structures. However, this is only true if the order the elements are placed in memory is not important to either the programmer or the program.

You can have problems if you load or store multiple elements of a structure in a single instruction. These problems arise in operations such as:

These operations require the data elements in the structure to be contiguous in memory, and to be in a specific order. If the order of the elements is changed, or a new element is added, the program is broken in a way that cannot be detected by the assembler.

There are a number methods for avoiding problems such as this.

Example 5.27 shows a sample structure.

Example 5.27. 

MiscBase				RN		r10
				MAP		0,MiscBase
MiscStart				#		0
Misc_a				#		1
Misc_b				#		1
Misc_c				#		1
Misc_d				#		1
MiscEndOfChars				#		0
MiscPadding				#		(-:INDEX:MiscEndOfChars) :AND: 3
Misc_I				#		4 
Misc_J				#		4
Misc_K				#		4
Misc_data				#		4*20
MiscEnd				#		0
MiscLen				EQU		MiscEnd-MiscStart

There is no problem in using LDM/STM instructions for accessing single data elements that are larger than a word (for example, arrays). An example of this is the 20-word element Misc_data. It could be accessed as follows:

ArrayBase			RN		R9
			ADR		ArrayBase, MiscBase
			LDMIA		ArrayBase, {R0-R5}

This example loads the first six items in the array Misc_data. The array is a single element and therefore covers contiguous memory locations. It is unlikely that in the future anyone will split it into separate arrays.

However, for the case of loading Misc_I, Misc_J, and Misc_K into registers r0, r1, and r2 the following would work, but could cause problems in the future:

ArrayBase			RN		R9
			ADR		ArrayBase, Misc_I
			LDMIA		ArrayBase, {R0-R2}

Problems arise if the order of Misc_I, Misc_J, and Misc_K is changed, or if a new element Misc_New is added in the middle. Either of these small changes breaks the code.

If these elements need to be accessed separately elsewhere, so you do not want to amalgamate them into a single array element, you must amend the code. The first remedy is to comment the structure to prevent changes affecting this area:

Misc_I			#		4  		;  ==} Do not split/reorder
Misc_J			#		4  		;    } these 3 elements, STM 
Misc_K			#		4  		;  ==} and LDM instructions used.

If the code is strongly commented, no deliberate changes are likely to be made that would affect the workings of the program. Unfortunately, mistakes can still occur. A second method of catching these problems would be to add ASSERT directives just before the STM/LDM instructions to check that the labels are consecutive and in the correct order:

ArrayBase			RN		R9
							; Check that the structure elements
							; are correctly ordered for LDM
	ASSERT		(((Misc_J-Misc_I) = 4) :LAND: ((Misc_K-Misc_J) = 4)) 
			ADR		ArrayBase, Misc_I
			LDMIA		ArrayBase, {R0-R2}

This ASSERT directive stops assembly at this point if the structure is not in the correct order to be loaded with an LDM. Remember that the element with the lowest address is always loaded from, or stored to, the lowest numbered register.

Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0040D