Schritt 5: Push 'n Pop
Es gibt nur ein paar "allgemeine Zweck registriert", die wir zur Verfügung haben und sobald sie verwendet werden, gibt es nicht mehr. So ist es gut zu benennen Programmierstil, verwenden sie nur für ein paar Variablen, die als Zwischenspeicher verwendet werden, die Sie zum Lesen benötigen von und schreiben in Häfen und SRAM mit, oder auch diejenigen, die Sie in Unterroutinen überall und so benötigen Sie. Also was ich getan habe jetzt, wir initialisiert haben und lernen des Stapels, durch den Code gehen und finden die benannte Allzweck-Register, die sind nur innerhalb einer einzigen Unterroutine oder Interrupt und nirgendwo im Code verwendet und ersetzen Sie sie mit einem unserer temp Register und eine Push- und Pop auf den Stapel. In der Tat, wenn Sie Code für kleinere Mikrocontroller geschrieben betrachten, oder gehst du zurück in der Zeit, wann alle Chips kleiner waren, sehen Sie nur ein paar der Allzweck-Register, die für alles verwendet werden musste, also Sie konnte nicht nur einen Wert speichern, dort und lassen Sie es allein, da Sie dieses Register für andere Dinge brauchen sicher waren. So sehen Sie bestiegen und ein poppin ' überall im Code. Vielleicht sollte ich unsere temp Allzweck-Register AX und BX als eine respektvolle ein großes Lob an diese längst vergangene Tage benannt.
Ein Beispiel hilft dies klarer zu machen.
Beachten Sie, dass in unserer Analog-Digital Umwandlung vollständig Interrupt ADC_int verwenden wir eine Allzweck registrieren, dass wir ButtonH benannt haben, die wir zum Laden des Wertes des ADCH und vergleichen Sie es mit unseren Lookup-Tabelle der Analog-Button Presse Konvertierungen. Wir verwenden nur diese ButtonH Register innerhalb des Unterprogramms ADC_int und nirgendwo sonst. Stattdessen verwenden wir unsere Variablen temp2, die wir als eine temporäre Variable verwenden, die wir innerhalb einer bestimmten Unterroutine verwenden können und seinen Wert hat keine Auswirkungen auf alles, was außerhalb dieser Unterroutine (d. h. wird nicht der Wert geben wir es in ADC_int überall sonst verwendet werden).
Ein weiteres Beispiel ist in unserem Verzögerung Makro. Wir haben ein Register haben wir "Millisekunden" genannt, enthält unsere Verzögerungszeit in Millisekunden. In diesem Fall ist es in einem Makro und wir erinnern daran, dass die Art und Weise Makro-Arbeit ist, dass der Assembler den gesamten Makro-Code in die Stelle des Programms Orte wo es genannt wird. In diesem Fall möchten wir die Variable "Millisekunden" loswerden und ersetzen Sie es durch eines unserer temporären Variablen. In diesem Fall werde ich es ein wenig anders tun, um Ihnen zu zeigen, auch wenn der Wert der Variablen wird an anderer Stelle benötigt werden noch Verwendung können mithilfe des Stapels. So anstelle von Millisekunden verwenden wir "temp" und, dass wir vermasseln nicht andere Dinge, die auch den Wert von Temp verwenden einfach zunächst "Verzögerung" Makro "pushen" Temp auf dem Stack, dann wir es anstelle von Millisekunden verwenden, und dann am Ende des Makros wir "" seinen vorherigen Wert zurück vom Stapel Pop.
Das Ergebnis ist, dass wir "" Temp und temp2 zum vorübergehenden Gebrauch ausgeliehen und sie dann auf ihre vorherigen Werte wiederhergestellt, wenn wir fertig sind.
Hier ist die ADC_int-Interrupt-Routine nach dieser Änderung:
ADC_int: push temp ; save temp since we modify it here push temp2 ; save temp2 lds temp2,ADCH ; load keypress ldi ZH,high(2*numbers) ldi ZL,low(2*numbers) cpi temp2,0 breq return ; if noise triggers don't change 7segnumber setkey: lpm temp,Z+ ; load from table and post increment clc cp temp2,temp ; compare keypress with the table brlo PC+4 ; if ADCH is lower, try again lpm 7segnumber,Z ; otherwise load keyvalue table inc digit ; increment the digit number rjmp return ; and return adiw ZH:ZL,1 ; increment Z rjmp setkey ; and go back to top return: pop temp2 ; restore temp2 pop temp ; restore temp reti
Beachten Sie, dass die Funktionsweise der Stack ist, dass die ersten auf den letzten ausgeschaltet ist. Genau wie ein Stapel von Papieren. Sie sehen, dass in unseren ersten beiden Linien wir den Wert der Temp auf dem Stack schieben, dann wir temp2 auf dem Stapel Push, dann wir sie in die Unterroutine für andere Dinge verwenden, und schließlich wir wiederherstellen auf ihre vorherigen Werte wieder zuerst abspringen temp2 (da es war der letzte schob es ist an der Spitze des Stacks und wird das erste sein, die wir pop wieder aus) und dann tauchen Temp.
Von nun an werden wir immer diese Methode verwenden. Das einzige Mal, das wir tatsächlich ein Register für etwas anderes als eine temporäre Variable benennen ist, wenn wir gehen, um es überall brauchen. Zum Beispiel ist das Register namens "überläuft", verwenden wir an verschiedenen Stellen im Programm und wir möchten ihm einen Namen geben. Natürlich könnten wir noch sie verwenden wie wir mit Temp und temp2 getan haben, weil wir es Wert wiederherstellen würde, nachdem wir fertig sind. Aber das wäre zu viel Spaghettify Dinge. Sie werden aus einem bestimmten Grund genannt und wir haben Temp und temp2 bereits für diesen Job bezeichnet.