Erklärung für eine Zeile Assembler benötigt

OP #5364132
Lesenswert?
• ▲
▼
Guten Abend,

ich benötige eine Erklärung für eine einzelne Zeile Assembler (ARMv6). 
Ich würde den Code, den ich benutze gerne vollständig verstehen, 
allerdings klappt das bei diesem ASM-Statement nicht:
1
asm volatile("mcr p15, 0, %[addr], c12, c0, 0" : : [addr] "r" (&interrupt_vectors));

Dabei ist
1
interrupt_vectors
 eine in C definierte Funktion. Die Zeile stammt aus diesem Repo: 
https://github.com/brianwiddas/pi-baremetal/blob/master/interrupts.c

Die Erklärung des Befehls 
(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489g/Cihfifej.html) 
hilft mir auch nicht weiter. Wie komme ich auf diesen Befehl und seine 
Parameterwerte? Was ist ein Coprozessor im Sinne einer ARM-CPU?

Was bedeuten die zwei Doppelpunkte und das "r"?
Gast #5364379
Lesenswert?
• ▲
▼
Hallo,

>Was ist ein Coprozessor im Sinne einer ARM-CPU?
Das ist typisch ARM und wieder völlig missverständlich.
Es handelt sich hier nicht um eine eigene CPU sondern um eine 
Erweiterung der ARM v6 CPU.
Das Coprozessor-Infterface stellt ein Register-Interface zum Ansrpechen 
der verschiedenen Subsysteme, die nicht direkt in der CPU eingebaut 
sind, bereit. Dazu zählen z.B. Memory-Protection, Interrupt Controller, 
Cache, ect. Dabei hat jedes Subsystem eine eigene 'Nummer'.

Welches Register sich hinter der 'Codierung' verbrigt muß man sich aus 
der ARM Doku zusammen suchen.

Jetzt zum ASM-Befehl:
>asm volatile("mcr p15, 0, %[addr], c12, c0, 0" : : [addr] "r" 
(&interrupt_vectors));

mcr (move to copro register):
P15 ist die Nummer des Coprozessors (in deinem Fall wohl der Interrupt 
Controller).
C12, C0 und die beiden 0 definieren das anzusprechende Register im 
Copro.

Für den Compiler ist asm volatile(...) wie ein Funktionsaufruf. Dieser 
kann Parameter und einen Return Wert haben. Der Compiler versteht den 
ASM-Code aber nicht. Daher muß ihm am Ende der ASM-Sequenz durch eine 
Liste mitgeteilt werden, welche Register die Eingangsparameter 
beinhalten und wo der Return-Wert abgelegt werden soll.

Die Syntax ist dabei
asm volatile("string mit asm instruktionen": Ausgangsreg: Liste mit 
Eingangswerten.
Dabei wird auch noch mit symbolischen Ersetzungen gearbeitet. %[addr] 
heißt, genau an dieser Stelle soll das "Symbol" addr aus der Liste 
genommen werden.

In der Liste sagt man, dass [addr] ein "r"-register ist das vorher mit 
dem C-Symbol &interrupt_vectors zu laden ist.

In Pseudo C-Code würde der Befehl so aussehen:

uint32 r = &interrupt_vectors;
asm_func(r)

void asm_func(uint8 r)
{
 *(Copro_x_Reg_y) = r;
}

Hier hilft ein Blick in das ARM-Compiler Manual.
(GCC macht das anders...)

Hoffe, das war einigermaßen richtig und verständlich.
(Firma: fritzler-avr.de) #5364512
Lesenswert?
• ▲
▼
ASM Funktionen in C nutzen nennt sich "intrinsics".
Das sieht dann aus wie ein C Funktionsaufruf, aber am Ende fällt ein asm 
Code raus.
So kann man zB manuell die x86 AVX Funktionen nutzen fürs 
Numbercrunchen.
(Bei ARM wäre das dann die NEON Engine)

Guckst du hier: 
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/arm/arm_acle.h
Die Funktion heist "__arm_mcr".


Aber was noch nicht ganz geklärt ist, wozu der Befehl denn nun genutzt 
wird.
Die Zahlenkombination zeigt auf das Vector Base Address Register (VBAR).
Bei ARMv4 zB musste die Interrupttabelle noch an Adresse 0x0 sein oder 
als "High Vectors" an 0xFFFF0000.
Die Interrupttabelle enthält aber direkt ARM Befehle dessen 
Sprungreichweite begrenzt ist.
Daher musste man sich mit Doppelsprüngen aushelfen wenn der Speicher zB 
erst ab 0x20000000 eingebunden ist.
Mit dem VBAR Register wurde das geändert. Die Interrupttabelle kann man 
irgendwo 32Byte aligned in sein Programm werfen und dem ARM Kern dann 
einen Pointer darauf mitteilen.
-> Alle sind glücklich ;)

Hier noch ein paar Infos dazu:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0433c/CIHHDAIH.html

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.