mikrocontroller.net

Forum: Compiler & IDEs ARM-Assembler-Tutorial


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
8 lesenswert
nicht lesenswert
Hi,

ich habe (mal wieder :) ) ein Tutorial geschrieben und würde mich über 
Feedback hier im Thread freuen. Diesmal auf Englisch, vielleicht hilft 
es so mehr Leuten.

Es geht um das Programmieren von ARM-Cortex-M in Assembler. Auch wenn 
Hochsprachen wie C und C++ dort gut verfügbar sind, sind 
Assembler-Kenntnisse zum Debuggen und Low-Level-Code sinnvoll.

Zum Text: ARM-ASM-Tutorial
Beispiel-Code: https://github.com/Erlkoenig90/ArmAsmTutorial

Fragen und Anregungen können hier abgegeben werden :)

: Bearbeitet durch User
Beitrag #5998633 wurde von einem Moderator gelöscht.
Autor: PSblnkd (Gast)
Datum:

Bewertung
-7 lesenswert
nicht lesenswert
@erlkoenig
... Tutorials sind immer willkommen - auch für Assembler, aber warum nur 
in Englisch?

Sind wir schon soweit, dass wir das Deutsche verleugnen müssen?

Eine deutsche Version wäre mir (und vielleicht auch vielen Anderen) viel 
angenehmer.

Grüsse aus Berlin

PSblnkd

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
6 lesenswert
nicht lesenswert
PSblnkd schrieb:
> aber warum nur
> in Englisch?

Damit mehr Menschen in aller Welt das lesen können.

PSblnkd schrieb:
> Eine deutsche Version wäre mir (und vielleicht auch vielen Anderen) viel
> angenehmer.

Vielen anderen Menschen, welche kein Deutsch können, wäre eine englische 
Version lieber.

Autor: Wilhelm M. (wimalopaan)
Datum:

Bewertung
7 lesenswert
nicht lesenswert
PSblnkd schrieb:
> @erlkoenig
> ... Tutorials sind immer willkommen - auch für Assembler, aber warum nur
> in Englisch?

Damit es so gut wie jeden erreicht.

Jemand aus dem Bereich Technik/Informatik, der des Englischen zumindest 
lesend nicht mächtig ist, hat den Schuss nicht gehört.

>
> Sind wir schon soweit, dass wir das Deutsche verleugnen müssen?

Tut er doch gar nicht. Er nimmt einfacht die internationale lingua 
franca für Technik (s.o.).

>
> Eine deutsche Version wäre mir (und vielleicht auch vielen Anderen) viel
> angenehmer.

Mimimi, lern endlich Englisch, damit Du die Handbücher zu ARM auch lesen 
kannst.

Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas G. schrieb:
> ch habe (mal wieder :) ) ein Tutorial geschrieben

Wow. Danke.


Wenn es um Reichweite geht, würde vielleicht der Einstieg über 
Inline-Assembler oder Assembler-Funktionen noch breiteres Interesse 
finden als Projekte komplett in Assembler von Null aufzubauen.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Walter T. schrieb:
> Wenn es um Reichweite geht, würde vielleicht der Einstieg über
> Inline-Assembler

Inline-Assembler ist recht komplex mit diversen Fallstricken. Damit 
sollte man sich lieber erst befassen nachdem man die Assembler-Sprache 
an sich beherrscht...

Walter T. schrieb:
> Assembler-Funktionen

Wie man Assembler-Funktionen aus C aufruft ist ja auch gezeigt. Die 
Kapitel über Startup-Code und Linker könnte man zwar überspringen wenn 
man Assembler-Funktionen in C-Projekte einbinden will, aber Kenntnis 
dieser Themen ist allgemein hilfreich wenn man mit Assembler arbeitet. C 
kann einem ziemlich dazwischen funken, weshalb es nicht ganz verkehrt 
ist erstmal nur Assembler und Linker zu nutzen...

Autor: Roland F. (rhf)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Hallo
Niklas G. schrieb:
> und würde mich über Feedback hier im Thread freuen.

Vielen Dank für deine Arbeit. Ich persönlich halte allerdings ein 
weitere englische Anleitung zur Assemblerprogrammierung von 
ARM-Prozessoren für überflüssig. Für mich ist deine Arbeit daher leider 
nutzlos.

