This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: efficient memory access from assembly
- To: "Jeger, Tobias" <tobias dot jeger at intersil dot com>
- Subject: Re: efficient memory access from assembly
- From: Nick Clifton <nickc at redhat dot com>
- Date: 20 Feb 2001 14:13:13 -0800
- Cc: binutils at sources dot redhat dot com, rearnshaw at cambridge dot arm dot com
- References: <200102201119.LAA19178@cam-mail2.cambridge.arm.com>
Hi Tobias,
> I am currently porting code (both C and assembler) from the ARM toolkit to the
> GNU GCC environment. Reading through the documentation of GCC, I can't figure
> out how to port register relative memory access instructions without duplicating
> information. So what I have is a (relocatable) area of data storage, where space
> is allocated for a number of variables.
> Having the base-address of this area in a register (say r5), I would like to be
> able to perform accesses of the kind
>
> ldr r1, [r5, #<variablename>]
>
> so <variablename> must be the offset from the base-address. The location of the
> code accessing the variables must be completely independent from the area where
> the variables are stored at assembly-time, and the variables need to be
> accessible to code in different files. Must this be done using {absolute}
> addresses, which overlap at link-time, or does anybody have a better idea?
If you are using assembler source code, then you should be able to do
this using symbol arithmetic. For example:
.text
foo:
ldr r5, =start_of_data_block
ldr r1, [r5, # (variable_in_data_block - start_of_data_block)]
.data
start_of_data_block:
.word 1, 2, 3, 4
variable_in_data_block:
.word 5
If you are using C then you *might* be achieve the same kind of thing
by making your base register a fixed register (ie compile with
-ffixed-r5) and then making use of assembler aliases, like this:
typedef struct
{
int field1;
int field2;
int field3;
} data_block;
volatile register data_block * base_address asm ("r5");
int foo (void) // Returns 'field3' from data block
{
return base_address->field3;
}
Of course you would have to make sure that there is code to initialise
r5 to the correct value somewhere.
Cheers
Nick