Forum: Compiler & IDEs AVR ASM soll AVR GCC aufrufen


von Adib (Gast)


Lesenswert?

Hallo Leute,

ich habe ein AVR ASM Projekt. Das will ich jetzt erweitern und zwar mit 
C.

Mein Problem ist jetzt, dass ich dem Assembler-code die C Funktionen 
bekannt machen muss.

Ich kenne dieses Paper: http://www.atmel.com/images/doc42055.pdf

Wenn ich aber im Code
1
.extern mycfunction

erhalte ich eine Fehlermeldung:
1
Invalid directive: '.extern'

Mein Projekt ist initial ein ASM Projekt und ich will jetz C Code 
hinzufügen.

Die generierte Programmzeile ist:
1
C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR Assembler\Native\2.1.1175\avrassembler\avrasm2.exe -fI -S "asmfoo.tmp"  -W+ie -im16def.inc -d "asmfoo.obj"  "asmfoo.asm"  -I "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR Assembler\Native\2.1.1175\avrassembler\Include"

Es scheint, als ob der Assembler die Direktive .extern nicht kennt. ?

Habt ihr Hinweise?

Danke,

Adib.
--

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Adib schrieb:
> Es scheint, als ob der Assembler die Direktive .extern nicht kennt. ?

Klar, wofür auch?

Das Ding ist doch ein Primitiv-Assembler, der nur als Absolutassembler
arbeiten kann und keinen Linker kennt.  Was sollte er dann mit einem
als extern deklarierten Symbol anfangen können?

Beim GNU-Assembler kannst du sowas machen, aber der hat halt rundum
eine andere Syntax als der von Atmel, du müsstest also deinen Quellcode
umschreiben.

von Karl H. (kbuchegg)


Lesenswert?

Adib schrieb:
> Hallo Leute,
>
> ich habe ein AVR ASM Projekt. Das will ich jetzt erweitern und zwar mit
> C.

Falsche Vorgehensweise.
Du willst nicht ein Assembler Projekt mit C erweitern sondern du willst 
ein C Projekt neu beginnen, in dem du von C aus an ausgewählten Stellen 
Funktionen aufrufst, die in Assembler geschrieben sind.

Damit C Code laufen kann gilt es Vorbedingungen einzuhalten. Da muss 
eine Runtime Umgebung aufgesetzt werden, ehe dann dein main() erstmals 
die Kontrolle kriegt. Diese Umgebung wird vom Startup-Code eingerichtet, 
die du in einem C Projekt immer automatisch mit dabei hast. Startest du 
mit einem Assembler Projekt, dann fehlt diese Einrichtung.

Allerdings erhebt sich die Frage, warum du Teile deines Programms in 
Assembler schreiben willst. Es gibt natürlich Fälle an denen dies 
notwendig ist, weil man 100% taktgenaues Code-Timing benötigt. Ist 
dieser Fall nicht gegeben, dann ist es das vernünfigste den Code noch 
mal neu in C zu formulieren.
Wenn das nicht geht, dann musst du eben bei Assembler bleiben und deine 
Erweiterungen in Assembler machen.
Das ist eben die Krux an Assembler: du bist zu nichts kompatibel und 
kannst nur mit viel Aufwand aus diesem Korsett ausbrechen. Ein in 
Assembler vorliegendes Programm mal eben so durch neue Funktionalität in 
einer anderen Sprache erweitern spielt es da nicht.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Adib schrieb:

Das Problem liegt hier:

> avrasm2.exe

Du brauchst einen Assembler/Linker, der ABI-kompatibel mit dem 
GNU-Assembler ist, da avr-gcc diesen als "Backend" verwendet.

Ein Assembler, der ABI-kompatibel zum GNU-Assembler ist, ist natürlich 
der GNU-Assembler selbst :-)

von Adib (Gast)


Lesenswert?

Jo,

Danke erst mal. Dachte, es wäre einfacher.

Grüße, Adib.
--

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Jörg W. schrieb:
> Beim GNU-Assembler kannst du sowas machen, aber der hat halt rundum
> eine andere Syntax als der von Atmel, du müsstest also deinen Quellcode
> umschreiben

Quark. Das von Atmel zitierte Dokument  bezieht sich auf den GCC. Und es 
funktioniert wie dort beschrieben in beide Richtungen. Wohingegen es in 
der Tat ungewöhnlich ist das Assembler C Funktionen aufruft.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Adib schrieb:
> Dachte, es wäre einfacher.