https://azeria-labs.com/writing-arm-assembly-part-1/
Youtube-Video "Assembly Language Tutorial"
Youtube-Video "ARM Assembly Language Tutorial - Part 1 - Setup ARM Tools"
http://infocenter.arm.com/help/topic/com.arm.doc.dui0068b/DUI0068.pdf
http://www.peter-cockerell.net/aalp/html/frames.html
u.s.w.

rhf

Autor: Gerd (Gast)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
Ja danke ganz nett und interessant.
Bin trotzdem der Meinung dass Asm bei den 8Bittern viel besser 
aufgehoben ist.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schöne Anleitung die Du da geschrieben hast, kommt für mich leider etwa 
ein Jahr zu spät....hab es mir aufwändig selbst beigebracht.

Deshalb hier noch einen Verbesserungsvorschlag:
Wenn die Register noch eigene Namen erhalten liest sich der Code fast 
wie von selbst...

//Arbeits-Register benennen
BASE   .req r0
OFFSET  .req r1
COUNTER  .req r2
POINTER .req r3
VALUE  .req r4
TEMP  .req r5
MASK   .req r6
DELAY  .req r7

//Funktions-Register benennen
.equ  RCC_AHB1ENR,    0x40023830

//Bitnamen für die Funktionsregister benennen
.equ GPIOAEN, 0
.equ GPIOGEN, 6

//TAKT für die Ports G und A einschalten
LDR POINTER, = RCC_AHB1ENR    //lade die Adresse in den Pointer
LDR VALUE,[POINTER]           //lade den Wert aus der aus der Adresse
LDR VALUE, = #((1<<GPIOGEN)|(1<<GPIOAEN))   //schreibe neuen Wert
STR VALUE,[POINTER]        //schreibe den Wert zurück in die Adresse

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Roland F. schrieb:
> https://azeria-labs.com/writing-arm-assembly-part-1/

Dieses Tutorial ist zwar gut gemacht, aber nicht sehr ausführlich und 
vernachlässigt die Toolchain (Linker, Linkerscripte...). Es zeigt auch 
nicht wie man konkret ein Mikrocontroller-Programm umsetzt.

Roland F. schrieb:
> Youtube-Video "Assembly Language Tutorial"

Kann in 38 Minuten wohl kaum die gleiche Menge an Inhalt wie mein 
Tutorial vermitteln.

Roland F. schrieb:
> Youtube-Video "ARM Assembly Language Tutorial - Part 1 - Setup ARM
> Tools"

In 11 Minuten auch nicht.

Roland F. schrieb:
> http://infocenter.arm.com/help/topic/com.arm.doc.dui0068b/DUI0068.pdf

Ist keine Schritt-Für-Schritt-Anleitung welche den Leser an konkrete 
Projekte heranführt. Funktioniert außerdem so nur mit den 
proprietären/teuren Tools von ARM selbst. Natürlich ist die ARM-Doku an 
sich aber sehr gut.

Roland F. schrieb:
> http://www.peter-cockerell.net/aalp/html/frames.html

Dito. Ist von 1987 und daher kaum relevant für Cortex-M MCUs.

Gerd schrieb:
> Bin trotzdem der Meinung dass Asm bei den 8Bittern viel besser
> aufgehoben ist.

Wie schon erwähnt sind Assembler-Kenntnisse für bestimmte Situationen 
erforderlich. Ganze Anwendungen wird man da nicht drin schreiben.

Bernd schrieb:
> Wenn die Register noch eigene Namen erhalten liest sich der Code fast
> wie von selbst...

Genau das passiert auch im Tutorial. Der .req Befehl wird gezeigt, aber 
ich halte es für nicht sehr flexibel, den Prozessor-Registern derart 
fixe Bedeutungen zuzuordnen.

Autor: Markus M. (adrock)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist ganz interessant, aber hat mir gerade wieder gezeigt, dass mir ASM 
auf ARM mit dem Thumb(2) Befehlssatz keine Freude bereiten wird :)

In 68k Assembler konnte man tatsächlich sehr guten Code schreiben, der 
oft effizienter als C und dennoch übersichtlich war. Bei Thumb2 muss man 
viele triviale Sachen "zu Fuß" machen, das kostet Zeit und 
Übersichtlichkeit.

Aber zum Verstehen von übersetztem Code ist es natürlich schön das 
zumindest mal gesehen zu haben.

