Forum: Compiler & IDEs Stack kopieren&vergleichen in assembler


von Sarah M. (nevu21)


Lesenswert?

Hallo liebe Forengemeinde, ich hänge seit tagen an einem Problem und 
finde einfach keine Lösung. Evtl. fehlt mir genug Abstraktionsvermögen 
um mein Studium durchzuziehen.


Ich soll in Assember ein Programm entwickeln das eine Liste TAB1 in eine 
Liste TAB2 kopiert.
Nach dem Kopiervorgang sollen in einem weiteren Schritt die beiden 
Listen verglichen werden. Ist ein Wert
der beiden Tabellen ungleich, so soll der Fehler in der Liste TAB2 
korrigiert werden, danach wird mit dem
Vergleich weitergemacht. Zusätzlich soll ein Zähler die Anzahl der 
ungleichen Speicherstellen mitzählen.

Hierzu steht ein Programmrahmen zur Verfügung. Der erste Eintrag in der 
Quellenliste (TAB1) beinhaltet die
Länge der Liste. Beachten Sie, dass an der Marke TAB2 nur ein Wort 
reserviert ist, Der entsprechende
Speicherinhalt verweist auf den Speicher, an dem die Originalliste 
(TAB1) kopiert werden soll.


Nun zum Code:
1
  .text      @ legt eine Textsection fuer PrgrammCode + Konstanten an
2
  .align  2    @ sorgt dafuer, dass nachfolgende Anweisungen auf einer durch 4 teilbaren Adresse liegen
3
        @ unteren 2 Bit sind 0
4
  .global  main    @ nimmt das Symbol main in die globale Sysmboltabelle auf
5
  .type  main,function
6
main:
7
//  Hier bitte Ihren ProgrammCode einfuegen
8
  stmfd  sp!, {r4, r5, lr}    @ Ruecksprungadresse und Register sichern
9
  
10
11
12
13
14
15
16
  ldmfd  sp!, {r4, r5, pc}    @ zurueck zu aufrufendes System
17
18
  
19
// Tabellen erster Wert der Tabelle steht fuer die Laenge der Tabelle
20
TAB1:  .word  ((TAB1ende-TAB1)/4), 1, 2, 3, 4, 5, 6, 7, 8, 9, 8
21
TAB1ende:
22
23
TAB2:  .word  Tabelle2  
24
25
.Lfe1:
26
  .size  main,.Lfe1-main
27
  .comm  Tabelle2, TAB1ende-TAB1    @ Speicherbereich mit der Groesse von TAB1 reservieren
---------------------------------------------

Was macht .word  ((TAB1ende-TAB1)/4), 1, 2, 3, 4, 5, 6, 7, 8, 9, 8

Und wie hole ich Daten aus der Tabelle in die Register?

und welchen Lösungsansatz schlagt ihr vor?
Ich freu mich auch über kleine Hinweise.


Sarah

von R. F. (rfr)


Lesenswert?

.word legt eine Tabelle aus words in den Speicher.

Um einen Tabellenwert in ein Register zu kopieren, verwende 
Pointerregister.

Gruss

Robert

PS.: auf was soll der Code laufen?

von Sarah M. (nevu21)


Lesenswert?

Das ganze sollte auf einem at91eb63 laufen.

Und die Wörter hier wären "1" "2" ... "8"?


Danke für den Hinweis, wenn ich ne Lösung hab, schreib ich sie.


Gruß
Sarah

von R. F. (rfr)


Lesenswert?

Die Anweisung .word reserviert Speicher für alle der Anweisungen 
folgenden Werte. In deinem Falle legt sie eine Tabelle im Speicher an, 
die die genannten Werte beinhalten.

Der Zugriff geschieht in der Regel über Pointerregister.

Gruss

Robert

von Sarah M. (nevu21)


Lesenswert?

Hallo nochmal,

ich habe nun folgendes gebastelt:
1
main:
2
//      Hier bitte Ihren ProgrammCode einfuegen
3
        stmfd   sp!, {r4, r5, lr}               @ Ruecksprungadresse und Register sichern
4
        ADR r1, TAB1
5
        ADR r0, TAB2
6
        add r1, r1, #4
7
        add r0, r0, #4