Es ist auch ganz einfach! Wenn man weiss wie es geht.

Was Herr Buchegg schreibt bezogen auf das "Framework" ist fast richtig.

Voraussetzung dass es geht, ist dass der GCC Assembler benutzt wird. Um 
das ganz einfach zu realisieren setzt man einfach ein GCC "C" Projekt 
auf. In das Bindet man ein .s (Assembler-File) ein.

Das man eine "C" main() Funktion benötigt ist quatsch. Ich bin für ein 
paar Tage auf Meetings in den USA. Danach kann ich Dir gerne ein AVR 
Studio Beispielprojekt senden.  Dazu eine PM an mich.

Im Prinzip als Beispiel zum aufrufen einer "C" Funktion aus einem 
Assembler Code, schnell getippt, eifach so machen:

C-FILE
1
#include <avr/io.h>
2
3
4
uint8_t myCFunction(void)
5
{
6
   //irgendwas machen wie z.B.
7
   volatile uint8_t myVar = 123;
8
   return(myVar);
9
}


Und im Assembler File (.s)
1
#include <avr/io.h>
2
#define __SFR_OFFSET 0
3
4
      
5
6
  .extern myCFunction //C-Funktion bekannt machen
7
  .global main      //main bin jetzt ich da unten
8
      
9
main:  rcall  myCFunction  //C-Funktion aufrufen
10
  nop
11
  nop
12
13
  rjmp main
14
15
  .end


Beachten! Das Label "main" muss auch genau so geschrieben werden

: Bearbeitet durch User
von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Karl H. schrieb:
> Allerdings erhebt sich die Frage, warum du Teile deines Programms in
> Assembler schreiben willst. Es gibt natürlich Fälle an denen dies
> notwendig ist, weil man 100% taktgenaues Code-Timing benötigt. Ist
> dieser Fall nicht gegeben, dann ist es das vernünfigste den Code noch
> mal neu in C zu formulieren.

Warum hört ihr eigentlich nicht das ständige Missionieren auf? Besonders 
dann wenn jemand eine offensichtlich konkrete Frage hat und nicht 
versucht eine Datenbankabfrage in Assembler zu realisieren.

von Stefan K. (stefan64)


Lesenswert?

Thomas H. schrieb:
>> Beim GNU-Assembler kannst du sowas machen, aber der hat halt rundum
>> eine andere Syntax als der von Atmel, du müsstest also deinen Quellcode
>> umschreiben
>
> Quark. Das von Atmel zitierte Dokument  bezieht sich auf den GCC. Und es
> funktioniert wie dort beschrieben in beide Richtungen. Wohingegen es in
> der Tat ungewöhnlich ist das Assembler C Funktionen aufruft.

Ärger mit dem Chef gehabt oder was?

Was Jörg da schrieb, ist kein Quark, sondern exakt dasselbe, was Du dann 
nochmal drunter geschrieben hast.

Stefan

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas H. schrieb:
> Quark. Das von Atmel zitierte Dokument  bezieht sich auf den GCC.

Ist „Quark“ dein „von Atmel zitierte(s) Dokument“?  Ansonsten sehe
ich da kein solches, aber ein
1
C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR Assembler\Native\2.1.1175\avrassembler\avrasm2.exe

recht prominent im ersten Beitrag, und das ist nun einmal nicht
der GNU-Assembler, und ein für diesen Atmel-Assembler geschriebener
Quellcode läuft auch nicht 1:1 durch den GNU-Assembler durch.

Behalt' deinen „Quark“ also besser für dich …

Thomas H. schrieb:
> Warum hört ihr eigentlich nicht das ständige Missionieren auf?

Wenn man den Assembler-Quelltext ohnehin (mehr oder minder umfassend,
wir haben ihn ja nicht gezeigt bekommen) anfassen muss, dann stellt
sich schon sehr wohl die Frage, ob man ihn nicht mit weniger Aufwand
hernach gleich in C verfassen kann.  Wie Karl Heinz schon schrieb,
die Initialisierung des Laufzeitsystems muss man ohnehin C-konform
vornehmen.

von Karl H. (kbuchegg)


Lesenswert?

Thomas H. schrieb:

