2012-04-10 10 views
8

ich vor kurzem begann Assembler Programmierung für Arm Kerne. Meine ersten kleinen Demos, nur mit der .text-Sektion, liefen ohne Probleme.interner Umzug nicht behoben

Als logische Erweiterung wollte ich den Assembler-Code in die üblichen Abschnitte strukturieren: .text, .data, .bss.

Also schrieb ich die folgende einfache Programm:

.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 

Aber

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

Ausfahrten mit dem Fehler

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

ich keine Ahnung, warum der Monteur über Umzug beschwert, weil Ich dachte, das ist die Aufgabe des Linkers. Ich könnte mir vorstellen, dass ich dem Assembler sagen muss, dass mein .data-Abschnitt nicht auf der letzten Speicherposition in der Zusammenstellungsphase liegt, aber ich kann nichts Ähnliches finden.

Obwohl ich fand einen Weg, den Code richtig zusammengebaut zu bekommen, von

.section .data 

von

.org . 

ersetzt, die keine befriedigende Lösung. Vor allem angesichts der Tatsache, dass die Gasdokumentation den Sinn dieses Abschnitts unterstreicht.

Vielleicht hat jemand von euch Experten kann mir helfen, einige Weisheit

Antwort

13

es den einzigen Weg scheint zu gewinnen, die Sie tun können es durch Greifen der Adresse der Variablen ist und einen Wert von dieser Adresse geladen werden.

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

In gewisser Weise macht dies auch Sinn. Was ist, wenn die Adresse von x (nach der Verknüpfung) für einen relativen PC-Zugriff zu weit entfernt ist? Da der Compiler (der die Verknüpfung nicht durchführt) nicht weiß, wie weit der Datenabschnitt von dem Textabschnitt entfernt sein könnte, würde er sich weigern, diesen Code nur dann zu kompilieren, wenn er nicht erreichbar ist.

Mit dieser indirekten Art des Zugriffs auf eine Variable wird garantiert, dass die Variable erreichbar ist (oder zumindest der Compiler kann sicher sein, ob die Variable erreichbar ist oder nicht).

-Code angepasst von http://www.zap.org.au/elec2041-cdrom/examples/intro/pseudo.s

+0

Vielen Dank für Ihre Erklärung und das Beispiel. Dies oder etwas Ähnliches sollte in den Armbereich der binutils-Dokumentation gehen. Ich merke mir, dass der Linker den großen Maßstab macht und der Coder die kleine Verlagerung. Wenn ich etwas mehr Zeit habe, werde ich einige demontierte C-Programme studieren und hoffe, mehr Einblick zu bekommen ... – user1146332

+0

ist das die akzeptierte Antwort? – aditya