: Bearbeitet durch User
Autor: Christoph db1uq K. (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meinen Artikel zu QO-100 habe ich zuerst in deutsch verfasst und jetzt 
noch im englischen Forum https://embdev.net/articles gepostet. Das macht 
zwar etwas mehr Arbeit, aber dank automatischer Rohübersetzung ging das 
recht schnell. Die Stilblüten muss ich noch im Laufe der Zeit ausmerzen, 
ich hoffe, das mir kompetentere Mitleser dabei helfen.

Am ARM Assembler interessieren mich vor allem die DSP-Möglichkeiten. Es 
gibt anscheinend einige ARM-Typen, die z.B. MAC-Befehle und begrenzende 
mathematische Operationen beherrschen, also bei Überschreiten der 16- 
oder 32-Bit Grenze nicht ins negative rutschen.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Markus M. schrieb:
> Ist ganz interessant, aber hat mir gerade wieder gezeigt, dass mir ASM
> auf ARM mit dem Thumb(2) Befehlssatz keine Freude bereiten wird :)

Ja, die Architektur ist darauf optimiert Hochsprachen-Code effizient 
ausführen zu können, nicht darauf, schönen Assembler-Code zu haben. Es 
sind einige clevere Tricks nötig, welche in Assembler nicht sehr schön 
sind, aber vom Compiler gut beherrscht werden können.

Christoph db1uq K. schrieb:
> Meinen Artikel zu QO-100 habe ich zuerst in deutsch verfasst und jetzt
> noch im englischen Forum https://embdev.net/articles gepostet.

Na, wenn es einmal schon auf Englisch vorliegt, ist es schon ziemlich 
universell. Wenn jemand Interesse hat das ins Deutsche zu übersetzen...

Christoph db1uq K. schrieb:
> Es
> gibt anscheinend einige ARM-Typen, die z.B. MAC-Befehle und begrenzende
> mathematische Operationen beherrschen

Ja, die Cortex-M4F haben das. Das sind die "saturating" Operationen. 
Bevor man sich damit auseinandersetzt sollte man aber erstmal die Basics 
kennen :)