> Und im Assembler File (.s)
>
1
> #include <avr/io.h>
2
> #define __SFR_OFFSET 0
3
> 
4
> 
5
> 
6
>   .extern myCFunction //C-Funktion bekannt machen
7
>   .global main      //main bin jetzt ich da unten
8
> 
9
> main:  rcall  myCFunction  //C-Funktion aufrufen
10
>   nop
11
>   nop
12
> 
13
>   rjmp main
14
> 
15
>   .end
16
>
>
>
> Beachten! Das Label "main" muss auch genau so geschrieben werden

und jetzt hätte ich da gerne noch eine Erklärung, was da jetzt 
wahnsinnig besser ist, als gleich
1
int main()
2
{
3
  while( 1 )
4
    myCFunction();
5
}
zu schreiben.

Fazit: Klar kann man die Arbeit vom Compiler auch zu Fuss erledigen. 
Aber wozu?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Thomas H. schrieb:

> Warum hört ihr eigentlich nicht das ständige Missionieren auf? Besonders
> dann wenn jemand eine offensichtlich konkrete Frage hat und nicht
> versucht eine Datenbankabfrage in Assembler zu realisieren.

Nun. Irgendeinen Grund wird es schon haben, warum er Teile in C 
schreiben will. Ich denke nicht,  dass es sich bei den zu schreibenden 
Dinge um die trivialsten Teile seines Programmes handelt.
Ausserdem missioniere ich nicht.
Was ich nämlich denke, das ist, dass er von irgendwoher ein Assembler 
Programm hat, das er gerne erweitern möchte. Und anstatt das in ein C 
Korsett zu zwängen mit all seinen Problemen, wie zum Beispiel 
einzuhaltender ABI, würde ich dazu raten den Schritt zu machen und nur 
die Teile in Assembler zu belassen, die aus Code-Timing Gründen 
taktgenau sein müssen. Die Zeit, die er für einen derartigen Umbau auf 
Assembler Ebene benötigt (er benutzt ja noch nicht einmal den richtigen 
Assembler dafür), die Zeit kann besser investiert werden. Auch im 
Hinblick auf zukünftige Wartungen und/oder Erweiterungen. Denn eines ist 
klar: Arbeit muss er so und so investieren. Mit ein paar .extern und 
einem call ist es im Regelfall nicht getan, so wie du das suggerierst. 
Das funktioniert nur, weil dein Programm nichts anderes macht als genau 
die Funktion aufzurufen. Oder weisst du, ob sein Programm ein paar ISR 
hat, die sich die Freiheit nehmen einige Register nur für ihre eigene 
Verwendung zu reservieren und daher nicht pushen/popen? Das möchte ich 
dann sehen, was da rauskommt, wenn ein derartiger Interrupt genau dann 
zuschlägt wenn gerade der C-Teil an der Arbeit ist. Oder wenn irgendwo 
im Programm an einer ganz anderen Stelle ein Register seinen Wert 
behalten soll, welches der gcc als clobber-Register einstuft?
Wir wissen nichts über sein Programm und die Fallstricke, die sich darin 
verbergen. Aber eines hab ich im Laufe der Jahre gelernt: die Dinge sind 
immer komplexer als ursprünglich gedacht.

Der wesentliche Punkt ist der Wechsel der Sichtweise. Er hat nicht mehr 
ein Assembler Programm, das mit C Funktionen aufgepeppt wurde, sondern 
die Sichtweise muss sein, dass er ein C Programm hat, dass mit Assembler 
Funktionalität aufgepeppt wurde. Das dieser Assembler Anteil am Anfang 
durchaus 90% betragen kann, ist ja kein Hindernisgrund. Aber wenn es zu 
Problemen kommt (und die wird es voraussichtlich), dann ist immer der 
Assembler-Teil an das anzupassen, wie der Compiler die Welt sieht. Und 
wenn ich schon anpasse, dann steht selbstverständlich die Überlegung im 
Raum: warum nicht gleich zumindest diesen Teil in C neu schreiben, denn 
dann kümmert sich der Compiler um das ABI.

: Bearbeitet durch User
von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Guten Tag die Herren,

ich möchte die ganzen Anfeindungen gemeinsam beantworten, da mir ein 
eingehen auf einzelne zu mühsam ist und es vermutlich eh keine Einsicht 
bringt.

Ich habe weder ärger mit dem Chef, noch sonst etwas. Ich habe keinen 
Chef. Ich bin der Chef.

