Allocation of Variables at Absolute Address in RAM

Question: How do I allocate variables at absolute address in RAM?



There are three options by which variables may be placed in absolute address in RAM.


Option-A: Using the #pragma directive:

Let us say, we need to allocate a variable ‘myByte’ at an address 0x78 in RAM and another variable ‘myByte1’ at address 0x104 , then the process would be:

1. Declare a custom area in RAM using the ‘#pragma data’ directive and declare the variable under this area:

#pragma data: MyAbsArea
BYTE myByte;

#pragma data: MyAbsArea1
BYTE myByte1;

‘MyAbsArea’ and ‘MyAbsArea1’ can be any user defined name.

2. Create a file called ‘custom.lkp’ in the project folder with the following lines:



1. After defining variables in the custom areas, before starting the code, remember to use the “#pragma data: data” instruction before starting the main code.

2. The variable allocation to the absolute addresses may be verified by checking the map file (.mp).  In the map file, the address of these variables are shown as below.

Area                               Addr   Size   Decimal Bytes (Attributes)
--------------------------------   ----   ----   ------- ----- ------------
                       MyAbsArea   0078   0001 =      1. bytes (rel,con,ram)

       Addr  Global Symbol
      -----  --------------------------------
       0078  _myByte
       0079  __MyAbsArea_end

Area                               Addr   Size   Decimal Bytes (Attributes)
--------------------------------   ----   ----   ------- ----- ------------
                      MyAbsArea1   0104   0001 =      1. bytes (rel,con,ram)

       Addr  Global Symbol
      -----  --------------------------------
       0104  _myByte1
       0105  __ramareas_end
       0105  __MyAbsArea1_end

The two custom areas are shown towards the end of the .mp file.

User Base Address Definitions

lit = 0x150
data = 0x0
MyAbsArea = 0x78
MyAbsArea1 = 0x104

3. For devices with 256 Byte RAM, the variables can be placed at any desired address in the RAM. For parts with greater than 256 Bytes RAM, there is a limitation where the Absolute area can be placed . The RAM is organized in multiple pages of 256 Bytes  each.  The minimum address at which the area starts should be the page boundary minus the total size of the variables under the area.  For example, if we place 5 bytes under MyAbsArea and 15 bytes under MyAbsArea1, then the minimum starting address becomes  0x00FA[0x00FF-5] and 0x01F0[0x01FF – 15 ] respectively. Note that for ‘MyAbsArea’ , the starting address can range from 0x00FA to 0x00FF and for ‘MyAbsArea1’ , it is from 0x01F0 to 0x01FF . In the figure below , the crossed area shows the Allowed address range :

Apart  from this range , a starting address of 0x0000 is also permitted.  Any starting address outside this range throws an error:

The compiler has failed an internal consistency check. This may be due to incorrect input or an internal error.”

The logic is that the absolute areas  can be either at the beginning of a page or towards the end , but it cannot be midway . The same applies for option B below.

Option – B: Declaring the Absolute area in a separate .asm file:

For the same requirement as in case A : declaring a variable ‘myByte’ at 0x0078  and ‘myByte1’ at 0x0104 , the procedure here would be :

1. Create a new assembly file, say ‘variable.asm’ and add the following code:

export _myByte
export _myByte1

AREA MyAbsArea (RAM)
 _myByte:BLK 1

AREA MyAbsArea1(RAM)
 _myByte1:BLK 1

Note that the ‘export’ keyword makes the variable global and the underscore ‘_’  before the variable name makes it accessible from a ‘C’ file.  In the ‘C’ file, declare the variable with the extern keyword, without the underscore:

extern BYTE myByte;
extern BYTE myByte1;

2. Create a custom.lkp file similar as in case A , with the following lines :


Note :

1. Another way to make the variable global and accessible from ‘C’ file is to use the following syntax :

_myByte1::BLK 1

Note the leading underscore and the double colon. The double colon makes the variable global and the underscore makes it accessible from C. In this case, the declaration with the export keyword is not required.

Option – C:  Assembly language

Here, we have to declare an absolute area in RAM with the attributes - RAM, ABS, CON and this area needs to originate from the required address. Then the variables can be placed under this area. For example, let’s say, if  we need a variable ‘myByte’ at address 0x74 in RAM, the syntax would be:

AREA myAbsArea( RAM, ABS, CON)
ORG 74h
myByte: BLK 1


1.The custom.lkp file is not required in this case .

2. After declaring this area in RAM, before writing program code, use the ‘area text (ROM)’ to start the code.

Options A and B apply for the ImageCraft compiler.  In HiTech compiler, a variable may be placed in an absolute location by using the following syntax.

variable_type variable_name @ address

For example to place an BYTE variable named myByte at address 0x78 :

unsigned BYTE myByte@ 0x78;

Find attached 3 projects where the above methods have been implemented :
1.RAM_var_pragma_1 : option A .
2.RAM_Var_MyAbsArea : option B.
3.RAM_Var_Assembly_1 :option C.