mikrocontroller.net

Forum: Compiler & IDEs Stack kopieren&vergleichen in assembler


Autor: Sarah Müller (nevu21)
Datum:

Bewertung
0 lesenswert
nicht 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:
  .text      @ legt eine Textsection fuer PrgrammCode + Konstanten an
  .align  2    @ sorgt dafuer, dass nachfolgende Anweisungen auf einer durch 4 teilbaren Adresse liegen
        @ unteren 2 Bit sind 0
  .global  main    @ nimmt das Symbol main in die globale Sysmboltabelle auf
  .type  main,function
main:
//  Hier bitte Ihren ProgrammCode einfuegen
  stmfd  sp!, {r4, r5, lr}    @ Ruecksprungadresse und Register sichern
  






  ldmfd  sp!, {r4, r5, pc}    @ zurueck zu aufrufendes System

  
// Tabellen erster Wert der Tabelle steht fuer die Laenge der Tabelle
TAB1:  .word  ((TAB1ende-TAB1)/4), 1, 2, 3, 4, 5, 6, 7, 8, 9, 8
TAB1ende:

TAB2:  .word  Tabelle2  

.Lfe1:
  .size  main,.Lfe1-main
  .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

Autor: R. Freitag (rfr)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Sarah Müller (nevu21)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: R. Freitag (rfr)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sarah Müller (nevu21)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

ich habe nun folgendes gebastelt:

main:
//      Hier bitte Ihren ProgrammCode einfuegen
        stmfd   sp!, {r4, r5, lr}               @ Ruecksprungadresse und Register sichern
        ADR r1, TAB1
        ADR r0, TAB2
        add r1, r1, #4
        add r0, r0, #4
        //ldr r2, [r1], #4
        //ldr r3, [r1], #8

        ldmia r1, {r2-r11}
        stmia r0, {r2-r11}
        mov r2, #0
        mov r3, #0
        mov r10, #0
        mov r5, r0
        mov r6, r1

        ldr r2, [r1], #4 //]!
        ldr r3, [r0], #4 //]!

        B LOOP


        ldmfd   sp!, {r4, r5, pc}               @ zurueck zu aufrufendes System

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

TAB2:   .word   Tabelle2


LOOP:
        ldr r2, [r6], #4 //]!
        ldr r3, [r5], #4 //]!
        ADD r10, r10, #1
        cmp r11, r12
        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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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/

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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/

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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/

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.