Ich habe in meinem Leben schätzungsweise Millionen von Zeilen 
Assemblercode programmiert und das weder zu Hobby oder anderen privaten 
Zwecken, sondern in Bereichen der Industrie, wo dies unumgänglich ist. 
Es gibt nämlich mannigfache  Gründe so etwas zu tun, auch wenn dem einen 
oder anderen hier die Einblicke fehlen. Nicht zuletzt ein Grund warum 
Atmel diese AppNote überhaupt herausgibt. Was übrigens auch die anderen 
Compilerbauer so machen. Die Schnittstellen zwischen Assembler und C 
oder gar C++ sind essentiell für einen Compiler.

Der TO hatte eine ganz konkrete Frage, sich sogar die entsprechende 
AppNote herausgesucht. Das bedeutet doch unzweifelhaft dass er eben 
diese Frage gerne beantwortet hat. Er hat weder nach der Sinnhaftigkeit 
dieses Vorgehens  gefragt, noch danach ob generell das Mischen der 
beiden Sprachen sinnvoll ist.

Diese Frage wurde mit viel Prosa beantwortet, an der Teile korrekt waren 
und andere eben nicht. Darauf hatte ich bereits hingewiesen. Kein 
Einziger hat die eigentliche Frage beantwortet, so das der TO sein 
Problem lösen konnte.  Die Frage wurde vielmehr so beantwortet, mit in 
die Irre führenden Hinweisen, man müsse z.B. eine main() Funktion in „C“ 
zwingenderweise implementieren, das der TO am Ende mehr oder weniger 
aufgegeben hat.

Dafür gab es Äußerungen wie:

„Klar, wofür auch?“

„Das Ding ist doch ein Primitiv-Assembler“

„aber der hat halt rundum
eine andere Syntax als der von Atmel“

Das sind Aussagen die inhaltlich falsch, degradierend und nicht 
zielführend sind und zudem eines Moderators nicht würdig. Der Code lässt 
sich leicht portieren und der Assembler -ist im Gegensatz zu der 
Aussage- nicht primitiv. Er macht genau das was ein Assembler können 
muss.

Ich habe dem TO ein einfaches funktionierendes Beispiel gegeben welches 
zweifelsohne Funktioniert, ohne main() Funktion in „C“.  Dass 
anschließend jemand kommt und dem funktionierenden Beispiel –das seiner 
eigenen vorherigen Aussage gar nicht hätte funktionieren können- 
unterstellt das es Sinnfrei ist und durch 3 Zeilen „C“ Code ersetzt 
werden kann ist wirklich Lachhaft. Ein Beispiel ist in der Regel 
Sinnfrei und ließe sich demnach regelhaft auf Null reduzieren.
Dieses Beispiel beantwortet aber in einfacher Weise die gestellte Frage 
und das ist der essentielle und einfache Sinn einer Antwort auf eine 
konkrete Frage.

Für mich ist an dieser Stelle diese alberne Diskussion Assembler und „C“ 
beendet. Die Frage ist beantwortet und wenn der TO noch eine Frage zum 
Problem hat oder Hilfe benötigt bitte  eine PM Schreiben.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas H. schrieb:

> Der Code lässt
> sich leicht portieren

Das kann man erst beantworten, nachdem man den Code gesehen hat.

Klar benutzen beide die gleichen AVR-Befehle, aber im gesamten
Bereich der Pseudo-Anweisungen unterscheiden sie sich, und auch in
vielen anderen Details (Registerpaare, Wort-Adress-Behandlung,
Behandlung der IO-Port-Namen).

Je nachdem, wie der Code gezimmert ist, kann man also einiges an
Aufwand reinstecken, den auf den anderen Assembler zu portieren.
BTDT.

> und der Assembler -ist im Gegensatz zu der
> Aussage- nicht primitiv.

Er ist dahingehend primitiv, dass er keinen verschieblichen Objektcode
generieren kann, den man zusammen mit anderen Objektmodulen linken
könnte.  Genau das benötigt man aber, wenn man den Assemblercode
gemeinsam mit C-Code benutzen will in einem Projekt, und genau darum
ging es in der Frage (und genau deshalb kann er auch kein .extern
kennen).

Warum ich das als „primitiv“ bezeichne?  Weil bessere Lösungen schon
vor 40 Jahren existiert haben (und die liefen auf viel kleineren
Maschinen) und es nicht verständlich ist, warum Atmel Jahrzehnte später
noch mit sowas aufwarten musste.  Ob du das nun „degradierend“
empfindest, ist mir eigentlich egal – es ist meine Meinung, und ich
habe sie dir hiermit auch begründen können.

