Hallo liebe Gemeinde, ich programmiere auf einem Atmega324 in Assembler und habe da letztens im Netz irgendwo her eine interessante Variante gefunden um Sprungweiten zu definieren. In dem Beispiel: brne pc+2 ist das Sprungziel statt einem Label/Sprungmarke einfach der aktuelle stand des Programmcounters+2...d.h der nachfolgende Befehl wird nicht ausgeführt,wenn die Bedingung nicht wahr ist. Damit kann man z.B. sehr kompakt Bedingungen auswerten....allerdings ist mir aufgefallen, dass die Sprungweite nicht gleich der Anzahl der zu überspringenden Befehle ist!? Ich hab die Vermutung das dies an der unterschiedlichen Länge der Op- codes liegt, wenn diese in den Flash abgelegt werden. Bei folgenden Beispiel sollte man annehmen das der Sprung auf "rcall bedingung_nicht_wahr" erfolgt,allerdings landet man promt auf "ret", weshalb man hier eine Sprungweite von pc+5 angeben müsste. brne pc+4 ldi r17,1 sts status,r17 ret rcall bedingung_nicht_wahr Hingegen funktioniert dieses Beispiel gut: brne pc+2 ret rcall bedingung_nicht_wahr Vielleicht hat sich jemand schon näher damit befasst und kann mir ein paar Tips geben,um die Sprungweite in jedem Fall genau berechnen zu können? Vielen Dank fürs lesen!!!
Das ist nicht interessant, sondern einfach nur unübersichtlicher bullshit, du merkst selbst wie du damit durch unterschiedliche Instruktiondlängen in die Bedroullie kommst. Schreibe am Ziel (also ggf. hinter der nächsten Instruktion) ein Label (Sprungmarke) hin und nenne die in deinem Branch (Sprunganweisung) und alles wird gut. Man wird nicht zum Held bloss weil man partout alles schlechter machen will als Millionen andere Leute.
Jaja, das musste man früher mal so machen, als die Assembler noch keine Forward Labels konnten - und niemand möchte das wiederhaben. Jeder moderne 2-Pass Assembler kommt auch mit Forward Labels klar und du musst nicht auswendig wissen, wieviele Bytes jeder einzelne Befehl hat.
:
Bearbeitet durch User
Hallo MaWin, da hast Du sicher Recht, ich hab mich immer sehr schwer sinnige Namen für die Label zu vergeben,fand es ehrlich gesagt gut eine Sprungweite anzugeben...allerdings geht es ja eben auch oft in die Hose im Gegensatz zu eindeutigen Sprungmarken ;-) Danke für Deine investierte Zeit :) Felix
Felix schrieb: > Tips geben,um die Sprungweite in jedem Fall genau berechnen zu können? Das Instruction Set Summary könnte das * die Adresse wird als Wortadresse berechnet * jeder deiner Befehle belegt 1 Wort, mit Ausnahme vom * STS, der belegt 2 Wörter Wie man alles unschwer am Assembler Listing File erkennen kann. ABER: MaWin hat recht. Das ist alles hauptsächlich dazu geeignet sich möglichst unelegant ins Knie zu schiessen. Oder willst du wirklich in einem Assembler Programm alle Adressen bei allen Branches kontrollieren, ob sie sich geändert haben, nur weil du irgendwo einen Befehl dazu gemacht hast? Sei froh, dass diese Zeit vorbei ist und jemand vor langer, langer Zeit die glorreiche Idee hatte, dass man Sprungziele auch mit einem Namen benennen kann und sich der Assembler den Offset auch selbst ausrechnen kann. Die Zahl der wilden Programmfehler ist dadurch von einem Tag auf den anderen drastisch gefallen.
Es sind vier Befehle, die zwei Worte belegen: sts, lds, jmp und call. Die kann man sich merken, und das ist auch nicht das Problem. Das Problem entsteht, wie bereits beschrieben, bei Programmänderungen; Befehle herauszunehmen oder hinzuzufügen ohne genaue Kontrolle der Programmumgebung führt zu stundenlanger Fehlersuche. Andererseits - ebendies, eine genaue Kontrolle des zu ändernden Bereichs, ist bei Assemblerprogrammierung zwingend; eine Frage der Disziplin.
Ja. Ja. Es ist Wochenende und wieder hat einer das geschnittene Brot erfunden.
Felix schrieb: > ich hab mich immer sehr schwer sinnige Namen > für die Label zu vergeben,fand es ehrlich gesagt gut eine Sprungweite > anzugeben Wie hat Herr Karlton so schön gesagt:"There are only two hard things in Computer Science: cache invalidation and naming things." Weil die Namensfindung schwierig ist, gleich gar keine Namen mehr zu vergeben ist ein "kreativer" Ansatz :)
Felix schrieb: > ist das Sprungziel statt einem Label/Sprungmarke einfach der aktuelle > stand des Programmcounters+2 Das ist auch keineswegs ein anderer Befehl, JMP PC+Dist ist genau das Gleiche wie JMP Label, nur rechnet beim Label der Assembler den Abstand selbst aus, und zwar immer richtig, sofern der Sprung überhaupt möglich ist. Man kann also nicht das geringste einsparen und verzichtet nur völlig unnötig auf Bedienkomfort, ganz abgesehen davon, dass man ein riesiges Fass an zusätzlichen Fehlern aufmacht (Gilt natürlich nicht für die Poster hier, die niemals einen Fehler machen und alle Befehle inklusive Byte- und Zyklenzahl im Kopf haben). Georg
@Klaus Was hat das mit dem Wochenende zutun? Die Woche neigt sich gerade zum WE,wir sind also noch in der Woche und Neugier zu teilen,dabei vielleicht altes zu erfahren ist keine schlechte Sache. Oftmals kann man durch das Gesamtbild besser Probleme lösen,man nennt dieses Gesamtbild auch Erfahrung... Viele User haben mir diese weitergereicht,dafür bin ich sehr dankbar! Ich weis nicht ob Du das verstehen kannst, aber ich erweitere meine Sichtweise gerne, denn ich möchte nicht zu den Leuten gehören deren Horizont einen Radius von 0 hat und diesen ihren Standpunkt nennen :) Schönen Freitag Abend noch ;-)
Ihn dünkt', er sähe einen Sprung, dahinter stand + 10. Er guckt' noch mal und merkt', es war, auch noch "pc" zu sehn. "Das, freilich, geht so nicht," sprach er, "hier muss ein Label stehn."
Felix schrieb: > ich hab mich immer sehr schwer sinnige Namen > für die Label zu vergeben Wenn Du Labels mehrfach vergibst, kriegst Du das von Assembler angemeckert, also kein Problem. Oder nimm den GAS des AVR-GCC, da kannst Du dann z.B. nach 1b, 2f usw. springen. https://sourceware.org/binutils/docs/as/Symbol-Names.html#Symbol-Names Siehe Local Labels
> Oder willst du wirklich in einem Assembler Programm alle > Adressen bei allen Branches kontrollieren, ob sie sich > geändert haben, nur weil du irgendwo einen Befehl dazu > gemacht hast? Um Missverständisse auszuschließen: es geht nicht um entweder/oder, sondern um sowohl/als auch. Normale Sprünge wird man immer mit Label ausführen, ein pc +- n ist nur sehr lokal beherrschbar, vielleicht mit n<6, spätestens bei 10 wird es schwierig. Aber ich bin wie Felix der Meinung, dass beim 'Auswerten kompakter Bedingungen' die Vielzahl der Label zu einer gewissen Unübersichtlichkeit führt.
Macht der ARM Cortex M4 ebenfalls: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/CHDDIGAC.html R15 ist identisch zum programm counter, das reduziert den Befehlssatz, da kein extra JMP implementiert werden muß. Durch die bedingte Ausführung der meisten ARM Befehle werden so bedingte Sprünge "im vorbeigehen" implementiert. MfG,
Felix schrieb: > brne pc+4 > ldi r17,1 > sts status,r17 > ret > rcall bedingung_nicht_wahr Wieso das ubersichtlicher und einfacher als Beispiel unten sein soll, wird mir niemals klar sein:
1 | brne b_false |
2 | ...
|
3 | ...
|
4 | ret
|
5 | b_false: |
6 | rcall bedingung_nicht_wahr |
S. Landolt schrieb: > Aber ich bin wie Felix der Meinung, dass beim 'Auswerten kompakter > Bedingungen' die Vielzahl der Label zu einer gewissen > Unübersichtlichkeit führt. Label trennt man normalerweise mit einer Leerzeile ( neues Block ) oder schreibt nur diese in eine Zeile mit CR/LF. Nur weil man keine Label in seinem Programm hat, wird es bestimmt nicht ubersichtlicher. Und wenn man ein bisschen weiter als LED-blinken kommt, wird es mit bedingten Sprungen von 2,3 oder sogar 60 Bytes nix. Und solltest du in deinem Beispiel irgendetwas andern, z.B. r17 retten (PUSH), wird es schon kritisch. Vielleicht ist das die einzige Stelle mit einem solchen Sprung - aber was ist wenn du weiter oben noch einen Sprung hast ? Felix schrieb: > Ich weis nicht ob Du das verstehen kannst, aber ich erweitere meine > Sichtweise gerne, denn ich möchte nicht zu den Leuten gehören deren > Horizont einen Radius von 0 hat und diesen ihren Standpunkt nennen :) Wie man mit so etwas unsinnigem sein Horizont erweitern kann, ist mir nicht ganz klar, aber wenn das trotzdem so ist, braucht dein Horizont wirklich dringend eine Erweiterung, nur hast du die falsche Richtung gewahlt...
:
Bearbeitet durch User
Hi
> oder schreibt nur diese in eine Zeile mit CR/LF.
Wo steht das? Bei mir sieht eine Assemblerzeile mit Label so
Label: Befehl :Kommentar
aus. Ich frag mich immer warum das alles an den linken Rand geklemmt
werden muss. Stammt wahrscheinlich aus den Zeiten mit Monitoren mit 20
Zeichen/Zeile.
Obwohl, zu DDR-Zeiten gab es schon für Assembler Formulare bei denen
alles in einer Zeile war.
MfG Spess
spess53 schrieb: > Wo steht das? Bei mir sieht eine Assemblerzeile mit Label so > > Label: Befehl :Kommentar Dann muss dein Compiler entweder sehr tolerant oder sehr schlau sein.
HI >Dann muss dein Compiler entweder sehr tolerant oder sehr schlau sein. Wieso? Wird vom AVR-Assembler problemlos Assembliert: http://www.mikrocontroller.net/attachment/highlight/43220 MfG Spess
spess53 schrieb: > HI > >>Dann muss dein Compiler entweder sehr tolerant oder sehr schlau sein. > > Wieso? Wird vom AVR-Assembler problemlos Assembliert: > > http://www.mikrocontroller.net/attachment/highlight/43220 > > MfG Spess spess53 schrieb: > Label: Befehl :Kommentar ^ | Doppelpunkt auch ?
Felix schrieb: > ich programmiere auf einem Atmega324 in Assembler und habe da letztens > im Netz irgendwo her eine interessante Variante gefunden um Sprungweiten > zu definieren. > > In dem Beispiel: > > brne pc+2 > > ist das Sprungziel statt einem Label/Sprungmarke einfach der aktuelle > stand des Programmcounters+2...d.h der nachfolgende Befehl wird nicht > ausgeführt,wenn die Bedingung nicht wahr ist. > Vielleicht hat sich jemand schon näher damit befasst und kann mir ein > paar > Tips geben,um die Sprungweite in jedem Fall genau berechnen zu können? Moin , die Frage bezieht sich auf unterschiedlich arten von Sprüngen resp Sprugzielen: 1) absolut 2) relativ Bei nummer 1 ist im sprungbefehl die Zieladdresse komplett angeben, bei 2 dagegen der Offset der zum aktuellen PC hinzuaddiert werden muß. Variante 1 benötigt den längeren Befehlscode da die absolute adresse eben 16 bit o.ä lang ist, während die relative Addresse mit weniger bits (bspw 8) auskommt. deshalb führt die verwendung von relativen Sprüngen zu kürzeren und schnelleren Code. Welche Sprungarten es nun gibt ist von CPU zu CPU unterschiedlich. Die älteren Semester erinnern sich sicher noch an x86 mit den Segmentregister, da müsste gut zwischen short jumps, und far jumps unterscheiden. http://x86.renejeschke.de/html/file_module_x86_id_147.html Bei absoluten Sprungzielen kann man das Ziel einfach mit einem Label markieren und der assembler ersetzt es mit der ermittelden Speicheraddressen. Bei relativen Sprüngen kommt es auf dem assembler an. bei manchen kann man in dem Memnomics mit absoluten Label arbeiten und der assembler rechnet das in den passenden relativen Sprung um. Oder man gibt anhand der Anzahl und länge der zu überspringenden Addressen selbst den Offset. Da hilft eine reference card , ein A4 Ausdruck mit einer Tabelle die die länge der einzelnen Befehle auflistet. Hat man früher auf karrierten Papier selbst geschrieben. Oft braucht man eine solche Tabelle garnicht da die Befehle bis aug einzelnen Ausnahmen (Sprünge mit absoluter adresse) gleich lang sind: https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set#Instruction_list Als 3 Möglichkeit die relative addresse zu bestimmen schaut man in das von assembler erzeugte adress listing, da steht nämlich zu jeden Befehl die Speicheraddresse, der rest ist kopfrechnen: http://www.avrfreaks.net/forum/how-do-you-view-assembly-listing-after-compile Richtig spannend sind die Möglichkeiten der PC-referenzierung bei 32bit RISC maschinen wie ARM. Da kann man nicht nur munter auf dem PC addieren sondern auch Unterprogrammrücksprungaddressen selbst verwalten (mv PC , r14). Und alle Instructionen sind gleich lang (32bit). Dort wird man aber eher selten den assemblercode selber schreiben, da genügt lesen können und das verständnis das PC = pc+2 nicht das selbe ist wie BRANCH ghjklabel. http://www.toves.org/books/armsub/ http://www.peter-cockerell.net/aalp/html/ch-2.html MfG, PS: Die Ausführungen unter dem Pseudonym MaWin gehen am Kern der Frage vorbei, deine Frage ist keinesfalls bullshit.
Georg schrieb: > Felix schrieb: >> ist das Sprungziel statt einem Label/Sprungmarke einfach der aktuelle >> stand des Programmcounters+2 > > Das ist auch keineswegs ein anderer Befehl, JMP PC+Dist ist genau das > Gleiche wie JMP Label, nur rechnet beim Label der Assembler den Abstand > selbst aus, und zwar immer richtig, sofern der Sprung überhaupt möglich > ist. Man kann also nicht das geringste einsparen und verzichtet nur > völlig unnötig auf Bedienkomfort, Stimmt so pauschal nicht, relative sprünge sind in der regel kürzer (1 instructionword) als Sprünge zu absoluten sprungzielen (2 instruction words) http://www.atmel.com/images/Atmel-0856-AVR-Instruction-Set-Manual.pdf S. 28 BREQ -> 16 bit Instruction S. 79 JUMP -> 32 bit Instruction Relative und absolute Sprünge sind zwei unterschiedliche Befehle. MfG,
Fpga Kuechle schrieb: > relative sprünge sind in der regel kürzer (1 > instructionword) als Sprünge zu absoluten sprungzielen (2 instruction > words) Ach, das ist mir jetzt völlig neu. Das Thema war: der TO hat eine alternative Schreibweise für Sprungziele entdeckt. Dass es sich dabei eben nur um eine Schreibweise handelt und sich am erzeugten Sprungbefehl garnichts ändert, wie ich geschrieben habe, ist also keineswegs der totale Blödsinn als das du das jetzt darstellst. Aber so eine Falschinterpretation ermöglicht es dir, einen total überflüssigen Monsterpost dazu zu plazieren, der nur deinem Ego dient. Glückwunsch. Vielleicht belehrst du uns noch über ein paar andere Selbstverständlichkeiten, nach denen niemand gefragt hat? Georg
Georg schrieb: > Vielleicht belehrst du uns noch über ein paar andere > Selbstverständlichkeiten, nach denen niemand gefragt hat? Gerne: Aus meinem Blickwinkel erhöht die Verwendung von Sprungzielbezeichnern die Lesbarkeit und damit die Wartbarkeit des Programms. Wenn jemand alleine im stillen Kämmerlein arbeitet, dann von mir aus, ohne Labels. Im Team, oder wenn man den Code irgendwo publizieren möchte, ist das schon (fast) eine Gemeinheit.
Georg schrieb: > Fpga Kuechle schrieb: >> relative sprünge sind in der regel kürzer (1 >> instructionword) als Sprünge zu absoluten sprungzielen (2 instruction >> words) > > Ach, das ist mir jetzt völlig neu. Das Thema war: der TO hat eine > alternative Schreibweise für Sprungziele entdeckt. Dass es sich dabei > eben nur um eine Schreibweise handelt und sich am erzeugten Sprungbefehl > garnichts ändert, wie ich geschrieben habe, ist also keineswegs der > totale Blödsinn als das du das jetzt darstellst. Nein das ist keine alternative Befehl-Schreibweise, das ist ein anderer Befehl. Schau den erzeugten ICode an. Es ist auch keine alternative Schreibweise für Sprungziele es ist kürzeres Sprungziel (8 bit) statt 16bit. Eben wie "8 und 16 bit" befehler, "char und int". Siehe auch http://stackoverflow.com/questions/4697877/relative-vs-absolute-jmp-in-assembly > Aber so eine Falschinterpretation ermöglicht es dir, einen total > überflüssigen Monsterpost dazu zu plazieren, der nur deinem Ego dient. Bleib mal locker, wenn Dich Computerarchitektur und mikrocontroller nicht interessiert dann ist das dein Problem - nicht meins. MfG,
Fpga Kuechle schrieb: > PS: > Die Ausführungen unter dem Pseudonym MaWin gehen am Kern der Frage > vorbei, deine Frage ist keinesfalls bullshit. Nein, deine total überflussigen und überlangen "Erklärungen" gehen am Kern der Frage vorbei, da TOs Frage mit Sicherheit bullshit ist. Warum sollte jemand bei klarem Verstand die Sprungbefehle so schreiben ? Fpga Kuechle schrieb: > S. 28 BREQ -> 16 bit Instruction > S. 79 JUMP -> 32 bit Instruction > > Relative und absolute Sprünge sind zwei unterschiedliche Befehle. Erstens: BREQ ist ein bedingter Sprung, geht nur bis -63/+64 und ist somit immer relativ. Zweitens: JMP für sich alleine ist auch kein absoluter Sprung, kann aber den gesammten FLASH abdecken. RJMP für sich alleine ist kein relativer Sprung, da er aber nicht den gesammten FLASH erreichen kann, sondern nur +/- 4KB, wird er relativ genannt. In beiden Fällen wird die angegebene Sprungmarke vom Assembler in eine Adresse umgerechnet und steht im HEX-File als absolute Adresse für JMP, als Offset für RJMP. Also, erst mal informieren und dann schreiben. Was du hier erfolglos mit vielen Wörtern und wenig Sinn zu erklären versuchst, ist wahrscheinlich relokativer code und das ist bei kleinen AVRs immer der Fall, also uninteressant in diesem Zusammenhang.
:
Bearbeitet durch User
Fpga Kuechle schrieb: >> Das ist auch keineswegs ein anderer Befehl, JMP PC+Dist ist genau das >> Gleiche wie JMP Label, nur rechnet beim Label der Assembler den Abstand >> selbst aus, und zwar immer richtig, sofern der Sprung überhaupt möglich >> ist. Man kann also nicht das geringste einsparen und verzichtet nur >> völlig unnötig auf Bedienkomfort, > > Stimmt so pauschal nicht, relative sprünge sind in der regel kürzer (1 > instructionword) als Sprünge zu absoluten sprungzielen (2 instruction > words) Ich glaube, die ganze Diskussion um absolute und relative Sprünge beruht auf einem Missverständnis: Der Name "PC" im AVR-Assembler von Atmel steht nicht etwa für das Programm-Counter-Register des Prozessors, sondern für den Adresszähler des Assemblers der während des Assemblierens hochgezählt wird. Das ist eine Softwarevariable auf dem Entwicklungsrechner und hat mit der AVR-Hardware nicht das Geringste zu tun. Deswegen liefern
1 | JMP PC+Dist |
und
1 | JMP Label |
bei gleichem Sprungziel tatsächlich den gleichen 32-Bit-Opcode mit absoluter Adressierung. Die Verwendung von "PC" Operanden ändert im generierten Code nicht die absolute in relative Adressierung, und die Addition von PC und Dist erfolgt nicht auf dem Ziel- sondern auf dem Entwicklungsrechner. Will man einen relativen Sprung, muss man den RJMP-Befehl verwenden. Beim Gnu-Assembler heißt das entsprechende Symbol nicht "PC", sondern ".", was meiner Meinung nach weniger missverständlich ist.
Marc Vesely schrieb: > Fpga Kuechle schrieb: >> PS: >> Die Ausführungen unter dem Pseudonym MaWin gehen am Kern der Frage >> vorbei, deine Frage ist keinesfalls bullshit. > > Nein, deine total überflussigen und überlangen "Erklärungen" gehen am > Kern der Frage vorbei, da TOs Frage mit Sicherheit bullshit ist. > Warum sollte jemand bei klarem Verstand die Sprungbefehle so > schreiben ? Weil sie ebenso geschrieben werden (können) (lt. mnemonic datenblatt) oder C-Compiler eben Assemblercode erzeugen der so ausschaut, Bspw aus Raspi. > BREQ ist ein bedingter Sprung, geht nur bis -63/+64 und ist somit > immer relativ. > JMP für sich alleine ist auch kein absoluter Sprung, kann aber den > gesammten FLASH abdecken. > RJMP für sich alleine ist kein relativer Sprung, da er aber *nicht* > den gesammten FLASH erreichen kann, sondern nur +/- 4KB, wird er > relativ genannt. ?alleine, nicht alleine? absolut| nicht absolut? Bedingt, nicht bedingt? Der TO fragt hier nach unterschiedlichen Sprung-"zielen", nicht nach bedingten oder unbedingten Sprung-"modi". Also stellt sich nur die Frage nach relativer (PC <- PC+x) und absoluter (PC <- K) Adressierung. Und da sollte man nicht behaupten das "springe label" das selbe wäre wie "Springe relativ". Spätestens wenn das Label auf eine Adresse verweist die ausserhalb der Sprungweite der relativen addressierung wird das dem TO böse auf die Füße fallen. > In beiden Fällen wird die angegebene Sprungmarke vom Assembler in > eine Adresse umgerechnet und steht im HEX-File als *absolute* > Adresse für JMP, als Offset für RJMP. > Also, erst mal informieren und dann schreiben. Link auf datenblatt übersehen? > > Was du hier erfolglos mit vielen Wörtern und wenig Sinn zu erklären > versuchst, ist wahrscheinlich relokativer code und das ist bei > kleinen AVRs immer der Fall, also uninteressant in diesem Zusammenhang. Das ist ein Aspekt der relativen Adressierung, aber nicht der einzige. Der Kern der Frage ist der Unterschied zwischen relativer Addressierung des Sprungziels und absoluter. Und aus dem subject dieses therads kann ich keine Einschränkung auf kleine AVR herauslesen, nicht mal Einschränkung auf AVR, denn da steht "Assembler Programmcounter". Deshalb ist es auch Falsch die Frage als "bullshit" abzutun weil man aus dem individuellen Erkenntnishorizont "kleine AVR" keine Anwendung parat hat. Und das es sich bei dem vom TO gezeigten Codeschnipsel explizit um lageunabhängigen Code handelt kann ich auch nicht erkennen. Ob der erwähnte Atmega324 ein "kleiner AVR" ist, ist ebenfalls strittig aber mindestens Geschmackssache. MfG,
Yalu X. schrieb: > > Ich glaube, die ganze Diskussion um absolute und relative Sprünge beruht > auf einem Missverständnis: Damit hast du IMHO nicht ganz unrecht. > Beim Gnu-Assembler heißt das entsprechende Symbol nicht "PC", sondern > ".", was meiner Meinung nach weniger missverständlich ist. Interessante neue Info, beim ARM-Assembler bedeudet dagegen PC tätsächlich den programm counter des Cores. http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0473c/CJAJBFHC.html Und bei (den meisten) ARM-Cores ist der PC genauso breit wie ein Instructionword und die GP-Regs. MfG,
Fpga Kuechle schrieb: > Macht der ARM Cortex M4 ebenfalls: > Durch die bedingte > Ausführung der meisten ARM Befehle werden so bedingte Sprünge "im > vorbeigehen" implementiert. Das trifft auf den klassischen ARM Befehlssatz zu, nicht aber auf dem Thumb2 Befehlssatz der Cortex M4.
Netterweise unterscheiden sich Atmels und GNUs Assembler nicht nur in der Syntax bei der Angabe der Befehlsadresse (PC v. "."): Atmel rechnet im Programadressraum in Worten, GNU aber in Bytes, weshalb die Distanzangabe in der GNU Variante doppelt so gross ist.
A. K. schrieb: > Netterweise unterscheiden sich Atmels und GNUs Assembler nicht nur in > der Syntax bei der Angabe der Befehlsadresse (PC v. "."): Atmel rechnet > im Programadressraum in Worten, GNU aber in Bytes Kann es sein, dass auch der Offset verschieden ist? Beim GNU-Assembler zeigt "." auf den Anfang des jeweils nächsten Befehls, beim Atmel-Assembler scheint PC auf den Anfang des aktuellen Befehls zu zeigen (s. Eröffnungsbeitrag). Ein JMP . bzw. JMP PC hätte also bei GNU außer dem Verbrauch von Taktzyklen überhaupt keinen Effekt, würde aber bei Atmel eine leere Endlosschleife erzeugen. Aber genau um solchen Problemen aus dem Weg zu gehen, benutzt man, wenn möglich, Labels. Der Assembler will ja auch ein Bisschen was zu tun bekommen.
:
Bearbeitet durch Moderator
Yalu X. schrieb: > Beim Gnu-Assembler heißt das entsprechende Symbol nicht "PC", sondern > ".", was meiner Meinung nach weniger missverständlich ist. "$" ist auch weniger missverständlich. Yalu X. schrieb: > Der Name "PC" im AVR-Assembler von Atmel steht nicht etwa für das > Programm-Counter-Register des Prozessors, sondern für den Adresszähler > des Assemblers der während des Assemblierens hochgezählt wird. Das ist > eine Softwarevariable auf dem Entwicklungsrechner und hat mit der > AVR-Hardware nicht das Geringste zu tun. Eigentlich schon, nur ist eben PC (Programm-Counter) in diesem Zusammenhang relativ ;-) PC+4 ist immer Programm Counter + 4, nur hat der PC nicht denselben Wert wenn mit .org 0x100 oder mit .org 0x200 assembliert wird. Yalu X. schrieb: > Kann es sein, dass auch der Offset verschieden ist? > > Beim GNU-Assembler zeigt "." auf den Anfang des jeweils nächsten > Befehls, beim Atmel-Assembler scheint PC auf den Anfang des aktuellen > Befehls zu zeigen (s. Eröffnungsbeitrag). Beim Atmel zeigt PC tatsachlich auf den Anfang des aktuellen Befehls. Ob das unlogisch ist, bleibt diskutabel, für mich ist es jedenfalls nicht, weil sich dieser RJMP auf aktuelles Befehl bezieht und der beginnt eben in dieser Zeile.
Yalu X. schrieb: > Beim GNU-Assembler zeigt "." auf den Anfang des jeweils nächsten > Befehls, Sicher? https://sourceware.org/binutils/docs/as/Dot.html#Dot
A. K. schrieb: > Fpga Kuechle schrieb: >> Macht der ARM Cortex M4 ebenfalls: > >> Durch die bedingte >> Ausführung der meisten ARM Befehle werden so bedingte Sprünge "im >> vorbeigehen" implementiert. > > Das trifft auf den klassischen ARM Befehlssatz zu, nicht aber auf dem > Thumb2 Befehlssatz der Cortex M4. Ebenso thumb2 der anderen Cortex etc, ebenso der Vorläufer "thumb". https://en.wikipedia.org/wiki/ARM_architecture#Thumb Wobei thumb ja eher ein "Betriebsmodus"/Feature ist in dem man die ARM's die thumb unterstützen betreiben kann, aber nicht muß. MfG,
A. K. schrieb: > Sicher? https://sourceware.org/binutils/docs/as/Dot.html#Dot Das scheint für Daten und Programmcode unterschiedlich zu sein:
1 | cli |
2 | loop: |
3 | rjmp .+0 |
4 | next: |
5 | rjmp .-4 |
6 | |
7 | data: .word . |
ergibt
1 | Disassembly of section .text: |
2 | |
3 | 00000000 <__ctors_end>: |
4 | 0: f8 94 cli |
5 | |
6 | 00000002 <loop>: |
7 | 2: 00 c0 rjmp .+0 ; 0x4 <next> |
8 | |
9 | 00000004 <next>: |
10 | 4: fe cf rjmp .-4 ; 0x2 <loop> |
11 | |
12 | 00000006 <data>: |
13 | 6: 06 00 .word 0x0006 ; ???? |
Fpga Kuechle schrieb: > Wobei thumb ja eher ein "Betriebsmodus"/Feature ist in dem man die ARM's > die thumb unterstützen betreiben kann, aber nicht muß. Die Cortex M Serie kennt nur den Thumb bzw. Thumb2 Modus. Die klassischen ARM Befehle existieren bei diesen Cores überhaupt nicht. Der im Wikiedia-Artikel erwähnte alte ARM7TDMI ist hingegen ein klassischer ARM7 mit zusätzlicher Thumb-Option, wie in den LPC2000. Vorsicht Falle: ARM7 ist ein Core, ARMv7 eine Befehlssatz-Architektur, die Nummern haben keinen Bezug zueinander: ARM7TDMI=ARMv4T, CM0=ARMv6-M, CM3=ARMv7-M. Bedingte Ausführung allgemeiner Befehle gibt es in Thumb überhaupt nicht, in Thumb2 per Präfix-Befehl. Die bedingten Sprünge sind aber in Thumb und Thumb2 eben gerade nicht unbedingte Befehle mit IT-Präfix, sondern ganz klassisch wie in anderen Architekturen auch.
:
Bearbeitet durch User
A. K. schrieb: > Fpga Kuechle schrieb: >> Wobei thumb ja eher ein "Betriebsmodus"/Feature ist in dem man die ARM's >> die thumb unterstützen betreiben kann, aber nicht muß. > > Die Cortex M Serie kennt nur den Thumb bzw. Thumb2 Modus. Die > klassischen ARM Befehle existieren bei diesen Cores überhaupt nicht. Der > im Wikiedia-Artikel erwähnte alte ARM7TDMI ist hingegen ein klassischer > ARM7 mit zusätzlicher Thumb-Option, wie in den LPC2000. Unglaublich aber wahr. Hab gearde im M3/M4 Standardwerk 978-0-12-408082-9 nachgelesen diese beiden sind immer im T-Mode. Danke für die Klarstellung. MfG,
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.