Autor: Christoph db1uq K. (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Wikipedia wären das:
Atmel: SAM4-Familie (Cortex-M4)
Freescale: Kinetis-Familie (Cortex-M4 und Cortex-M4F)
STMicroelectronics: STM32-F3/F4-Familie (Cortex-M4F)
Infineon: XMC4000-Familie (Cortex-M4F)
Texas Instruments: MSP432, Stellaris-LM4F- und Tiva-TM4C-Familie 
(Cortex-M4F)
NXP Semiconductors: LPC4300-Familie (Cortex-M4)

Wie liegen die preislich, rentiert es sich, die speziell als low-cost 
DSP zu benutzen?

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Christoph db1uq K. schrieb:
> Wie liegen die preislich, rentiert es sich, die speziell als low-cost
> DSP zu benutzen?

Die meisten gibt es so im Bereich 3-10€. Das ziemlich beliebte 
STM32F407G Discovery Board mit Cortex-M4 inklusive Debug-Adapter gibt's 
für ca 15€.

Autor: Christoph db1uq K. (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die 15€ scheinen vom Billighuber zu sein, Reichelt will 25 und Digikey 
18+Steuer. Der billigste M4F von ST, STM32G441KBT6  bei Reichelt kostet 
4,30€ im LQFP32.

Ich habe mein altes DSP-Projekt schon mehrfach erwähnt, ein IIR-Hilpert 
als Breitband 90 Grad Phasenschieber zur SSB-Erzeugung. Passt mit Mühe 
noch in einen Arduino, aber 2 Bit mehr ADC und viel mehr Power in 
derselben Preislage wäre interessant. Das sind 8 IIR-Allpassfilter mit 
jeweils nur einer Multiplikation und ein paar Additionen.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Christoph db1uq K. schrieb:
> Die 15€ scheinen vom Billighuber zu sein, Reichelt will 25 und Digikey
> 18+Steuer.

Das war mal billiger, scheint wohl etwas vergriffen zu sein. Das 
NUCLEO-F446RE hat sogar noch etwas mehr Leistung, kostet aber weniger.

Christoph db1uq K. schrieb:
> Der billigste M4F von ST, STM32G441KBT6  bei Reichelt kostet
> 4,30€ im LQFP32.

Reichelt ist für sowas auch keine Referenz ;-)

Autor: Mistel (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Niklas G. schrieb:
> ...

Ich wollte es nicht nochmal alles zitieren, aber ich sehe es zu 97% wie 
du.


Ergänzend :
Gerade bei dem Drumherum (binutils, Linker, Debugger, ASM) fehlt es 
meistens den Studenten die kommen. Ich habe den Eindruck das ist als 
Basics Einführung für Neueinsteiger genau richtig. Das braucht man nicht 
oft, aber es hilft wenn man eine Vorstellung von dem hat wie sich das 
ganze drum herum aufbaut und welche Möglichkeiten sich da evtl. bei 
bestimmten Problemstellungen ergeben.

An vielen Hochschulen ist es leider so, dass es ein vorgefertigtes 
Project Template gibt wo man nur noch hier und dorthin klickt ohne zu 
wissen was im Hintergrund passiert. Wir hatten hier schon Bewerber 
Embedded Abschlussarbeit die auf die Frage nach dem verwendeten Compiler 
Eclipse gesagt haben :(. Was ein elf/hex/bin File oder Assembler ist 
haben die auch nicht gewusst.

Wünschen würde ich mir auch einen Blick auf inline ASM ... vielleicht 
sollte ich mal selbst den Hintern hochbekommen.
Aber ich bin da auch immer wieder halb raus, nur für Assembler Code in 
meinem Team (10 Personen) zuständig macht ca. 1-4 Tage im Jahr Assembler 
schreiben und das auch noch auf unterschiedlichen Architekturen. Lesen 
deutlich häufiger, Debuggen von optimierten Code -O2/-O3/-Os ist ja 
manchmal etwas schwierig ohne Blick ins Disassembly, aber das kann ich 
zeitlich schlecht beziffern.

*Was mir sehr gut gefallen hat:*
.section .VectorTable, "a" + nachfolgende Beschreibung.
Vielleicht ergänzend:
Wenn man die Section hart auf eine Adresse setzt klappt es ohne 
allocable (übrigens ist da ein Tippfehler), wenn man die Section nur 
einem "MEMORY" zuweist fliegt es raus.
-> das schöne "a" fehlt leider schon mal im Code von ARM :(

Zum Schluss Daumen hoch

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Mistel schrieb:
> Ich wollte es nicht nochmal alles zitieren, aber ich sehe es zu 97% wie
> du.

Danke :)

Mistel schrieb:
> Wir hatten hier schon Bewerber
> Embedded Abschlussarbeit die auf die Frage nach dem verwendeten Compiler
> Eclipse gesagt haben :(. Was ein elf/hex/bin File oder Assembler ist
> haben die auch nicht gewusst.

Oje... Ja genau darum ging es.

Mistel schrieb:
> Lesen
> deutlich häufiger, Debuggen von optimierten Code -O2/-O3/-Os ist ja
> manchmal etwas schwierig ohne Blick ins Disassembly, aber das kann ich
> zeitlich schlecht beziffern.

Ja, es kommt bei mir auch deutlich häufiger vor dass Disassembly-Code 
gelesen wird. IMO lernt man Sprachen aber am Besten via 
Learning-By-Doing, daher kann man auch selber ein Paar Dinge in 
Assembler programmieren um es zu lernen, auch wenn man später nur noch 
Code liest.

Mistel schrieb:
> Wenn man die Section hart auf eine Adresse setzt

Wie meinst du das denn genau? Das Problem taucht nur auf wenn man der 
Section im Linkerscript eine eigene Output-Section zuweist, weil sonst 
das "Alloc"-Bit von anderen Input Sections kommt.

Mistel schrieb:
> übrigens ist da ein Tippfehler

Ups :)

Mistel schrieb:
> -> das schöne "a" fehlt leider schon mal im Code von ARM :(

Ja, ST hat ja teilweise auch Fehler in Linkerscripten - das ganze Thema 
ist wohl doch noch nicht so weit bekannt...

Autor: Christoph db1uq K. (christoph_kessler)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für das Tutorial, ich habe es mir ausgedruckt und geheftet. Wer es 
auch lieber in Papierform hat, hier das PDF.

Der Nucleo446 sieht gut aus, bei Conrad derzeit sogar etwas billiger 
(17,99€ im Laden) als Reichelt. Jedenfalls bei Händlern weit verbreitet.

Die Datenblatt-Links speziell zu diesem Controller:

PM0214 Programming manual
https://www.st.com/content/ccc/resource/technical/document/programming_manual/6c/3a/cb/e7/e4/ea/44/9b/DM00046982.pdf/files/DM00046982.pdf/jcr:content/translations/en.DM00046982.pdf

Zum Mikrocontroller STM32F446
https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html
->Resources->Technical Literature->Datasheet.

jeweils über 200 Seiten, das werde ich nicht ausdrucken.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph db1uq K. schrieb:
> Der Nucleo446 sieht gut aus, bei Conrad derzeit sogar etwas billiger
> (17,99€ im Laden) als Reichelt. Jedenfalls bei Händlern weit verbreitet.

Jo, wobei ich sagen würde dass es für Hobby nicht auf den letzten Euro 
ankommt. Das Tutorial ist für den STM32F4 aber nur bedingt anwendbar, 
die GPIO- und RCC-Peripherie ist anders (u.a.).

Christoph db1uq K. schrieb:
> jeweils über 200 Seiten, das werde ich nicht ausdrucken.

Die Tabelle mit den Condition Codes liegt immer ausgedruckt neben dem PC 
;-)

Viel Spaß beim Lesen!

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas G. schrieb:

> ich habe (mal wieder :) ) ein Tutorial geschrieben und würde mich über
> Feedback hier im Thread freuen.

Wow, das ist ja richtig ausführlich, und sogar inklusive Toolchain! 
Gerade wo GCC manchmal etwas hakelig einzurichten ist, ist das 
hilfreich.

> Fragen und Anregungen können hier abgegeben werden :)

Nur ein paar Typos hätte ich im Angebot:

2.1 Mikrocontroller -> microcontroller

Debug adapter: JTAG oder SWD -> JTAG or SWD

Writing GPIO pins: dafult -> default

Address space: addresses where used -> addresses were used

objcopy: createed -> created

Interfacing C and C++ code: neccessary -> necessary

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke :)