: Bearbeitet durch Moderator
von Ralf G. (ralg)


Lesenswert?

Thomas H. schrieb:
> Der TO hatte eine ganz konkrete Frage, sich sogar die entsprechende
> AppNote herausgesucht. Das bedeutet doch unzweifelhaft dass er eben
> diese Frage gerne beantwortet hat. Er hat weder nach der Sinnhaftigkeit
> dieses Vorgehens  gefragt, noch danach ob generell das Mischen der
> beiden Sprachen sinnvoll ist.

Ein Hinterfragen sollte doch mal möglich sein.
Beispiel:
Dich fragt jemand, ob er lieber von der Brücke oder sturzbetrunken ins 
Meer springen soll. Wie lautet deine zielführende Antwort?
(Ich weiß: Gehört hier nicht her!)

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Ralf G. schrieb:
> Ein Hinterfragen sollte doch mal möglich sein.
> Beispiel:
> Dich fragt jemand, ob er lieber von der Brücke oder sturzbetrunken ins
> Meer springen soll. Wie lautet deine zielführende Antwort?
> (Ich weiß: Gehört hier nicht her!)

Nun jemand der in suizidaler Absicht nach der besten Art des Suizides 
fragt hat meiner Meinung auch eine Antwort auf seine Frage verdient. Der 
Freitod aufgrund nicht kurativ
behandelbarer Leiden ist schließlich Gegenstand diverser, auch 
politischer Diskussionen. Hier sollte jemandem der fest entschlossen ist 
seinem Leben ein Ende zu bereiten durchaus der humanste und schmerz- und 
leidensfreiste Weg aufgezeigt werden. Das wäre unter den zwei zur 
Auswahl gestellten Wegen sicher der Weg mit der vorher stattgefundenen 
Äthyltoxischen Sedierung und dem anschließenden Sprung ins kalte Wasser. 
Mit viel Glück kommt es dann zu einer Vasovagalen Reaktion mit 
konsekutivem Kreislaufstillstand. Das geht schnell und ist mit wenig 
leiden verbunden. Wohingegen Sprünge von einer Brücke oft daneben gehen, 
weil entweder die Höhe zu gering gewählt wurde, oder der Suizidant noch 
vor dem Fall der gesamten Höhe mit anderen Hindernissen Kollidiert. 
Nicht selten, werden solche Personen noch lebend und mit teilweise oder 
zur Gänze abgetrennten Gliedmaßen aufgefunden und befinden sich in einer 
entsprechenden Schmerzsituation.
Man kann solche, z.B. Krebskranken Menschen natürlich auch volllabern 
und ihnen sagen das sei alles nicht ganz so schlimm und es vielleicht 
doch besser wäre langsam dahin zu siechen, zu verrotten und zu verwesen 
am lebendigen Leibe usw.., aber das ist letzten Endes eine 
philosophische Frage und genau deshalb ist der Vergleich einer Frage 
nach einer etablierten Technologie und der Form eines Suizides selten 
dämlich und gehört wie von ihnen festgestellt nicht hierhin. Aber ich 
bin immer bemüht anderen etwas beizubringen. Und ich hoffe ich konnte 
ihnen vermitteln das die Art und Weise wie eine Selbsttötung ausgeführt 
wird durchaus nicht irrelevant ist.

Ein sinnigerer Vergleich wäre gewesen zu Fragen was ich mache, wenn ich 
abends auf der Straße von einem Paar, welches auf der Suche nach dem 
nahegelegenen Theater ist und bereits die Karten für die 
Abendvorstellung in der Hand hat , weil Sie zu Ihrem Hochzeitstag ein 
lange ersehntes Theaterstück sehen wollen, nach dem Weg gefragt werde.

Ich könnte Ihnen (A) einfach die Frage beantworten und Ihnen den Weg 
beschreiben.
Ich könnte ihnen (B) lang und breit erklären das Sie doch besser was 
anders machen, weil ich finde das dieses Theaterstück nicht besonders 
gut ist und der Meinung bin das man eh in seiner Freizeit andere Dinge 
macht, anstatt ins Theater zu gehen.

