Datenzugriff

 

Globale Variablen

 

Im Bytecode Interpreter liegen in den Registern 8 und 9 ein 16-Bit Zeiger auf das Ende des Speicherbereichs der globalen Variablen. Möchte man auf eine globale Variable zugreifen, die in der ".def" Datei definiert wurde, so erhält man die Adresse der Variablen, wenn man die Position der Variablen von R8,R9 abzieht. Dies sieht dann so aus:

 

 

    ; global variable access example

    ; write 0042 to global variable glob1

    MOVW R26,R8          ; get Ram Top from register 8,9

    SUBI R26,LOW(glob1)  ; subtract index from glob1 to get address

    SBCI R27,HIGH(glob1)

 

Liegt dann die Adresse der globalen Variable im X Registerpaar  (R26,R27), dann kann man den gewünschten Wert (in unserem Beispiel 42) dort hineinschreiben:

 

    LDI  R30,LOW(42)

    ST   X+,R30

    CLR  R30             ; the high byte of 42 is zero

    ST   X,R30

 

 

 

Parameterübergabe

 

Parameter werden auf dem Stack des Bytecode Interpreters übergeben. Der Stackpointer (SP) sitzt im Registerpaar R10,R11. Werden Parameter übergeben, so werden sie der Reihe nach auf den Stack geschrieben. Da der Stack nach unten wächst, sieht in unserem Beispiel (integer a, floating point b, byte c) das Speicherlayout folgendermaßen aus:

 

SP+5: a  (typ integer, länge 2)

SP+1: b  (typ float, länge 4)

SP+0: c  (typ byte, länge 1)

 

 

Möchte man nun a und c addieren, so findet man a bei SP+5, und c bei SP. Im folgenden Assembler Code wird der SP (R10,R11) in das Registerpaar Z (R30,R31) kopiert, und dann indirekt über Z die beiden Parameter a und c geladen.

 

    ; example for accessing and returning parameter

    ; we have int proc2(int a, float b, byte c);

    MOVW R30, R10 ; move parameter stack pointer into Z

    LDD R24, Z+5  ; load parameter "a" into R24,25

    LDD R25, Z+6

 

    LDD R26, Z+0  ; load byte parameter "c" into X (R26)

    CLR R27       ; hi byte zero because parameter is byte

 

Man hat jetzt die beiden Parameter a und c in den Registerpaaren X und R24,R25. Nun kann man die Zahlen addieren.

 

    ADD R24, R26  ; add X to R24, R25

    ADC R25, R27

 

 

 

Rückgabe von Werten

 

In der Routine proc2 wird auch die Summe zurückgegeben. Rückgabewerte werden auf den Parameter Stack (PSP) des Bytecode Interpreter geschrieben. Der Zeiger auf den PSP liegt im Registerpaar R6,R7. Man muss vorher allerdings eine 4 auf den PSP Zeiger addieren, dann kann man den Wert dort speichern. Im Gegensatz zur Parameterübergabe spielt der Typ des Rückgabeparameters keine Rolle. Auf dem Parameterstack sind alle Parameter immer 4 Bytes lang.

 

 Auch bei einem 8-Bit Rückgabewert erwartet der Interpreter immer einen 16-Bit Wert, dies wird gemacht um Bytecodes im Interpreter einzusparen. Ist die Assemblerroutine als byte deklariert, muss ein word als Rückgabewert geschrieben werden, ist die Assemblerroutine vom Typ char, ist ein int erforderlich. In allen anderen Fällen ist keine Änderung erforderlich.

 

 

    ; return a + c

      MOVW R30, R6      ; copy stack pointer from R6

      ADIW R30, 4       ; add 4 to sp  - ADIW only works for R24 and greater

      MOVW R6, R30      ; copy back to stack pointer location

 

      ST   Z+, R26      ; store R26, R27 on stack

      ST   Z, R27