Hallo Leute, bin grad dabei ein Assembler-Projekt in ein C-Projekt umzuprogrammieren. Da ich nicht so der Assemblerkünstler bin habe ich da meine probleme. Ich bräuchte ein paar tipps wie ich am besten anfangen soll bzw. dann auch weitermachen. Hab jetzt schon mittlerweile die ganzen .equ,..., usw. als makros in C und fange jetzt an die ganzen Funktionen zu übersetzen. Das Assembler-Projekt läuft auf einem ATmega169 Controller und soll auch in C auf diesem Controller laufen. Jede art von Rat und Hilfe sind mir willkommen ingmar
Gast
#2788196
Ingmar H. schrieb: > Jede art von Rat und Hilfe sind mir willkommen man sollte verstehen was Programm macht und es dann NEU in C schreiben. eine umsetzung von ASM zu C macht wenig sinn auf codebasis.
was das programm macht versteh ich schon... ich hab jetzt z.B. probleme
den
code richtig zu übersetzen weil es doch so ein paar unterschiede gibt.
Beispiel:
PUSH AKKU_1
PUSH AKKU_2
LD AKKU_1, X
INC XL
LD AKKU_2, X
DEC XL
CALL DISP_HEX
POP AKKU_2
POP AKKU_1
********************************************************************
LDI ZL, LOW(ST_OFFSET*2)
LDI ZH, HIGH(ST_OFFSET*2)
***********************************************************************
PUSH und POP kann ich verachlässigen oder??
wie würde LD AKKU_1, X und
LDI ZL, LOW(ST_OFFSET*2) in C aussehen?
Gast
#2788240
Ingmar H. schrieb: > was das programm macht versteh ich schon Ja also, dann kannst du ja wohl auch die Funktionalität in C programmieren.
Gast
#2788241
Ingmar H. schrieb: > LD AKKU_1, X http://www.atmel.com/Images/doc0856.pdf Im übrigen: Vergiß es. Peter II schrieb: > eine umsetzung von ASM zu C macht wenig sinn auf codebasis. So ist es. Oliver
Gast
#2788257
Ich schließe mich den Vorrednern an. In Assembler arbeitest du mit Registern, dem Akku (sofern vorhanden) und ein paar Speicherstellen). In C arbeitest du mit Variablen (= Speicherstellen), und nicht mit den Registern. Das nimmt dir der C-Compiler ab. Du sagst du weisst was das Programm macht. Dann notiere dir dazu den PAP (Programm-Ablauf-Plan) oder etwas äquivalentes, was dir eben den Ablauf passiert, aber auf Basis des "was passiert", nicht "wie's passiert". An deinem o.g. Code-Auszug wäre das dann also nicht "Lade Akku nach...", etc., sondern "Zeige auf Display in Hex-Darstellung" (dem Call nach zu urteilen). Wenn du das gemacht hast, dann hast du eine von der Sprache unabhängige Beschreibung des Programms. Und das wiederum setzt du dann in C um:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Ralf
Gast
#2788261
Ingmar H. schrieb: > PUSH und POP kann ich verachlässigen oder?? > wie würde LD AKKU_1, X und > LDI ZL, LOW(ST_OFFSET*2) in C aussehen? Falls es dir noch nicht klar ist: Du musst die Funktionalität nachbilden, nicht den Maschinencode. Der hier gezeigte Codeausschnitt könnte mit der Standardfunktion printf() nachgebildet werden, odet du linkst deine uart Bibliothek dazu und verwendest deine uart_putc() Funktion oder ... du verstehst wie ich's meine?!
Wenn Du grundlegende Probleme mit Assembler hast, solltest Du Dich vielleicht erst mal in einen Assembler einarbeiten, bevor Du C programmierst. C ist keine Hochsprache, es ist eine Art "Makro-Assembler". Arrays gibts in C nicht, das sind nur Zeiger, und wenn Du über das Ende hinaus zugreifst, greifst Du auf was auch immer dahinter liegt zu. Wenn Dein Array auf dem Stack liegt (z.Bsp. bei lokalen Variablen) so liegt nach dem Array die Rücksprungadresse. Falls Du aber wirklich eine 1:1 Umsetzung haben willst, dann scheibe Dir doch einfach ein Programm, welches das macht. Im Prinzip musst Du nur das Programm zeilenweise einlesen, und die Kommentare entfernen, sowie den #includes folgen. #defines kannst Du als Makros übersetzen. Zeilen mit .cseg und .dseg Schalten zwischen Programmspeicher und Datenspeicher um. Abhängig davon musst Du bei Labels entweder Sprunglabels in C oder Variablen anlegen. Gut ist das dann nicht, aber die Aufgabe wäre erfüllt. Ich würde aber in Deiner Situation mir 90% der Zeit nehmen den existierenden Code zu verstehen, und ihn in der restlichen Zeit neu implementieren. Danach wirst Du besseren C-Code schreiben als vorher.
onno und Christian Berger. Könnt ihr euch bitte mit eurem Halbwissen über C verziehen? Das gilt ganz besonders für onno. Danke.
Ingmar H. schrieb: > was das programm macht versteh ich schon... ich hab jetzt z.B. probleme > den > code richtig zu übersetzen weil es doch so ein paar unterschiede gibt. > > Beispiel: > > PUSH AKKU_1 > PUSH AKKU_2 > LD AKKU_1, X > INC XL > LD AKKU_2, X > DEC XL > CALL DISP_HEX > POP AKKU_2 > POP AKKU_1 Das lässt sich so nicht "übersetzen". Hier wird ein 16-Bit Wert indirekt über X geladen und vermutlich an DISP_HEX übergeben. Ob der Wert übergeben wird — d.h. in DISP_HEX verwendet wird — ist an dem Code nicht zu sehen, ebenso ob DISP_HEX etwas zurückliefert oder Seiteneffekte hat. Die Registerzuordnung in einem C-Programm erledigt der Compiler. Das ist ja auch einer der Gründe, eine Compiler einzusetzen :-) Einen 16-Bit Wert aus dem RAM zu lesen und damit eine Funktion aufzurufen sieht in C so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
und avr-gcc übersetzt das zB so:
1 | |
2 | |
3 | |
4 | |
5 | |
Du kannst also versuchen, dieses kleine C-Beispiel zu verstehen und auf deinen Fall anzupassen oder in eine größere Funktion einzubette. > LDI ZL, LOW(ST_OFFSET*2) > LDI ZH, HIGH(ST_OFFSET*2) Dieses Beipiel ist mindestend genauso übel. Ist der nach Z geladene Wert eine Adresse? Oder eine Konstante, die zur Compilezeit bekannt ist? Oder der Index in ein Array aus 16-Bit Werten? Im einfachsten Fall ist der C-Code
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
und wird zu:
1 | |
2 | |
3 | |
4 | |
Die Registerzuordnung ist wie gesagt Aufgabe des Compilers. Ist ST_OFFSET ein Index in ein 16-Bit Array, und wird auf dem Array an dieser Stelle gelesen, dann:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
und das compiliert zu
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Als erstes musst du also das Programm abstrahieren und von der konkreten Registerverwendung, den Instruktionen, etc. loskommen und dir klarmachen • Welche (globalen) Objekte und Datenstrukturen gibt es? • Welche Funktion erfüllt welche Aufgaben? • Welche Parameter bekommen die Funktionen? • Und was geben sie zurückgeben? • Welche globalen Variablen werden sie (falls überhaupt) • Wie werden asynchrone Ereignisse (IRQs) verdaut? • Was ist eine sinnvolle Strukturierung von alledem?
Danke ich werds versuchen umzusetzen....
Gast
#2794451
@ Christian Berger Seit wann ist C keine Hochsprache ? Eine Hochsprache ist jede Programmiersprache die über Assembler hinausgeht. Arrays als Datenstruktur gibt es sehr wohl in C. Man kann aber beispielsweise einen C-String in Form eines Arrays anlegen
1 | |
zum durchlaufen index inkrementieren bzw. dekrementieren (Index entspricht Speicheradresse). oder so:
1 | |
hier pointer inkrementieren bzw. dekrementieren. über sizeof(hallo)/sizeof(char) überlauf abfangen. gruß R2D2
Gast
#2795917
Man kann wie oben schon geschrieben, einfach nur die Funktionalität nachahmen, ohne groß auf den Assemblercode zu gucken. Wenn man aber z.B. wissen möchte, welcher Algorithmus eingesetzt wird, oder ob Hardware"tricksereien" (Hardwareverständnis) im Spiel sind o.ä. dann sollte man möglichst den Algo kennen, wie auch Assemblergrundlagen zum Lesen des Asm-Codes. Ich würde die Gelegenheit beim Schopfe packen, und gleich Assemblergrundlagen lernen und mit der Aufgabe vertiefen. Und man versteht den Assemblercode oft sehr viel besser, wenn man weiß, um was es geht. Assembler lernt sich normalerweise leicht und schnell, weil ja kaum Abstrakta im Spiel sind. Nur ein wenig Zeit sollte man sich geben und die ein oder andere, grundlegende Lowlevelsubroutine verstanden haben. Einzelne Funktionen kann man sich isoliert im Debugger angucken und versuchen, besser zu verstehen. Und auch im Manual des jeweiligen Assemblers lassen sich meist wertvolle Hilfen zum Programmverständnis oder Programmiertechniken finden. )Und wenn die Assemblerroutine sehr gut ist, warum dann nicht drinlassen und von C aus aufrufen? --> hier spielt auch das "Warum" von Asm nach C eine gewisse Rolle und in dem gleichen Zusammenhang auch die Nützlichkeit von C zurück nach Asm)
Gast
#2795952
Peter II schrieb: > man sollte verstehen was Programm macht und es dann NEU in C schreiben. > eine umsetzung von ASM zu C macht wenig sinn auf codebasis. Abgesehen von der Rechtschreibung, ist das die einzig richtige Einschätzung der Sachlage.
Gast
#2798032
Es gab auch mal einen generellen Dr. Dobbs Guru Blog Artikel von Walter Bright zu diesem Thema, die Seite finde ich gerade nicht, aber hier der betreffende Inhalt: http://www.allhatter.com/archive/index.php/t-33853.html
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.