Meine klare Antwort ist (A) Denn das ist Zielführend im Sinne der Frage.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Jörg W. schrieb:
> Das kann man erst beantworten, nachdem man den Code gesehen hat.
>
> Klar benutzen beide die gleichen AVR-Befehle, aber im gesamten
> Bereich der Pseudo-Anweisungen unterscheiden sie sich, und auch in
> vielen anderen Details (Registerpaare, Wort-Adress-Behandlung,
> Behandlung der IO-Port-Namen).

Nein das geht auch zu beantworten ohne den den Code gesehen zu haben!

Gefragt wäre hier eine Portierung von einem,ich Zitiere „primitiven 
System“ zu einem besseren. Diese Art der Portierung ist per se 
einfacher.

Die Portierung von AVR-Assembler Code zu GCC kann mit Copy&Pate und der 
einfachen Such und Ersetzen Funktion der Gängigen Code-Editoren 
bewerkstelligt werden. Die wesentlichen Dinge die geändert werden müssen 
bei den Direktiven zwischen den beiden Assemblern sind folgende:

GCC:                           Atmel AVR:
hi8                            high
lo8                            low
.asciz “hello”                 .db “hello”, 0
.section                       .data .dseg
.section                       .text .cseg
<avr/io.h>                     “m32def.inc”



Ein Beispiel zur Portierung eines kurzen AVR-Assembler Codes


AVR-CODE
1
        .include “m32def.inc”
2
        .cseg
3
        .org 0
4
         rjmp main
5
        .org 0x2A
6
main:    ldi r16, 0xff
7
         out DDRB, r16
8
         ldi r16, high(RAMEND-0x20)
9
         out SPH, r16
10
         ldi r16, low(RAMEND-0x20)
11
         out SPL, r16
12
         sei
13
         rcall lcd_init
14
         ldi ZH, high(message)
15
         ldi ZL, low(message)
16
         rcall prtmsg
17
quit:    rjmp quit
18
prtmsg:  lpm r24, Z+
19
         cpi r24, 0
20
         breq exit
21
         rcall lcd_print_char
22
         rjmp prtmsg
23
exit:    ret
24
message: .db “hallo”, 0


Das ganze muss also lediglich wie folgt geändert werden damit es GCC 
Kompatibel ist:

1
#include <avr/io.h>
2
#define __SFR_OFFSET 0
3
          .section .data
4
          .org 0x0
5
message:  .asciz "hallo"
6
          .section .text
7
          .global main
8
9
main:     ldi r16, 0xff
10
          out DDRB, r16
11
          ldi r16, hi8(RAMEND-0x20)
12
          out SPH, r16
13
          ldi r16, lo8(RAMEND-0x20)
14
          out SPL, r16
15
          sei
16
          rcall lcd_init
17
          ldi XH, hi8(message)
18
          ldi XL, lo8(message)
19
          rcall prtmsg
20
quit:     rjmp quit
21
prtmsg:   ld r24, X+
22
          cpi r24, 0
23
          breq done
24
          rcall lcd_print_char
25
          rjmp prtmsg


Das ist mit search&replace in 2 minuten getan und das ist unabhängig 
davon ob der Code 20 Zeilen oder 20000 hat,  es geht gerade mal darum 6, 
oder 7 Dinge zu ändern.

Jörg W. schrieb:
> Je nachdem, wie der Code gezimmert ist, kann man also einiges an
> Aufwand reinstecken, den auf den anderen Assembler zu portieren.
> BTDT

Jetzt ist in der Tat meine Neugierde geweckt!  Und ich wäre jetzt 
natürlich sehr an einem Beispiel interessiert wie ein Code gezimmert 
sein muss, damit eine Portierung von AVR-Assembler zu GCC einiges an 
Aufwand kosten würde.

: Bearbeitet durch User
von Ralf G. (ralg)


Lesenswert?

Thomas H. schrieb:
> Hier sollte jemandem der fest entschlossen ist
> seinem Leben ein Ende zu bereiten durchaus der humanste und schmerz- und
> leidensfreiste Weg aufgezeigt werden. Das wäre unter den zwei zur
> Auswahl gestellten Wegen sicher der Weg mit der vorher stattgefundenen
> Äthyltoxischen Sedierung und dem anschließenden Sprung ins kalte Wasser.

