Ich habe Arm/Daumen seit vielen Jahren viele Assembler programmiert und habe sehr wenige der vielen Richtlinien da draußen benötigt.
.thumb_func ist ziemlich wichtig, wie von einem anderen Responder angegeben.
zum Beispiel
.globl _start
_start:
b reset
reset:
.arm
.globl one
one:
add r0,r0,#1
bx lr
.thumb
.globl two
two:
add r0,r0,#2
bx lr
.thumb_func
.globl three
three:
add r0,r0,#3
bx lr
.word two
.word three
.arm oder verwendet so etwas wie .code32 zu sein oder .CODE 32 sagt er dies Arm Code nicht Daumen-Code, der für die Cortex-M3 Sie nicht verwenden müssen.
.thumb ebenfalls, früher .code 16 oder vielleicht, dass immer noch funktioniert, macht gleichen Deal den folgenden Code Daumen nicht Arm.
Wenn die verwendeten Beschriftungen keine globalen Beschriftungen sind, zu denen Sie von anderen Dateien oder indirekt verzweigen müssen, benötigen Sie nicht .thumb_func. Aber damit die Adresse einer Verzweigung zu einem dieser globalen Labels richtig berechnet werden kann (lsbit ist eine 1 für den Daumen und 0 für den Arm), möchten Sie es als Daumen- oder Arm-Label markieren, und die thumb_func macht das, sonst Sie haben dieses Bit zu setzen, bevor mehr Code und das Etikett Zugabe ist nicht aufrufbaren von C.
00000000 <_start>:
0: eaffffff b 4 <one>
00000004 <one>:
4: e2800001 add r0, r0, #1
8: e12fff1e bx lr
0000000c <two>:
c: 3002 adds r0, #2
e: 4770 bx lr
00000010 <three>:
10: 3003 adds r0, #3
12: 4770 bx lr
14: 0000000c andeq r0, r0, ip
18: 00000011 andeq r0, r0, r1, lsl r0
bis .thumb der Assembler ARM-Code ist, wie gewünscht Verzweigung.
Sowohl die zwei als auch die drei Beschriftungen/Funktionen sind wie gewünscht mit einem Daumenkürzel, aber die zwei Beschriftungen haben eine geradzahlige Adresse und drei die richtige ungerade Adresse.
Die neuesten codesourcery-Tools wurden verwendet, um die obige Probe zu assemblieren, zu verknüpfen und zu entladen.
Jetzt für die Cortex-m3, wo alles Daumen (/ thumb2) thumb_func möglicherweise nicht so wichtig ist, kann es nur mit Befehlszeilenschaltern arbeiten (sehr einfach, ein Experiment zu tun, um herauszufinden). Es ist eine gute Angewohnheit, wenn Sie sich von einem Daumen-Prozessor zu einem normalen Arm/Daumen-Kern bewegen.
Assemblers fügen im Allgemeinen gerne alle diese Direktiven und andere Methoden hinzu, um Dinge wie eine Hochsprache aussehen zu lassen. Ich sage nur, dass Sie sie nicht verwenden müssen, ich habe Assemblierer für Arm ausgetauscht und viele verschiedene Assembler für viele verschiedene Prozessoren verwendet und bevorzuge den Ansatz "Weniger ist mehr", dh ich konzentriere mich auf die Baugruppe selbst und verwende so wenig werkzeugspezifische Teile wie möglich. Ich bin normalerweise die Ausnahme, nicht die Regel, so können Sie wahrscheinlich die häufiger verwendeten Direktiven herausfinden, indem Sie sich anschauen, welche Direktiven die Compiler-Ausgabe erzeugt (und mit der Dokumentation verifizieren).
unsigned int one (unsigned int x)
{
return(x+1);
}
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.file "bob.c"
.text
.align 2
.global one
.type one, %function
one:
.fnstart
.LFB0:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
add r0, r0, #1
bx lr
.fnend
.size one, .-one
.ident "GCC: (Sourcery G++ Lite 2010.09-50) 4.5.1"
.section .note.GNU-stack,"",%progbits
ich die .align tun verwenden, wenn Arm und Daumen Assembler oder Daten in mit Assembler Mischen, würden Sie den Assembler für eine solche Plattform erwarten etwas so offensichtlich wie Daumen Anweisungen zu wissen, auf Halbwortgrenzen und Arm Anweisungen sind an Wortgrenzen ausgerichtet. Die Werkzeuge sind nicht immer so schlau. Beregnung. Aligns über tut nicht weh
. Text ist der Standard, so dass ein wenig redundant ist, aber nicht weh tut. .text und .data sind Standardattribute (nicht spezifisch für arm), wenn Sie für eine Kombination aus rom und ram auf Ihrem Ziel kompilieren, was Ihnen egal ist (hängt davon ab, was Sie mit Ihrem Linker-Skript machen), sonst funktioniert .text für alles .
. Größe scheinbar die Größe der Funktion zu dieser Direktive starten. Der Assembler kann das nicht selbst herausfinden, also wenn die Größe dieser Funktion für Ihren Code wichtig ist, Linker-Skript, Debugger, Loader, was auch immer dann muss das richtig sein, sonst müssen Sie sich nicht darum kümmern. Eine Funktion ist ein High-Level-Konzept sowieso Assembler hat nicht wirklich Funktionen viel weniger eine Notwendigkeit, ihre Größe zu deklarieren. Und der C-Compiler ist sicherlich nicht interessiert, es ist nur auf der Suche nach einem Label zu verzweigen und im Falle der Arm-Familie ist es Daumencode oder Arm-Code, der verzweigt wird.
Sie finden die .pool-Direktive (es gibt eine neuere Entsprechung) nützlich, wenn Sie mit Ihren unmittelbaren (ldr rx, = 0x12345678) auf langen Abschnitten des Codes faul sind. Auch hier sind die Tools nicht immer schlau genug, um diese Daten nach einem unbedingten Sprung zu platzieren, haben Sie manchmal gesagt. Ich sage faule halb ernsthaft, es ist schmerzhaft, das Etikett zu machen: .word thing die ganze Zeit und ich glaube, dass sowohl die Arm- als auch die gcc-Tools für diese Abkürzung erlaubt sind, also benutze ich sie genauso wie alle anderen.
Auch llvm gibt ein zusätzliches .eabi_attribute oder zwei aus, das von der Version/mods des Code-Quelltextes zu binutils unterstützt wird, aber nicht (vielleicht noch) von den freigegebenen gnu-binutils unterstützt wird. Zwei Lösungen, die funktionieren, modifizieren llvms asm print-Funktion, um die eabi_attributes nicht zu schreiben oder sie zumindest mit einem Kommentar (@) zu schreiben, oder die binutils source/mods aus Quellcode zu holen und so binutils zu erstellen. code-Quellen neigen dazu, gnu zu führen (zum Beispiel die Unterstützung von thumb2) oder vielleicht neue Funktionen zurück zu portieren, also nehme ich an, dass diese llvm attrubutes in den mainline binutils in Kürze vorhanden sein werden. Ich habe keine negativen Auswirkungen durch Abschneiden der eabi_attributes aus dem llvm kompilierten Code erlitten.
Hier ist der Llvm-Ausgang für die gleiche Funktion oben, anscheinend ist dies die llc, die ich modifiziert habe, um die eabi_attributes auskommentieren.
.syntax unified
@ .eabi_attribute 20, 1
@ .eabi_attribute 21, 1
@ .eabi_attribute 23, 3
@ .eabi_attribute 24, 1
@ .eabi_attribute 25, 1
@ .eabi_attribute 44, 1
.file "bob.bc"
.text
.globl one
.align 2
.type one,%function
one: @ @one
@ BB#0: @ %entry
add r0, r0, #1
bx lr
.Ltmp0:
.size one, .Ltmp0-one
Das Elf-Dateiformat ist gut dokumentiert und sehr einfach zu analysieren, wenn Sie wirklich sehen wollen, was die elf Einzelrichtlinien (falls vorhanden) tun. Viele dieser Direktiven sollen dem Linker mehr als alles andere helfen. .thumb_func, .text, .data zum Beispiel.
Ich habe der Frage eine Prämie hinzugefügt, in der Hoffnung, ausführlichere Antworten zu erhalten, insbesondere in Bezug auf die Anweisungen .type und .size. – Oystein
Dies sollte in eine Frage pro Direktive aufgeteilt werden. Hinweis: Verstehen Sie das ELF-Format, machen Sie dann minimale Beispiele mit und ohne jede Direktive, kompilieren Sie und 'readelf -a' auf ihnen. –