Um Platz zu sparen versuche ich den generierten C-Code mit inline asm(""); Wenn ich mir die ursprüngliche Disassemblierung und den gut funktionierenden Code ansehe, verstehe ich die Zeile 0x17E4 nicht.
void MENU_BUTTON(uchar Parm){
// This loop ends when the enter key is pressed
while EnterOpen(){ // SW3 = RE2
if ArrowUpClosed(){ // RE0
while ArrowUpClosed(){};
asm("call MBD");
if ArrowUpOpen()
LCDGotoPos(ArrowUp[index]);
};
if ArrowDownClosed(){ // SW3 RE1
while ArrowDownClosed(){};
asm("call MBD");
if ArrowDownOpen()
LCDGotoPos(ArrowDown[index]);
};
if ArrowRightClosed(){ // SW4 RC1
while ArrowRightClosed(){};
asm("call MBD");
if ArrowRightOpen()
LCDGotoPos(ArrowRight[index]);
};
if ArrowLeftClosed(){ // SW5 RC0
while ArrowLeftClosed(){};
asm("call MBD");
if ArrowLeftOpen()
LCDGotoPos(ArrowLeft[index]);
};
};
Pause(300);
return;
// a little trick to save space
asm("MBD:");
delay();
}; // End of MenuButtons.
// This loop ends when the enter key is pressed
while EnterOpen(){ // RE2
0x178E: BCF STATUS, 0x5
0x178F: BCF STATUS, 0x6
0x1790: BTFSS PORTE, 0x2
// jumping out of the loop as expected
0x1791: GOTO 0x7E5
// returns to the beginning? but during execution goes to 0x1792.
// The way I expect
0x17E4: GOTO 0x78E
// during execution
//if ArrowUpClosed() // RE0
0x1792: BTFSC PORTE, 0x0
//other code
} // end of while EnterOpen
// Pause(300);
0x17E5: MOVLW 0x8
Vorbehalte: Es ist mehr als ein Jahrzehnt her, dass ich routinemäßig PIC-Assembler-Code geschrieben habe (und ihren C-Compiler verwendet habe – ich bin mir auch nicht sicher, ob meine Lizenz noch gut ist.) Sie haben auch nicht gesagt, welchen Compiler Sie verwenden, also Ich kann mir keine Kopie besorgen und sehen, was sie erzeugt. Und ich weiß nicht einmal, ob Sie einen PIC16 oder einen PIC18 verwenden (andere Kreaturen, wobei der PIC18 schönere Vorkehrungen für den Assemblercode hat). Schließlich gehe ich davon aus, dass Sie mit dem PIC und dem in einigen ziemlich gut vertraut sind Wegen Ihrer aktuellen Arbeit im Vergleich zu meinem jahrzehntealten (und mehr) Wissen darüber werden Sie besser als ich in der Lage sein, spezifische Fragen zum Assemblercode zu beantworten.
Annahmen:
Unter der Annahme, dass das Obige richtig ist, vermute ich, dass Sie möglicherweise nicht bemerkt haben, dass die GOTO-Anweisung nur 11 Bits für die Adresse verwendet. Es kann nur innerhalb der aktuellen Code-"Page" verzweigt werden, wobei die oberen Adreßbits bei der Verzweigung zu einer neuen Adresse unverändert bleiben.
Wenn Sie in Assembly schreiben, verwenden Sie normalerweise Labels. Selbst wenn Sie absolute Adressen verwendet haben, "rechnet" der Assembler immer noch für Sie, um sicherzustellen, dass die von Ihnen angegebene Adresse "in Reichweite" ist. Sie würden also auf die eine oder andere Weise nicht einmal wissen, was vor sich geht, es sei denn, Sie sehen sich den von ihm generierten Maschinencode genau an.
Lassen Sie mich dokumentieren, was ich oben sehe (zusammen mit einer fehlenden Spalte, von der ich aufrichtig wünschte, Sie hätten sie auch aufgenommen):
Address Machine Code Code Lines Description
0x178E BCF STATUS, 0x5 These two lines make sure that data access
0x178F BCF STATUS, 0x6 is on page 0 where PORTE is at.
0x1790 BTFSS PORTE, 0x2 Skip GOTO if the loop should continue.
0x1791 GOTO 0x7E5 Go out of loop to 0x17E5 (past the GOTO.)
0x1792 BTFSC PORTE, 0x0 "if ArrowUpClosed()"
0x1793 <>
0x1794 <>
... ...
0x17E1 <>
0x17E2 <>
0x17E3 <>
0x17E4 GOTO 0x78E Branch to address 0x178E (start of loop.)
0x17E5 MOVLW 0x8
Wenn Sie feststellen, dass der codierte Maschinenbefehl für das GOTO nur 11 Bits enthält, können Sie sehen, warum nicht das gesamte „0x17E5“ oder „0x178E“ in das Maschinenwort codiert werden kann. Diese Tatsache hindert den Assembler und/oder Compiler jedoch nicht daran zu wissen, dass die Adresse tatsächlich richtig erreicht werden kann (oder nicht, was darauf hinweist, dass möglicherweise mehr Code benötigt wird, um eine weiter entfernte Übertragung durchzuführen.)
Der Code des Compilers funktioniert, glaube ich, sagen Sie. Sie sagen auch, dass es auch funktioniert hat, als Sie einen eigenen Assemblercode geschrieben haben. Ich glaube, beides ist wahr. Aber das Problem kann einfach sein, dass Sie nicht verstanden haben, wie ein Assembler (noch wichtiger, wie ein Linker) im Inneren arbeitet, um korrekten Code zu generieren oder Fehler zu generieren.
Der Assembler und der C-Compiler generieren eine Objektdatei, die "Strings" von wörtlichen Bytewerten + periodische "Patch-up"-Datensätze enthält, die den Linker genau anweisen, wo und wie er Bits und Teile dieser wörtlichen Strings währenddessen reparieren soll die Verlinkungsphase, wenn der Code tatsächlich irgendwo platziert wird. Ich bin mir ziemlich sicher, dass dies für Assembly-generierten Code ein sehr einfacher Prozess ist und der Linker sich beschweren wird, wenn Sie Anweisungen schreiben, die eine Codierung außerhalb des Bereichs erfordern würden. Beim C-Compiler bin ich mir nicht so sicher über die Komplexität, die sich auf den Linker ausdehnt. Aber es ist möglich, dass der C-Compiler nicht
Ich habe mich dazu geäußert. Es kann sein, dass ich Ihre Zwickmühle hier völlig missverstanden habe. Ich bin gerade aufgewacht und wer weiß, ob ich da nur im Schlaf wandle. Aber da ist es. Vielleicht könntest du das Gerät etc. auch klären?
Für diejenigen, die an etwas Geschichte über den XC8 C-Compiler sowie an Informationen über die Optimierungsunterschiede in den PRO-Versionen interessiert sind, fand ich diesen Link sofort nützlich. Daraus kann ich ersehen, dass der XC8-Compiler im Grunde der Hi-Tech-Compiler-Code ist, mit zusätzlichen "Beeinträchtigungen", um die Motivation zum Kauf der PRO-Version ihres Compiler-Toolsets zu "verbessern". Interessante Details dabei.
Anonym
Arsenal
Zehnfüßer
Anonym
Zehnfüßer
Zehnfüßer