2012-04-10 23 views
8

Ho iniziato di recente la programmazione degli assemblatori per i nuclei delle braccia. Le mie prime piccole demo, solo con la sezione .text, sono state eseguite senza problemi.lo spostamento interno non è stato corretto

Come estensione logica ho voluto strutturare il codice assembler nelle solite sezioni: .text, .data, .bss.

Così ho scritto il seguente programma semplice:

.globl _start 

.section .text 

_start: 
    b main 
    b . 
    b . 
    b . 
    b . 
    b . 
    b . 
    b . 


main: 
    ldr r0, x 
    nop 

.section .data 

x: .word 0xf0f0f0f0 

.end 

Ma

/opt/arm/bin/arm-as -ggdb -mcpu=arm7tdmi demo.s -o demo.o 

uscite con l'errore

prog.s: Assembler messages: 
prog.s:17: Error: internal_relocation (type: OFFSET_IMM) not fixed up 
make: *** [prog.o] Error 1 

non ho alcun indizio perché l'assemblatore lamenta delocalizzazione, perché ho pensato che fosse il compito del linker. Potrei immaginare di dover dire all'assemblatore che la mia sezione dati non si trova nella posizione di memoria finale in fase di montaggio, ma non riesco a trovare nulla di correlato.

Sebbene ho trovato un modo per ottenere il codice assemblato correttamente, sostituendo

.section .data 

da

.org . 

che non è una soluzione soddisfacente. Soprattutto in considerazione del fatto che la documentazione del gas evidenzia il senso di questa sezione.

Forse qualcuno di voi esperti può aiutarmi a guadagnare un po 'di saggezza

risposta

13

Sembra che l'unico modo per farlo è quello di afferrare l'indirizzo della variabile e caricare un valore da quell'indirizzo.

ldr r1,=x ; get address of x 
ldr r0,[r1] ; load from that address 

In un certo senso, anche questo ha un senso. Dopo tutto, cosa succede se l'indirizzo di x (dopo il collegamento) è troppo lontano per un accesso relativo al PC? Dato che il compilatore (che non esegue il collegamento) non sa quanto la sezione dei dati possa essere lontana dalla sezione di testo, rifiuta di compilare quel codice nel caso in cui non fosse raggiungibile.

Utilizzando questo modo indiretto di accesso a una variabile, è garantito che la variabile sia raggiungibile (o almeno il compilatore può essere sicuro che la variabile sia raggiungibile o meno).

Codice adattato da http://www.zap.org.au/elec2041-cdrom/examples/intro/pseudo.s

+0

Grazie per la tua spiegazione e l'esempio. Questo o qualcosa di simile dovrebbe andare nella sezione arm della documentazione binutils. Memorizzerò che il linker fa la grande scala e il coder il trasferimento su piccola scala. Se avrò un po 'di tempo in più, studierò alcuni programmi c smontati e spero di ottenere qualche informazione in più ... – user1146332

+0

è questa la risposta accettata? – aditya

Problemi correlati