Ist doch richtig! Nur, wenn du den Grund für seinen Freitod nicht 
kennst, dann solltest du erstmal nachfragen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas H. schrieb:
> Jetzt ist in der Tat meine Neugierde geweckt!  Und ich wäre jetzt
> natürlich sehr an einem Beispiel interessiert wie ein Code gezimmert
> sein muss, damit eine Portierung von AVR-Assembler zu GCC einiges an
> Aufwand kosten würde.

Kann ich dir leider nicht mehr so genau sagen, war meiner Erinnerung
nach mal Code aus einer Atmel-Appnote.  Ich war da auch erstmal
rangegangen mit: „Bisschen Suchen&Ersetzen, kann ja nicht so schlimm
sein.“

Zusätzlich kommt ja beim TE noch hinzu, dass er sich dann um die
Aufrufsequenzen (Registerbenutzung, Parameterübergabe) für den aus
C heraus generierten Code kümmern muss.  Wenn man nicht vorsätzlich
seinen Assemblercode bereits aufrufkompatibel dazu schreibt, kann das
auch nochmal einiges an Aufwand werden.

Da wir von Adib aber in diesem Thread ohnehin nichts mehr gehört haben,
hat sich die Angelegenheit wohl vorerst erledigt.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Ralf G. schrieb:
> Ist doch richtig! Nur, wenn du den Grund für seinen Freitod nicht
> kennst, dann solltest du erstmal nachfragen.

Nun dieses Beispiel ist als Vergleich zur Fragesituation des TO -ich 
hatte bereits darauf hingewiesen- inadäquat. Deshalb brachte ich das 
andere Beispiel ins Gespräch.

: Bearbeitet durch User
von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Jörg W. schrieb:

> Zusätzlich kommt ja beim TE noch hinzu, dass er sich dann um die
> Aufrufsequenzen (Registerbenutzung, Parameterübergabe) für den aus C
> heraus generierten Code kümmern muss.  Wenn man nicht vorsätzlich seinen
> Assemblercode bereits aufrufkompatibel dazu schreibt, kann das auch
> nochmal einiges an Aufwand werden.
>


Dass ist in der Tat richtig. Ich bin (gehe) davon aus das er dies aber 
getan hat, offensichtlich war er ja fest entschlossen das so umzusetzen. 
Die Konventionen sind in der AppNote die er zitierte ja beschrieben. 
Wenn er das nicht getan hat und sein Code ist umfangreich hätte er 
tatsächlich einiges zu tun.

: Bearbeitet durch User
von Adib (Gast)


Lesenswert?

Hallo Leute,

ich hatte in der Vergangenheit schon mal ein Assemblerprojekt mit 
existierendem C-Code erweitert. Das war aber ein 8051-Keil-A51/C51 
Projekt. Ich habe einen Wrapper geschrieben, der die Register 
ensprechend des Aufrufsyntax sichert, setzt und wiederherstellt. Das hat 
alles wie erwartet funktioniert.
Dass die Atmel Toolchain 2 unterschiedliche Möglichkeiten für Assembler 
Code bietet, hatte ich nicht bedacht.
Ihr habt mir aber bei der Entscheidungsfindung, wie jetzt mit dem 
Projekt weiter zu verfahren ist, auf alle Fälle geholfen.

Meine Frage zu der möglichen Länge der Labels 
Beitrag "GCC AVR ASM max. Anzahl Zeichen pro Label?" bezog sich auch auf diesen 
Code. Die Frage war also komplett falsch gestellt. Es war der AVRASM 
gemeint. Lokale Labels (also Labels beginnend mit einer Zahl) werfen 
auch einen Syntaxerror....

Nochmal vielen Dank für die viele Zeit, die ihr einsetzt für das 
Beantworten der Fragen der Anderen.

Adib.
--

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Adib schrieb:
> Ihr habt mir aber bei der Entscheidungsfindung, wie jetzt mit dem
> Projekt weiter zu verfahren ist, auf alle Fälle geholfen.

Dann würden sich sicher alle, die versucht haben zu helfen, gegenseitig 
Diskutiert haben oder sich beschimpft haben freuen wenn Du uns sagst wie 
es weiter geht. Denn auch Leute die Fragen beantworten lernen.....

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Adib schrieb:
> Lokale Labels (also Labels beginnend mit einer Zahl) werfen auch einen
> Syntaxerror....

Ja, das ist eine Eigenheit der Unix-Assembler, die auf die mal von
AT&T geschaffene Syntax zurückgeht.  Der GNU-Assembler (gas) ist zu
dieser Syntax kompatibel, daher haben wir das dann für den AVR-GCC
geerbt.

