[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
3.17.4.1 EIND
and Devices with more than 128 Ki Bytes of Flash
Pointers in the implementation are 16 bits wide. The address of a function or label is represented as word address so that indirect jumps and calls can target any code address in the range of 64 Ki words.
In order to facilitate indirect jump on devices with more than 128 Ki
bytes of program memory space, there is a special function register called
EIND
that serves as most significant part of the target address
when EICALL
or EIJMP
instructions are used.
Indirect jumps and calls on these devices are handled as follows by the compiler and are subject to some limitations:
-
The compiler never sets
EIND
. -
The compiler uses
EIND
implicitely inEICALL
/EIJMP
instructions or might readEIND
directly in order to emulate an indirect call/jump by means of aRET
instruction. -
The compiler assumes that
EIND
never changes during the startup code or during the application. In particular,EIND
is not saved/restored in function or interrupt service routine prologue/epilogue. - For indirect calls to functions and computed goto, the linker generates stubs. Stubs are jump pads sometimes also called trampolines. Thus, the indirect call/jump jumps to such a stub. The stub contains a direct jump to the desired address.
-
Linker relaxation must be turned on so that the linker will generate
the stubs correctly an all situaltion. See the compiler option
-mrelax
and the linler option--relax
. There are corner cases where the linker is supposed to generate stubs but aborts without relaxation and without a helpful error message. -
The default linker script is arranged for code with
EIND = 0
. If code is supposed to work for a setup withEIND != 0
, a custom linker script has to be used in order to place the sections whose name start with.trampolines
into the segment whereEIND
points to. -
The startup code from libgcc never sets
EIND
. Notice that startup code is a blend of code from libgcc and AVR-LibC. For the impact of AVR-LibC onEIND
, see the http://nongnu.org/avr-libc/user-manual/">AVR-LibC user manual. -
It is legitimate for user-specific startup code to set up
EIND
early, for example by means of initialization code located in section.init3
. Such code runs prior to general startup code that initializes RAM and calls constructors, but after the bit of startup code from AVR-LibC that setsEIND
to the segment where the vector table is located.#include <avr/io.h> static void __attribute__((section(".init3"),naked,used,no_instrument_function)) init3_set_eind (void) { __asm volatile ("ldi r24,pm_hh8(__trampolines_start)\n\t" "out %i0,r24" :: "n" (&EIND) : "r24","memory"); }
The
__trampolines_start
symbol is defined in the linker script. -
Stubs are generated automatically by the linker if
the following two conditions are met:
- - The address of a label is taken by means of the
gs
modifier (short for generate stubs) like so:LDI r24, lo8(gs(func)) LDI r25, hi8(gs(func))
- - The final location of that label is in a code segment outside the segment where the stubs are located.
- - The address of a label is taken by means of the
-
The compiler emits such
gs
modifiers for code labels in the following situations:- - Taking address of a function or code label.
- - Computed goto.
- - If prologue-save function is used, see ‘-mcall-prologues’ command-line option.
- - Switch/case dispatch tables. If you do not want such dispatch tables you can specify the ‘-fno-jump-tables’ command-line option.
- - C and C++ constructors/destructors called during startup/shutdown.
- - If the tools hit a
gs()
modifier explained above.
-
Jumping to non-symbolic addresses like so is not supported:
int main (void) { /* Call function at word address 0x2 */ return ((int(*)(void)) 0x2)(); }
Instead, a stub has to be set up, i.e. the function has to be called through a symbol (
func_4
in the example):int main (void) { extern int func_4 (void); /* Call function at byte address 0x4 */ return func_4(); }
and the application be linked with
-Wl,--defsym,func_4=0x4
. Alternatively,func_4
can be defined in the linker script.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on October 19, 2013 using texi2html 5.0.