K |
|||
Zeile 1: | Zeile 1: | ||
{{Baustelle|SprinterSB}} | {{Baustelle|SprinterSB}} | ||
− | + | In C versteht man unter '''Inline Assembler''' die Möglichkeit, direkt Assembler-Befehle in den Code einzufügen bzw. die eingefügten Assembler-Befehle selbst. | |
− | + | ||
− | + | Neben den einzufügenden Befehlen muss beschrieben werden, welche Nebeneffekte die Befehle auf die Maschine haben und wo/wie Parameter übergeben werden, bzw. wie die Zuordnung von Variablen zu den Registern ist. | |
− | + | ||
− | + | Obgleich das dazu verwendete Schlüsselwort <tt>__asm</tt> zum ANSI-C-Standard gehört, ist dies in jedem C-Compiler anders implementiert. Das gilt insbesondere für die Schnittstellenbeschreibung Variablen/Register. Dieser Artikel bezieht sich auf Inline Assembler von [[avr-gcc]]. | |
− | + | ||
− | + | =Begriffe= | |
− | + | ;Assembler-Template: Das Template (''Schablone'') ist ein statischer, konstanter String im Sinne von C. Es enthält die Assembler-Befehle sowie Platzhalter, in deren Stelle später die Operanden treten | |
− | + | ;Constraint: Die Constraints (''Nebenbedingungen'') beschreiben Einschränkungen an die zu verwendeten Register. Dies ist notwendig, da nicht alle Maschinenbefehle auf alle Register anwendbar sind | |
− | + | ;Clobber-List: Das ist eine Liste von Registern, deren Inhalt durch den Inline-Assembler zerstört wird | |
− | + | ||
− | + | =Syntax und Semantik= | |
− | + | Das Schlüsselwort, um eine Inline-Assembler Sequenz einzuleiten, ist <tt>__asm</tt> (ANSI). Oft ist auch <tt>asm</tt> oder <tt>__asm__</tt> verwendbar. Um zu kennzeichnen, daß die Sequenz keinesfalls wegoptimiert werden darf – etwa dann, wenn der Assembler keine Wirkung auf C-Variablen hat – wird dem <tt>asm</tt> ein <tt>volatile</tt> bzw. <tt>__volatile</tt> nachgestellt. Danach folgen in runden Klammern die durch <tt>''':'''</tt> getrennten Abschnitte des Inline-Assemblers: | |
− | + | asm volatile ([[#Assembler-Template|asm-template]] : [[#Operanden und Constraints|output-operand-list]] : [[#Operanden und Constraints|input-operand-list]] : [[#Clobbers|clobber-list]]); | |
− | + | Abschnitte, die leer sind, können auch weggelassen werden, wenn dahinter kein weiterer Abschnitt folgt: | |
− | + | asm volatile (asm-template); | |
− | + | ||
− | + | Oder | |
− | + | asm volatile (asm-template ::: clobber-list); | |
− | + | wenn weder Input- noch Output-Operanden gebraucht werden, aber Register oder Speicher verändert werden. | |
− | + | ||
− | |- | + | ==Assembler-Template== |
− | + | ||
− | + | ||
− | + | ||
<center> | <center> | ||
{| {{Blauetabelle}} | {| {{Blauetabelle}} | ||
Zeile 67: | Zeile 65: | ||
|} | |} | ||
</center> | </center> | ||
+ | |||
+ | ==Operanden und Constraints== | ||
<center> | <center> | ||
Zeile 197: | Zeile 197: | ||
|} | |} | ||
</center> | </center> | ||
+ | |||
+ | |||
+ | ==Clobbers== | ||
+ | |||
+ | ==Vordefinierte Bezeichner und Makros== | ||
+ | <center> | ||
+ | {| {{Blauetabelle}} | ||
+ | |+ '''Tabelle: vordefinierte Bezeichner/Makros | ||
+ | |- {{Hintergrund1}} | ||
+ | ! Bezeichner || Bedeutung | ||
+ | |- | ||
+ | |<tt>__SP_L__</tt> || unteres Byte des Stack-Pointers, für <tt>in</tt> bzw. <tt>out</tt> | ||
+ | |- | ||
+ | |<tt>__SP_H__</tt> || oberes Byte des Stack-Pointers, für <tt>in</tt> bzw. <tt>out</tt> | ||
+ | |- | ||
+ | |<tt>__SREG__</tt> || Status-Register, für <tt>in</tt> bzw. <tt>out</tt> | ||
+ | |- | ||
+ | |<tt>__tmp_reg__</tt> || ein Register zur temporären Verwendung (<tt>r0</tt>) | ||
+ | |- | ||
+ | |<tt>__zero_reg__</tt> || ein Register, das 0 enthält (<tt>r1</tt>) | ||
+ | |- | ||
+ | |<tt>lo8(''const'')</tt> || die unteren 8 Bit der Konstanten <tt>''const''</tt> | ||
+ | |- | ||
+ | |<tt>hi8(''const'')</tt> || Bits 8...15 der Konstanten <tt>''const''</tt> | ||
+ | |- | ||
+ | |<tt>hlo8(''const'')</tt> || Bits 16...23 der Konstanten <tt>''const''</tt> | ||
+ | |- | ||
+ | |<tt>hhi8(''const'')</tt> || Bits 24...31 der Konstanten <tt>''const''</tt> | ||
+ | |} | ||
+ | </center> | ||
+ | |||
+ | |||
+ | =Beispiele= | ||
+ | |||
+ | =Quellen= | ||
+ | * Doku zur avr-libc | ||
+ | * Doku zu avr-gcc | ||
+ | * Quellen von gcc | ||
+ | |||
+ | =Siehe auch= | ||
+ | * [[AVR Assembler Einführung]] | ||
+ | * [[:Kategorie:Quellcode Assembler|Quellcode Assembler]] | ||
+ | * [[Sourcevergleich]] | ||
+ | * [[avr-gcc]] | ||
+ | |||
+ | [[Kategorie:Microcontroller]] | ||
+ | [[Kategorie:Software]] | ||
+ | [[Kategorie:Grundlagen]] | ||
+ | [[Kategorie:Quellcode Assembler]] | ||
+ | [[Kategorie:Quellcode C]] |
Version vom 1. März 2006, 14:52 Uhr
An diesem Artikel arbeitet gerade Mitglied SprinterSB.
Am besten momentan noch keine gravierenden Ergänzungen / Änderungen vornehmen. Dieser Hinweis verschwindet wenn der Autor soweit ist. Sollte dieser Hinweis länger als drei Tage auf einer Seite sein, bitte beim Autor SprinterSB per PM / Mail oder Forum nachfragen ob er vergessen wurde. |
In C versteht man unter Inline Assembler die Möglichkeit, direkt Assembler-Befehle in den Code einzufügen bzw. die eingefügten Assembler-Befehle selbst.
Neben den einzufügenden Befehlen muss beschrieben werden, welche Nebeneffekte die Befehle auf die Maschine haben und wo/wie Parameter übergeben werden, bzw. wie die Zuordnung von Variablen zu den Registern ist.
Obgleich das dazu verwendete Schlüsselwort __asm zum ANSI-C-Standard gehört, ist dies in jedem C-Compiler anders implementiert. Das gilt insbesondere für die Schnittstellenbeschreibung Variablen/Register. Dieser Artikel bezieht sich auf Inline Assembler von avr-gcc.
Inhaltsverzeichnis
Begriffe
- Assembler-Template
- Das Template (Schablone) ist ein statischer, konstanter String im Sinne von C. Es enthält die Assembler-Befehle sowie Platzhalter, in deren Stelle später die Operanden treten
- Constraint
- Die Constraints (Nebenbedingungen) beschreiben Einschränkungen an die zu verwendeten Register. Dies ist notwendig, da nicht alle Maschinenbefehle auf alle Register anwendbar sind
- Clobber-List
- Das ist eine Liste von Registern, deren Inhalt durch den Inline-Assembler zerstört wird
Syntax und Semantik
Das Schlüsselwort, um eine Inline-Assembler Sequenz einzuleiten, ist __asm (ANSI). Oft ist auch asm oder __asm__ verwendbar. Um zu kennzeichnen, daß die Sequenz keinesfalls wegoptimiert werden darf – etwa dann, wenn der Assembler keine Wirkung auf C-Variablen hat – wird dem asm ein volatile bzw. __volatile nachgestellt. Danach folgen in runden Klammern die durch : getrennten Abschnitte des Inline-Assemblers:
asm volatile (asm-template : output-operand-list : input-operand-list : clobber-list);
Abschnitte, die leer sind, können auch weggelassen werden, wenn dahinter kein weiterer Abschnitt folgt:
asm volatile (asm-template);
Oder
asm volatile (asm-template ::: clobber-list);
wenn weder Input- noch Output-Operanden gebraucht werden, aber Register oder Speicher verändert werden.
Assembler-Template
Platzhalter | wird ersetzt durch |
---|---|
%n | Wird ersezt durch Argument n mit n = 0...9 |
%An | das erste (untere) Register des Arguments n (Bits 0...7) |
%Bn | das zweite Register des Arguments n (Bits 8...15) |
%Cn | das dritte Register des Arguments n (Bits 16...23) |
%Dn | das vierte Register des Arguments n (Bits 24...31) |
%an | Ausgabe des Arguments als Adress-Register, also als x, y bzw. z. Erlaubt zusammen mit Constraint b, e, x, y, z |
%~ | wird auf AVR mit Flash bis max. 8kByte durch ein r ersetzt, ansonsten bleibt es leer. Zum Aufbau von Sprungbefehlen, etwa "%~call foo" |
%= | eine für dieses asm-Template und die Übersetzungseinheit eindeutige Zahl. Zum Aufbau lokaler Sprungmarken. |
Sequenz | wird ersetzt durch Sonderzeichen |
%% | das %-Zeichen selbst |
\n | ein Zeilenumbruch zum Trennen mehrerer asm-Befehle/Zeilen |
\t | ein TAB, zur Übersichtlichkeit im erzeugten asm |
\" | ein " wird eingefügt |
\\ | das \-Zeichen selbst |
Kommentar | Beschreibung |
; Text | einzeiliger Kommentar bis zum Ende des Templates bzw. nächsten Zeilenumbruch |
/* Text */ | mehrzeiliger Kommentar wie in C |
Operanden und Constraints
Contraint | Register | Wertebereich | Contraint | Konstante | Wertebereich | |
---|---|---|---|---|---|---|
a | einfache obere Register | r16...r23 | G | Floatingpoint-Konstante | 0.0 | |
b | Pointer-Register | y, z | i | Konstante | ||
d | obere Register | r16...r31 | I | positive 6-Bit-Konstante | 0...63 | |
e | Pointer-Register | x, y, z | J | negative 6-Bit Konstante | -63...0 | |
l | untere Register | r0...r15 | K | Konstante | 2 | |
q | Stack-Pointer | SPH:SPL | L | Konstante | 0 | |
r | ein Register | r0...r31 | M | 8-Bit Konstante | 0...255 | |
t | Scratch-Register | r0 | N | Konstante | -1 | |
w | Obere Register-Paare | r24, r26, r28, r30 | O | Konstante | 8, 16, 24 | |
x | Pointer-Register X | x (r27:r26) | P | Konstante | 1 | |
y | Pointer-Register Y | y (r29:r28) | ||||
z | Pointer-Register Z | z (r31:r30) |
Mnemonic | Constraint | Mnemonic | Constraint | Mnemonic | Constraint | Mnemonic | Constraint | ||||
---|---|---|---|---|---|---|---|---|---|---|---|
adc | r,r | add | r,r | adiw | w,I | and | r,r | ||||
andi | d,M | asr | r | bclr | I | bld | r,I | ||||
brbc | I,label | brbs | I,label | bset | I | bst | r,I | ||||
cbi | I,I | cbr | d,I | com | r | cp | r,r | ||||
cpc | r,r | cpi | d,M | cpse | r,r | dec | r | ||||
elpm | t,z | eor | r,r | in | r,I | inc | r | ||||
ld | r,e | ldd | r,b | ldi | d,M | lds | r,label | ||||
lpm | t,z | lsl | r | lsr | r | mov | r,r | ||||
movw | r,r | mul | r,r | neg | r | or | r,r | ||||
ori | d,M | out | I,r | pop | r | push | r | ||||
rol | r | ror | r | sbc | r,r | sbci | d,M | ||||
sbi | I,I | sbic | I,I | sbiw | w,I | sbr | d,M | ||||
sbrc | r,I | sbrs | r,I | ser | d | st | e,r | ||||
std | b,r | sts | label,r | sub | r,r | subi | d,M | ||||
swap | r |
Clobbers
Vordefinierte Bezeichner und Makros
Bezeichner | Bedeutung |
---|---|
__SP_L__ | unteres Byte des Stack-Pointers, für in bzw. out |
__SP_H__ | oberes Byte des Stack-Pointers, für in bzw. out |
__SREG__ | Status-Register, für in bzw. out |
__tmp_reg__ | ein Register zur temporären Verwendung (r0) |
__zero_reg__ | ein Register, das 0 enthält (r1) |
lo8(const) | die unteren 8 Bit der Konstanten const |
hi8(const) | Bits 8...15 der Konstanten const |
hlo8(const) | Bits 16...23 der Konstanten const |
hhi8(const) | Bits 24...31 der Konstanten const |
Beispiele
Quellen
- Doku zur avr-libc
- Doku zu avr-gcc
- Quellen von gcc