Hallo, Vielleicht könnte mir jemand bei folgenden Problem helfen. Ich habe eine kleine Beispiel Routine in C für den HCS12 in Assembler übersetzt und würde gerne den Assembler code nachvollziehen. C Listing: ------------------------------------------ int sum(int len , int arr []) { int i; int sum = 0; for (i = 0; i < len ; i++) { sum += arr[i]; } return sum; } ------------------------------------------- ASM Listing: -------------------------------------------- _sum: pshd <---hier speichert er den akku D auf den stack leas -4,s <--- hier müsste er 4 bytes für die variablen reservieren? (also den RÜckgabewert, len, und den array pointer=) OFST: set 4 <--- Mir ist nicht ganz klar warum er den Offset auf 4 stellt. s müsste ja die adresse vom stackpointer sein, und der wächst doch nach unten (gegen kleinere adresse). Nur wenn offset 4 ist dann habe ich doch teils positive offsets? .dcall "8,2,_sum" clra clrb std OFST-2,s clra clrb std OFST-4,s bra L7 L3: ldy OFST+4,s ldd OFST-4,s lsld ldd d,y addd OFST-2,s std OFST-2,s ldy OFST-4,s iny sty OFST-4,s L7: ldd OFST-4,s cpd OFST+0,s blt L3 ldd OFST-2,s leas 6,s rts xdef _sum end ------------------------------------------------- LG
Mario Grotschar schrieb: > pshd <---hier speichert er den akku D auf den stack > leas -4,s <--- hier müsste er 4 bytes für die variablen An dieser Stelle: S[0..3] = lokale Variablen S[4..5] = D (len) S[6..7] = return S[8..9] = arr Offenbar wird der erste Parameter in D übergeben, der Rest auf dem Stack. Negativ zu OFST sind so die lokalen Daten, positiv die Parameter.
Mario Grotschar schrieb: > pshd <---hier speichert er den akku D auf den stack Das ist offensichtlich len. Es befindet sich später unter OFST+0,s. > leas -4,s <--- hier müsste er 4 bytes für die variablen > reservieren? (also den RÜckgabewert, len, und den array pointer=) Ja. Es sind zwei Variable: sum (später unter OFST-2,s) und i (später unter OFST-4,s). Der Rückgabewert ist nicht dabei, denn der wird offensichtlich beim Ausstieg über D übergeben. > OFST: set 4 <--- Mir ist nicht ganz klar warum er den > Offset auf 4 stellt. s müsste ja die adresse vom stackpointer sein, und > der wächst doch nach unten (gegen kleinere adresse). Nur wenn offset 4 > ist dann habe ich doch teils positive offsets? Die Stackpointer-Arithmetik (OFST-x,s) hat nichts damit zu tun, wohin der Stackpointer wächst. sum und i haben negative Werte gegenüber OFST+0,s. len ist bei OFST+0, s. Darüber liegt die Rücksprungadresse (OFST+2,s) und dann kommt die Adresse von arr (bei OFST+4,s), die vor dem Aufruf aufs Stack gepusht wurde.
Vielen Danlk für die schnelle Antwort. Eine Frage hätte ich noch. Wie macht er hier ein L3: ldy OFST+4,s <-- in Y register stack pointer laden ldd OFST-4,s <-- var i in den akku D laden. lsld <-- ? ldd d,y <-- arr[i] in akku D laden lsld ist kommt doch einer division durhc 2 gleich?
Mario Grotschar schrieb: > lsld ist kommt doch einer division durhc 2 gleich? Fast richtig. Nur an der Richtung musst du noch arbeiten. Links ist da wo der Daumen rechts ist, wie man gern zu sagen pflegt.
Mario Grotschar schrieb: > Wie macht er hier ein > L3: > ldy OFST+4,s <-- in Y register stack pointer laden Nein. Er lädt Y aus OFST+4,s. Welche Variable sich dort befindet, habe ich bereits geschrieben und andere auch (arr). > ldd OFST-4,s <-- var i in den akku D laden. > lsld <-- ? > ldd d,y <-- arr[i] in akku D laden > > lsld ist kommt doch einer division durhc 2 gleich? Nein. 1 links schieben ist eine Verdoppelung. Da jedes Element in arr 2 Bytes belegt, muss i verdoppelt werden und dann an diesem Offset vom Arraybeginn (ldd d,y) abgeholt werden.
Vielen Dank. Bin schon etwas eingerostet :-). Noch eine weitere Frage. Der CPU12 bietet ja folgende daten typen: 2.3 Data Types The CPU12 uses these types of data: • Bits • 5-bit signed integers • 8-bit signed and unsigned integers • 8-bit, 2-digit binary-coded decimal numbers • 9-bit signed integers • 16-bit signed and unsigned integers • 16-bit effective addresses • 32-bit signed and unsigned integers Negative integers are represented in two’s complement form. Five-bit and 9-bit signed integers are used only as offsets for indexed addressing modes. Sixteen-bit effective addresses are formed during addressing mode computations. Thirty-two-bit integer dividends are used by extended division instructions. Extended multiply and extended multiply-and-accumulate instructions produce 32-bit products. Meine Frage ist warum reserviert der compiler hier genau ein word fürs int anstatt nur jeweils ein byte? Gibt es dafür einen Grund oder reserviert er "vorsorglich" mehr?
Mario Grotschar schrieb: > Meine Frage ist warum reserviert der compiler hier genau ein word fürs > int anstatt nur jeweils ein byte? Gibt es dafür einen Grund oder > reserviert er "vorsorglich" mehr? Compiler sind dumm. Sie tun genau das was man ihnen sagt. Wenn man mit ihnen höflich und korrekt umgeht, dann tun sie das auch ohne Widerspruch. Ganz egal ob das sinnvoll ist oder nicht. Da hast ihm gesagt hast, er solle für die Variablen "int" nehmen. Der Herr C hat ihm gesagt, er sollte so tun als ob alle Rechnungen mindestens als "int" abzulaufen haben. Und hat auch gesagt, dass "int" Daten mindestens 16 Bits haben müssen.
Mario Grotschar schrieb: > Meine Frage ist warum reserviert der compiler hier genau ein word fürs > int anstatt nur jeweils ein byte? Gibt es dafür einen Grund oder > reserviert er "vorsorglich" mehr? Nein, er reserviert nicht vorsorglich mehr. Nach C-Standard hat eine int mindestens 16 Bits zu haben, siehe auch die Antwort meines Vorgängers. Wenn Du eine 8-bit-int brauchst, sieh mal in <stdint.h> nach und nimm uint8_t bzw. int8_t (chars tuns meistens auch, haben aber nicht garantiert 8 Bits).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.