ATmega128: Addition und Subtraktion von 16-bit-zahlen (Montage)
Ich arbeite mit einem ATmega128 mikrocontroller und angeblich müssen zwei 16-bit-zahlen. Ich bin mit AVR Studio und dieses ist, was ich so weit gekommen:
.include "m128def.inc";
.equ ramstart = 0x100
.def temp = r16
.dseg
.org ramstart
number1: .byte 2
number2: .byte 2
.cseg
.org 0
rjmp start
start:
; number1 := 0x7856
ldi temp, low(number1)
sts number1, temp
ldi temp, high(number1)
sts number1+1, temp
; number2 := 0x34B2
lds temp, number1
sts number2, temp
lds temp, number1+1
sts number2+1, temp
slutt:
rjmp slutt
Dies ist nicht weit von der ersten Zeit bin ich über jede Art von Montage, ich weiß, ich mache etwas falsch, aber kann nicht scheinen, um herauszufinden, was. Bin ich fehlt das carry-flag?
ist das eine Hausaufgabe? Wenn ja, bitte markieren Sie Sie als solche. ja, zuerst müssen Sie laden einige Register, dann müssen Sie Sie alle auf oder zu subtrahieren. Sie fallen immer wieder auf add/adc-oder sub/sbc durchführen große Anzahl der bit/byte addiert oder subtrahiert.
Wenn ich mit add-oder adc, wie Speichere ich das Ergebnis der richtige Weg?
Wenn ich mit add-oder adc, wie Speichere ich das Ergebnis der richtige Weg?
InformationsquelleAutor Lasse A Karlsen | 2012-02-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zurück zu gradeschool mit Bleistift und Papier. Wenn ich möchte hinzufügen, 1234 und 5678
4+8 2 tragen die 1
und so weiter
das carry-bit oberhalb der diejenigen Spalte ist signifikant, es heißt das carry-in und carry
etwas, dass Blätter, die am weitesten Links stehende Spalte durchführen.
Was ist, wenn ich hatte nur Papier breit genug, um zwei Spalten gleichzeitig?
Ich beginne mit den beiden unteren Reihen von Ziffern, und ich verlange eine null als tragen. Ich bekomme Folge 12 mit a durchzuführen.
Ich jetzt nehmen, durchführen, verwenden Sie es als eine carry-in für die nächsten zwei Ziffern. Dieser Zusatz muss ich ergreifen zu können, ist eine Durchführung von einer vorherigen hinzufügen und verwenden Sie es als die im für diese hinzufügen.
Wenn alles gesagt und getan, ich bekomme 69 und 12, die zusammen bekomme ich 6912 aber nicht benötigen einen 4-stelligen Addierer, um dorthin zu gelangen. Wiederholen Sie dies für immer oder bis Sie laufen aus Speicher, Registern oder Taktzyklen.
Den avr haben eventuell andere Möglichkeiten das problem zu lösen, aber die meisten Prozessoren haben mindestens zwei Formen der Beurteilung und in zwei Formen subtrahieren, so dass Sie die Kaskade der Additionen zu sein, so weit wie Sie benötigen. Untersuchen Sie die Anleitung für den avr und was Los ist, sollten die oben springen heraus an Ihnen.
EDIT:
C Beispiel könnte helfen...(Umschaltung auf hex)
EDIT2:
Ich hoffe, dies ist keine Hausaufgabe...
Ergebnis in r20 high-byte, und r21 low-byte
wenn Sie Lesen müssen, aus dem Arbeitsspeicher, es gibt viele Wege, dies meint die 16-bit-zahlen sind little-endian
r0 untere Hälfte des Ergebnisses, r1 Obere Hälfte.
oder verwenden Sie eine der x -, y-oder z-pointer Register
InformationsquelleAutor old_timer
Gut, du bist nicht wirklich der Ausstellung einer Anweisung zusätzlich. Ich bin kein AVR-Programmierer in irgendeiner Weise, aber nach einem kurzen Blick auf den Befehlssatz des ATmega128, sowas scheint es viel mehr richtige. Ich gehe davon aus, dass dein assembler verwendet die Intel-syntax, und dass die Nummern gespeichert werden als Little Endian.
Das Ergebnis ist daher gespeichert in
r17:r16
, z.B. das high-byte inr17
, und das low-byte inr16
.Die Spezifikation der hlt-Anweisung sagt, dass es korrekt arbeitet nur auf Registern 16 bis 31. Ich bearbeitet meine post entsprechend.
Anstelle der Verwendung von lds, was ldm? Nicht sicher, wo im RAM ramstart zugeordnet ist, aber es könnte sein, in "program memory" wenn man bedenkt Sie sind platzieren Sie Ihre zahlen und Codes in der gleichen Gegend. Meine Vermutung ist, das ist, warum Sie immer 0xFF - SRAM ist nicht initialisiert oder nicht vorhanden ist.
error: Operand(s) out of range in 'ldi r16,0x100'
InformationsquelleAutor Daniel Kamil Kozar
Ihrem Datenblatt hat
add
undadc
aus diese link. Wie ich vermutete, oben, vielleicht haben Sie verwenden müssen, um den Programmspeicher geladen, ldm, um auf Ihre zahlen.Grundsätzlich:
Obige code funktioniert nicht und es ist ein funktionierendes Beispiel...
Wenn ich das Verständnis der Kontext richtig mit dem post-Inkrement-ldm-Befehl und alle Register sind 8-bit.
Adresse laden sofort in r0. Load Program-Modus von r0 in r16,r17,r18,r19. So meinte ich das ldm-Anweisung. Ich bin verwirrt, wie, um Werte aus dem RAM obwohl über die Register, da Sie nur 8-bit lang.
Ah, X/Y/Z-Register ala Z80 Tage. Mein schlechtes.
InformationsquelleAutor Michael Dorgan
Das symbol "Zahl1" hat den Wert von einer Adresse, nicht der Inhalt der Adresse.
Da haben Sie sich "Zahl1" an .ORG RAMSTART, das ist wahrscheinlich 0100 Hex, dann
low(Zahl1) ist gleich 00 und hoch(Zahl1) gleich 01
Wenn Sie möchten, dass der INHALT der Adresse "Zahl1", müssen Sie zuerst die Adresse in einen
16-bit-Adresse zu registrieren, zum Beispiel das Z-register = (R30,R31), die durch die folgenden
LDI R30, HOCH(Zahl1)
LDI R31, LOW(Zahl1)
Nun das Z-register kann verwendet werden, um den WERT in der Adresse "Zahl1":
LD R16,Z+
LD R17.Z
Nun haben Sie die 16-bit-Wert in R16,R17
Jetzt haben Sie das gleiche zu tun für die "Zahl2"
LDI R30, HOCH(nummer2)
LDI R31, LOW(nummer2)
LD R18,Z+
LD R19.Z
Nun haben Sie den zweiten 16-bit-Zahl in R18, R19
Nun fügen Sie Sie zusammen mit tragen vom LSB zum MSB
ADD R19,R17 ;addiere LSB ' s erste
ADC R18,R16 ;dann fügen Sie die MSBs mit dem carry bit
Die Antwort ist jetzt in R18,R19
Fazit: Der AVR hat einen echt krass, ineffizient Befehlssatz. Es hat einen Vorteil gegenüber den 8051, aber: Das heißt, der stack kann sich irgendwo im RAM, die es Ihnen ermöglicht, mehrere Prozesse ausgeführt werden, jede mit Ihren eigenen Stapel.
Aber im Allgemeinen, alle Harvard-Architektur-Prozessoren SAUGEN im Vergleich zu von-Neumann-Architekturen.
Wenn nur, bitte, Gott, ich wünschte, jemand machte einen mikrocontroller auf Basis des 8085 oder Z80 mit on-chip-RAM und FLASH, verlassen alle pins frei für I/O-ports!
InformationsquelleAutor Paul