8
        //ldr r2, [r1], #4
9
        //ldr r3, [r1], #8
10
11
        ldmia r1, {r2-r11}
12
        stmia r0, {r2-r11}
13
        mov r2, #0
14
        mov r3, #0
15
        mov r10, #0
16
        mov r5, r0
17
        mov r6, r1
18
19
        ldr r2, [r1], #4 //]!
20
        ldr r3, [r0], #4 //]!
21
22
        B LOOP
23
24
25
        ldmfd   sp!, {r4, r5, pc}               @ zurueck zu aufrufendes System
26
27
TAB1:   .word   ((TAB1ende-TAB1)/4), 1, 2, 3, 4, 5, 6, 7, 8, 9, 8
28
TAB1ende:
29
30
TAB2:   .word   Tabelle2
31
32
33
LOOP:
34
        ldr r2, [r6], #4 //]!
35
        ldr r3, [r5], #4 //]!
36
        ADD r10, r10, #1
37
        cmp r11, r12
38
        BNE LOOP

Ganz abgesehen davon, dass das kopieren der Tabelle funktioniert, 
passiert beim geplanten Datenvergleich innerhalb von LOOP nur mist - 
nichtmal der Additionsbefehl funktioniert innerhalb von LOOP - was mache 
ich nur falsch?

Die ldr befehle funktionieren ebenfalls nur ausserhalb von LOOP 
innerhalb von main.

von Peter D. (peda)


Lesenswert?

Sarah Müller schrieb:
> Nach dem Kopiervorgang sollen in einem weiteren Schritt die beiden
> Listen verglichen werden.

Was soll das denn für einen Sinn haben?

Wenn nach dem Kopieren beide Bereiche ungleich sind, dann ist Deine 
Hardware defekt.


Peter

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Wenn nach dem Kopieren beide Bereiche ungleich sind, dann ist Deine
> Hardware defekt.

Diese Einschränkung gilt nur wenn der Kopieralgorithmus richtig 
funktioniert. Da es sich ziemlich offensichtlich um eine Übungsaufgabe 
handelt, ist der Vergleich sinnvoll. Wir stellen in unseren Kursen unter 
anderem eine ganz ähnliche Aufgabe.

Gruß
Marcus
http://www.doulos.com/arm/

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Hallo Sarah

Dein Programm kann nur dann funktionieren, wenn die Liste zufällig
in die freien Register passt. Ich vermute, dein Assi wäre nicht
unglücklich wenn Du den Code etwas allgemeiner halten würdest. Daher
wahrscheinlich das erste Feld, das die Größe der Tabelle
angibt. Alternativ könntest Du die aktuelle Adresse auch mit
"TAB1ende" vergleichen.

Das scheint übrigens Dein Problem beim Vergleich zu sein. Es gibt
keine Abbruchbedingung. Du lädst Werte in Register, vergleichst aber
andere Register :-/.

Die Funktion kehrt nie zurück.

Gruß
Marcus
http://www.doulos.com/arm/

von Peter D. (peda)


Lesenswert?

Ist denn wirklich noch bei 32Bit-Boliden Assemblerprogrammierung 
gefragt?

Ich würde ein kleines C-Progrämmchen mit memcpy und memcmp nach 
Assembler compilieren lassen.


Peter

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Ist denn wirklich noch bei 32Bit-Boliden Assemblerprogrammierung
> gefragt?

Nicht so sehr. Obwohl bei den meisten ARM Prozessoren Assembler hin
und wieder nötig ist. Bei der Programmierung auf Applikationsebene
wirst Du damit allerdings nicht in Berührung kommen. Aber es hilft
gerade bei low-level Programmierung enorm, den Befehlssatz und die
Architektur zu verstehen. Mit einfachen Assembler Programmen kann man
mal ein Gefühl dafür bekommen.

> Ich würde ein kleines C-Progrämmchen mit memcpy und memcmp nach
> Assembler compilieren lassen.

Erfahrungsgemäß bekommt hat man den besseren Lernerfolg, wenn man den
Code selber geschrieben hat und sich durch seine Fehler an die
richtige Lösung rantastet.

Gruß
Marcus
http://www.doulos.com/arm/

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.