Nop schrieb:
> Nur ein paar Typos hätte ich im Angebot:

Ups, sind behoben!

Nop schrieb:
> Gerade wo GCC manchmal etwas hakelig einzurichten ist, ist das
> hilfreich.

Ja genau, da sind bestimmt schon ein paar Anfänger dran gescheitert.

Autor: Christoph db1uq K. (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jatzt kann ich das auch in der Bahn lesen, was mir schon aufgefallen 
ist, der Cortex-M kann nur den T32 Thumb, nicht A32. Ich dachte das sind 
nur 16Bit-Instruktionen. Aber die DSP-Befehle (Multiply-accumulate) sind 
für 32 Bit.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph db1uq K. schrieb:
> Ich dachte das sind
> nur 16Bit-Instruktionen. Aber die DSP-Befehle (Multiply-accumulate) sind
> für 32 Bit.

Eine Sache, die ARM nicht kann, Dinge sinnvoll benennen :-)

T32 ist der Thumb-Instruction Set, welcher sich genau wie A32 auf eine 
32bit-CPU mit 32bit-Registern und 32bit-Adressraum bezieht.

Die meisten der T32-Befehle selbst sind 16bit groß, aber manche sind 
32bit. Als Programmierer merkt man von der Größe des Befehls selbst 
nicht so viel, die erkennt man im disassemblierten Code.

Christoph db1uq K. schrieb:
> Aber die DSP-Befehle (Multiply-accumulate) sind
> für 32 Bit.

Kommt drauf an welcher genau gemeint ist. Der "MLA" Befehl (Eine 32bit 
Multiplikation + Addition) ist auf ARMv7-M verfügbar, also 
Cortex-M3/4/7.

Der "SMLAD" Befehl (Zwei 16bit-Multiplikationen und Addition auf ein 
32bit-Register/Integer) ist Teil der DSP-Extension, und die gibt's nur 
auf ARMv7E-M, d.h. Cortex-M4/7.

Dann gibt's noch VMLA für Floating-Point, was nur auf ARMv7M + FPU 
verfügbar ist, also Cortex-M4/7 - mit 32bit "float", bei manchen M7 auch 
mit 64bit "double".

Alles etwas unübersichtlich, die Details entnimmt man dem ARMv7M 
Architecture Reference Manual. Damit hab ich mich auch noch nicht so 
genau auseinander gesetzt.

Auf A32 (ARMv7-A, Cortex-A), ggf. mit NEON-Extension, ist das alles 
nochmal anders...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.