Assembler code 68HCS12 (CPU12)

#1902575
Lesenswert?

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
#1902613
Lesenswert?

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.
#1902721
Lesenswert?

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?
#1902883
Lesenswert?

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.
#1905792
Lesenswert?

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?
#1905808
Lesenswert?

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.
#1906208
Lesenswert?

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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren