kleine Frage zu Assembly-Befehl

haben meine register r0 - r15 feste adressen zum startzeitpunkt ? eigentlich schon, oder ?
Die Register r0-r15 sind ganz spezielle Speicherzellen Addressraum des controllers.
Die Frage lautet nicht welche Addresse diese haben, sondern welchen Inhalt. Den Inhalt der Register siehst ja wunderbar in deinem uVison.
Der Inhalt der Register zum Startzeitpunkt ist so glaube ich nicht bei allen Registern gleich definiert.

wie in der aufgabenstellung oben, geht es auch viel mehr um die register und deren adressen, statt dem ram...
Ich entnehme der Aufgabenstellung genau das Gegenteil!

wenn nun etwas wie
str r0, [r1, #4] kommt, heißt das, dass mein r0 in 0x20000010 + 4 geschrieben wird, also = 0x20000050 ?

Das ist der Fall wenn der !!!INHALT und nicht die Adresse!!! deines r1 = 0x20000010 ist und der Inhalt von r0 = 0x20000050 ist.

Hast du die den Code aus meinem vorherigen Post mal probiert ?

Code:
    mov   r0,#0x20000000
    mov   r1,#0x12345678
    str   r1,[r0,#0]
 
nein, weil ich ja keine speicheradressen sehen kann....

ich habe mein eigenes programm durchlaufen lassen, die inhalte der register verändern sich, aber bei adresse 0x20000000 sehe ich keine veränderung.... für was soll ich es dann durchlaufen lassen ?

schau mal, die aufgabenstellung sieht so aus:

endlicj.png


die adresse 0x20000000 hat keinen inhalt, obwohl am anfang r0 und r1 bekannt sind (gefüllt mit einem wert)

in der liste unten, müsste ja nun irgendwo bei den angegebenen adressen dieser inhalt zu finden sein....


anschließend kommt folgendes:

str r0, [r1] was genau geschieht da ? r0 wird in die adresse von r1 geschrieben.... unten in der adressleiste ist r1 und r0 aber nirgends vertreten, also kann ich auch nicht sagen WOHIN der inhalt geschrieben wird




dann kommt:

mov r2, r0 nun wird der inhalt von r0 (0x84030201) in register 2 geschrieben


lsl r2, #1 nun wird aus 0x84030201 -> 0x08060402 , da linksshift.


jetzt soll dieser neue wert in die adresse von r1 geschrieben werden + 4 bytes....... wird nun eine adresse, 4 bytes weiter gewählt, oder wird innerhalb von der adresse r1, 4 bytes "später" mit dem schreiben bekommen (speichernummern) ?


wo schreibe ich das nun hin ? die adresse von r1 ist ja unbekannt....
 

Anhänge

  • a.png
    a.png
    520,7 KB · Aufrufe: 219
  • sdsdsdsdsdsd.png
    sdsdsdsdsdsd.png
    89,2 KB · Aufrufe: 211
Zuletzt bearbeitet:
Du gibst ja beim Befehl das Register beim Namen an, das reicht aus (der Name ist quasi die Adresse). Die Register sind ja spezielle Speicher die direkt in der CPU liegen. Adressiert werden sie über Befehle die eben ein Register anstelle einer direkt angegebenen Speicheradresse verwenden. Oft läuft wes aber auch so ab das im Register die Adresse der Speicherzelle steht die dann im RAM verwendet wird (wie auch in deinem Beispiel)

Edit: die "Adresse" von R1 ist "R1" und im Fenster "Registers" siehst du den Inhalt der Register.
 
habem ir nochmal alles durchgelesen und das blatt angeschaut.

ok, ich komme zu dem entschluss, dass die register, auch wenn sie einen wert besitzen, dieser wert in keiner speicheradresse hinterlegt ist, sondern er einfach im register hängt. erst durch die funktion STR, kann ich einen wert in den speicher schreiben.

nun kommt dadurch mir aber wieder die frage auf, wenn ich jetzt den wert von r2 in die adresse von r1 + 4 schreibe, dann ist das ja nicht möglich, da r1 einfach nur ein register ist und der inhalt zuvor nicht in eine speicherstelle geschrieben wurde ??!?


was genau macht dann mein befehl STR r2, [r1 +4] ???



wie kommt es dann, dass in der musterlösung unten bei den speicherstellen überhaupt werte drinnen stehen ? wenn angeblich nichts in den RAM geschrieben wird ?

legt er dann den wert in register r1 + 4 = r5 ab ? er kann ja nur was in einer speicheradresse ablegen, wenn diese auch existiert.

laut musterlösung liegt ja unser gebitshiftetes r2 in 0x20000010 ..aber warum ?
 
Zuletzt bearbeitet:
nein, weil ich ja keine speicheradressen sehen kann....
???

CortexM3.jpg

str r0, [r1] was genau geschieht da ? r0 wird in die adresse von r1 geschrieben
Nein, r1 hat einen Inhalt, dieser Inhalt repräsentiert für den Befehl str r0,[r1] die Addresse wo r0 hingeschrieben wird.
In deinem Fall (laut Screen shot) hat r1 den in Inhalt 0x00000018 und du schreibst irgendwo im Adressraum des Controller.

Dies erklärt auch :
ich habe mein eigenes programm durchlaufen lassen, die inhalte der register verändern sich, aber bei adresse 0x20000000 sehe ich keine veränderung.... für was soll ich es dann durchlaufen lassen ?
 
smuji schrieb:
nun kommt dadurch mir aber wieder die frage auf, wenn ich jetzt den wert von r2 in die adresse von r1 + 4 schreibe, dann ist das ja nicht möglich, da r1 einfach nur ein register ist und der inhalt zuvor nicht in eine speicherstelle geschrieben wurde ??!?

Die Verwirrung liegt hier glaub ich einfach in einer ungenauen Auslegung des Sachverhaltes. Der Wert von R2 wird nicht "in die Adresse von" R1 + 4 sondern in die Adresse die sich "aus dem Inhalt" von R1 + 4 ergibt geschrieben. Und diese Adresse liegt dann im RAM.
 
In der Aufgabe haben die Register r0 und r1 vor Aufruf der Funktion "func" bereits Werte zugewiesen bekommen.
r0 hat den Inhalt 0x12342A0C und r1 den Inhalt 0x2000001C. Das heißt der INHALT von r1 repräsentiert eine Adresse im RAM.

Bitte füge in deinem Code als allererstes die folgenden Kommandos ein und verändere r1 nicht mehr mit einem mov Befehl.

mov r1,#0x2000001C
mov r0,#0x12342A0C

STR r2, [r1 +4] bedeutet dann, dass der Inhalt von r2 and die Adresse 0x2000001C + 4 also 0x20000020 geschrieben wird. Bitte überprüfe das r2 einen Inhalt ungleich 0x00000000 sonst siehst du wieder nichts. (also zB. mov r2, #0xAA55AA55)
 
Zuletzt bearbeitet: (Falscher Wert, war vorher anders als in der Aufgabe)
hgader schrieb:
???

Anhang anzeigen 603318


Nein, r1 hat einen Inhalt, dieser Inhalt repräsentiert für den Befehl str r0,[r1] die Addresse wo r0 hingeschrieben wird.
In deinem Fall (laut Screen shot) hat r1 den in Inhalt 0x00000018 und du schreibst irgendwo im Adressraum des Controller.

Dies erklärt auch :



ach, ich glaube ich komme langsam auf den trichter.....

mein r1 enthält die information über die speicherstelle bzw. eine zahl die später durch STR als speicheradresse interpretiert wird......sprich, wäre mein r1 (wert) = 08154711, dann würde mein r0 in die speicherstelle 08154711 + 4 geschrieben werden ? (ich weiß, gibt es nicht)


ich glaube ich habe das nun verstanden. danke euch beiden..


nun versuche ich nochmals die aufgabe zu lösen:

r0: 0x84030201
r1: 0x20000018


str r0, [r1] -> 0x84030201 in speicheradresse: 0x20000018
mov r2, r0 -> r2=0x84030201
lsl r2, #1 -> linksshift und dadurch erhält r2=0x08060402
str r2, [r1, #4] -> schreibe 0x08060402 in adresse 0x20000018+4 = 0x20000022
mov r3, r0 -> r3= 0x84030201
lsl r3, #2 -> r3<<2 = 0x84030201*2² = 0x100C0804
add r0, r0, r2 -> r0=r0+r2= 0x8C090603
str r0, [r1, #8] -> 0x8C090603 in adresse: 0x20000018 + 8 = 0x20000026
str r3, [r1, #0xC] -> 0x100C0804 in adresse: 0x20000018 + 12 = 0x20000030
bx lr




ich vermute dass ich beim adresserechnen noch was falsch mache, da ja so krumme adressen nicht vorhanden sind wie 0x20000026

es sind ja immer:

0x20000010
0x20000020
0x20000030
0x20000040
0x20000050

was mache ich falsch ?
 
Ich kann mich nur noch mal wiederholen. Mach Dich erst mal mit den Grundlagen vertraut. Die Beiträge haben nämlich gezeigt, dass es da ganz klar hapert. Es kann nicht der Sinn eines Forums sein hier Grundlagen zu vermitteln. Und für dich ist es wenig hilfreich von Detailfrage zu Detailfrage zu hüpfen ohne überhaupt das Gesamte zu verstehen.

Mach Dich erst mal damit vertraut, wie eine CPU überhaupt arbeitet. Dann noch mit der ARM-Architektur im Besonderen. Und erst dann wirst Du auch in der Lage sein Code zu schreiben und bzw. auch aus vorhandenem Code abzuleiten, was dieser denn nun tut.

Klingt theoretisch. Klingt langweilig, aber anders gehts nun mal nicht.
Alles andere wird ein zielloses Stochern im Nebel bleiben.
 
hallo,

danke, aber das ist keine antwort auf meine frage. wenn es dich stört, bitte ich dich diesen thread zu meiden. danke.

ich möchte keine assemblerprogramme schreiben. sondern nur eine solche aufgabe lösen können.
 
Zuletzt bearbeitet:
Da fehlen wirklich die Basics... die "krummen" Adressen sind schon vorhanden, es gibt ja keine Löcher im RAM ;-)

Eine Speicheradresse enthält immer genau ein Byte, in hexadezimal also 2 Stellen. Das was am Anfang einer Zeile für den RAM steht ist die Adresse des ersten Bytes in dieser Zeile, die restlichen 15 Bytes die da noch aufgelistet sind haben dementsprechend die weiteren Adressen (und das was du mit den Befehlen ins RAM schreibst sind immer 4 Bytes am Stück, deswegen wird die Adresse auch um 4 erhöht um hinter den vorherigen Wert zu schreiben)
 
klar fehlen die basics, aber wir sollen auch nur ganz grob wissen wie es funktioniert. diese aufgabe ist sozusagen die "zusatzaufgabe"

aber deine antwort hat mir glaube die erleuchtung gebracht. wenn ich es richtig interpretiere ist der speicher schachbrettartig aufgebaut.


diese:
0x20000000:
0x20000010:
0x20000020:
0x20000030:
0x20000040:

sind sozusagen die zeilen

und von links nach rechts folgen danach die speicherstellen.

möchte ich nun ein einzelnes byte ganz oben rechts im schachbrett platzieren, hieße die adresse: 0x2000000F (oberste zeile, ganz rechts außen)


ich muss euch jetzt schonmal herzlich danken, dass ihr eure zeit mit so nem RAM-legastheniker wie mir verschwendet habt =)


wenn meine annahme also nun stimmt, vermute ich, dass dein beispiel was du mir oben gepostet hast (screenshot) mit BIG ENDIAN arbeitet, oder ?
 
Zuletzt bearbeitet:
wenn ich es richtig interpretiere ist der speicher schachbrettartig aufgebaut
Das ist nur eine übliche Visualisierung des Speichers.

und von links nach rechts folgen danach die speicherstellen.

möchte ich nun ein einzelnes byte ganz oben rechts im schachbrett platzieren, hieße die adresse: 0x2000000F (oberste zeile, ganz rechts außen)
Genau, beachte aber wenn du nur ein einzelnes Byte plazieren möchtest dass du "strb" verwenden solltest.

wenn meine annahme also nun stimmt, vermute ich, dass dein beispiel was du mir oben gepostet hast (screenshot) mit BIG ENDIAN arbeitet, oder ?
Nein, Little Endian höchstwertiges Byte zuletzt..
Als Faustregel kannst du dir merken, wenn du die Bytereihenfolge drehen mußt ==> Little Endian.

Wert : 0x12345678 Speicher 0x20000000 : 78 56 34 12 ==> Little Endian
Wert : 0x12345678 Speicher 0x20000000 : 12 34 56 78 ==> Big Endian
 
stimmt, sorry, verdreht, dann ist aber die musterlösung meiner aufgabe falsch. denn ARM arbeitet ja standardmäßig mit little endian und in der musterlösung wurde der wert 0x08060402 in der reihenfolge 08 06 04 02 von links nach rechts im speicher abgelegt. also die 02 auf F und die 08 auf C

Musterlösung:ded.png
 
Zuletzt bearbeitet:
hey, danke erstmal.

ich hätte nur noch mal zwei kleine verständnisfragen

wenn:

r0=16
r1= 0x00000018


str r0, [r1, #4]


1. wird dann diese als 16 in r1 geschrieben, oder in der form 0F (hex) in r1 geschrieben ?

2. 0x00000018 + 4 = 22 bedeutet das dann, r0 wird in adresse 0x00000022 geschrieben, also eine "zeile" drunter, oder aber, da ja die 1 von der 0x00000018 die zeile angibt, und die 8 die speichernummer, wird aus der 8 + 4 = 12 also speicherstelle 0x0000001C ???


würde mich nur noch über diese 2 antworten freuen.


gruß
 
smuji schrieb:
1. wird dann diese als 16 in r1 geschrieben, oder in der form 0F (hex) in r1 geschrieben ?
Kurzantwort: Ja in Hex.

Lange Antwort: Natürlich nicht in Hex. RAM kennt keinen Unterschied zwischen hexadezimal, dezimal usw. Du musst unterscheiden zwischen Information und Repräsentation. Und Dein Debugger zeigt die Speicherzellen nun mal in hexadezimaler Repräsentation an.

Abgesehen davon: 0x0F = 15 und nicht 16.

smuji schrieb:
2. 0x00000018 + 4 = 22 bedeutet das dann, r0 wird in adresse 0x00000022 geschrieben, also eine "zeile" drunter, oder aber, da ja die 1 von der 0x00000018 die zeile angibt, und die 8 die speichernummer, wird aus der 8 + 4 = 12 also speicherstelle 0x0000001C ???
0x18 + 0x04 = 0x1C
Ganz einfach. Was Du da mit den Begriffen Speichernummer und Zeile willst, weiß ich jetzt nicht.
Wenn überhaupt hat ne Speicherzelle eine Adresse.
 
tut mir leid, dass ich nochmal nerven muss, jetzt ist mir aber noch eine kleine verständnisfrage aufgekommen. ich weiß nicht ob ich mit nullen "auffüllen muss ,oder nicht. ich zeige euch mal meine rechnung.


r0: 0x12342A0C
r1: 0x2000001C



lsl r0, #2 -> 0001 0010 0011 0100 0010 1010 0000 1100 -> 0100 1000 1101 0000 1010 1000 0011 0000

str r0, [r1] -> dieser wert als HEX (0x48D0C830) in die adresse 2000001C

and r0, #0x8E00 -> 0100 1000 1101 0000 1010 1000 0011 0000 &&
0000 0000 0000 0000 1000 1110 0000 0000
------------------------------------------------------------------
0000 0000 0000 0000 1000 1000 0000 0000


ist mein r0 nun = 0x00008800 oder 0x8800 ?


str r0, [r1, #8] -> soll ich nun 0x8800 in den speicher schreiben, oder mit vorangestellten 0000 ??



freue mich über antworten...

gruß smuji
 
Zurück
Oben