Linker Directives
The mikroC PRO for 8051 uses an internal algorithm to distribute objects within memory. If you need to have a variable or routine at specific predefined address, use the linker directives absolute
and org
.
Directive absolute
Directive absolute
specifies the starting address in RAM for a variable or a starting address in ROM for a constant. If the variable or constant is multi-byte, higher bytes will be stored at the consecutive locations.
Directive absolute
is appended to declaration of a variable or constant :
// Variable x will occupy 1 byte at address 0x22 : short x absolute 0x22; // Variable y will occupy 2 bytes at addresses 0x23 and 0x24 : int y absolute 0x23; // Array elements will be placed on the consecutive locations starting from 0x1000 : const short ConstantArray[] = {1,2,3} absolute 0x1000;

If you want to place simple type constant into Flash memory, instead of following declaration:
const short SimpeConstant = 0xAA absolute 0x2000;
use an array consisting of single element :
const short SimpleConstant[] = {0xAA} absolute 0x2000;
In first case, compiler will recognize your attempt, but in order to save Flash space, and boost performance, it will automatically replace all instances of this constant in code with it's literal value.
In the second case your constant will be placed in Flash in the exact location specified.
Be careful when using the absolute
directive, as you may overlap two variables by accident. For example:
// Variable i will occupy 1 byte at address 0x33 char i absolute 0x33; // Variable will occupy 4 bytes at 0x30, 0x31, 0x32, 0x33; thus, // changing i changes jjjj highest byte at the same time, and vice versa long jjjj absolute 0x30;
Directive org
Directive org
specifies a starting address of a routine in ROM. Directive org
is appended to the function definition. Directives applied to non-defining declarations will be ignored, with an appropriate warning issued by the linker.
Here is a simple example:
void func(int par) org 0x200 { // Function will start at address 0x200 asm nop; }
It is possible to use org directive with functions that are defined externally (such as library functions). Simply add org directive to function declaration:
void UART1_Write(char data) org 0x200;
Note: Directive org
can be applied to any routine except for interrupt.
Directive orgall
If the user wants to place his routines, constants, etc, above a specified address in ROM, #pragma orgall
directive should be used:
#pragma orgall 0x200
This doesn't apply to IVT, Handler table and Goto table.
Directive funcorg
You can use the #pragma funcorg
directive to specify the starting address of a routine in ROM using routine name only:
#pragma funcorg <func_name> <starting_address>
What do you think about this topic ? Send us feedback!