von Adib (Gast)


Lesenswert?

Thomas H. schrieb:
> Dann würden sich sicher alle, die versucht haben zu helfen, gegenseitig
> Diskutiert haben oder sich beschimpft haben freuen wenn Du uns sagst wie
> es weiter geht. Denn auch Leute die Fragen beantworten lernen.....

Hallo Thomas,

... eigentlich wollte ich das nicht ausufern lassen und als Troll gelten 
...

Die Ausgangssituation: Der Programmierer verlässt die Firma und 
hinterlässt merere (gewachsene) Assembler-Projekte mit unterschiedlicher 
Komplexität. Die Dateien sind zwischen 3000 und 6000 Zeilen lang. Die 
Programmstruktur nicht dokumentiert. Jediglich die Codesequenzen sind 
kommentiert, wenigstens was. Die anderen 3 Kollegen programmieren 
ausschliesslich C (u.U. mit Assembler-Sequenzen).
Nun müssen Änderungen an den ASsemblerprojekten gemacht werden ....
Der Plan war: Jetz: Möglichst wenig ändern und nur die nötigen neuen 
Funktionen implementieren. Wenn möglich in C. Später: evtl. Schrittweise 
Portieren in C oder neucodieren in C.

Erkenntisse: 1) Das mit dem "jediglich neue Funktionen in C 
implementieren" ist erst mal vom Tisch. Es wird in den 
Assembler-Quelltext reinprogrammiert.
Es ist selbst bei den 3000 Zeilen nicht richtig zu erkennen, welche 
Prämissen der Quelltext setzt. Und ob die neuen Funktionen nicht derart 
in das Programm eingreifen, dass andere Funktionen nicht gehen.
2) das schrittweise Refaktorieren sparen wir uns auch lieber und
3) investieren lieber die verbleibende Zeit bis zur nächsten Anpassung 
in das Neuschreiben in C mit einer Dokumentation der Programmstruktur.

Besser wären die Voraussetzungen: wenn es nur ein Programmiersystem 
gegeben hätte. Assembler, Compiler, Linker (wie beim Keil A51/C51). 
Nicht zu vergessen vom System der "persöhnlichen" Projekte; Nur ein 
Mitarbeiter bekommt das Projekt zugeordnet. Der Chef interresiert sich 
nicht um das Wie bei der Programmierung. Die Welt ist halt nicht perfekt 
...
Das soll jetzt auch keine Breitseite gegen Assemblerprogrammierung sein. 
Wenn man halt ein Assemblerprogramm und ein C-Programm schreibt, 
arbeitet man auf ganz anderen Abstraktionsebenen und die sind am Ende 
schwer zusammenzuführen. Ich schreibe ja kein C-Programm mit lauter 
globalen Variablen und Funktionsaufrufen (fast) ohne Parameter.
Für mich persöhnlich bedeutet Assembler-Programmierung gegenüber C: 
höherer Codieraufwand, schlechtere Wartbarkeit, keine Standard 
Unit-Tests, schlechte Wiederverwertbarkeit, Neuprogrammierung für jedes 
Target (AVR, ARM, PC). Unter gewissen Umständen nehme ich das in Kauf: 
Laufzeitverhalten, Generieren spezieller Befehlssequenzen, Codegröße.

Soweit von meiner Seite,

schönes WE,

Adib.
--

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Hallo Adib,

Vielen dank für die Mühe und das abschließende Aufklären über das 
eigentliche Problem. Das ist in der Tat multifaktoriell komplex und da 
der Assemblercode nicht von Beginn an in der Absicht der der 
"Mischbarkeit" erstellt wurde und zudem nicht durchgehend kommentiert 
ist wird es auch keine nichtkomplexe Lösung geben können. Euer Vorgehen 
ist deshalb sicher sinnvoll. Einzelkommentare  zu "C" oder Assembler zu 
deinen aufgezählten Punkten möchte ich hier öffentlich nicht geben, das 
gibt nur Sinnlose Diskussionen. Ich komme aus einem Bereich wo aus 
diversen Gründen sehr viel alternativlos in Assembler gemacht werden 
muss. Ich würde aber auch in anderen Bereichen keinen Programmierer für 
Embeded Systeme einstellen der nicht auch perfekt Assembler für die 
eingesetzten Typen beherrscht.

Ebenfalls ein schönes WE

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.