Navigation:  Compiler > Assembler >

Ein Beispiel

Vorherige SeiteZurück zur Kapitel ÜbersichtNächste Seite

 

Am folgenden Beispiel (ist auch in den Demo Programmen enthalten) wird die Struktur von Assemblerroutinen erklärt. Dabei muß in dem Projekt der CompactC Source Code die Endung ".cc" die Assembler Sourcen die Endung ".asm".

 

// CompactC Source

void proc1 $asm("tag1")(void);

int proc2 $asm("tag2")(int a, float b, byte c);

 

int glob1;

void main(void)

{

    int a;

 

    proc1();

    a= proc2(11, 2.71, 33);

}

 

Vor Aufruf der Assembler Prozeduren proc1 und proc2 müssen die beiden Prozeduren erstmal deklariert werden. Dies geschieht mit dem Befehlswort $asm. Die Deklaration sieht in Basic ähnlich aus:

 

' Basic Deklaration der Assembler Routinen

$Asm("tag1") proc1()

$Asm("tag2") proc2(a As Integer, b As Single, c As ByteAs Integer

 

 

Man sieht in der Deklaration die Strings "tag1" und "tag2".  Diese Strings werden in einer ".def" Datei definiert, wenn tatsächlich ein Aufruf der deklarierten Funktionen stattfand. In diesem Fall sieht dann die ".def" Datei folgendermaßen aus:

 

; .def file

.equ glob1 = 2

.define tag1 1

.define tag2 1

 

Setzt man nun im Assembler Source die einzelnen Routinen in ".ifdef ..." Anweisungen, so werden die Routinen nur assembliert, wenn ein Funktionsaufruf wirklich stattfand. Dies spart Platz bei der Codegenerierung. Auch werden in der ".def" Datei die Positionen der globalen Variablen definiert. Die ".def" Datei wird automatisch zusammen mit den Assemblerdateien gemeinsam übersetzt, sie braucht nicht extra inkludiert zu werden.

 

 

Hier folgt nun der Assembler Source der Prozedur proc1. In diesem Source wird die globale Variable glob1 auf den Wert 42 gesetzt.

 

; Assembler Source

.ifdef tag1

proc1:

    ; global variable access example

    ; write 42 to global variable glob1

 

    MOVW R26,R8          ; get RamTop from register 8,9

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

    SBCI R27,HIGH(glob1)

 

    LDI  R30,LOW(42)

    ST   X+,R30

    CLR  R30             ; the high byte is zero

    ST   X,R30

 

  ret

.endif

 

 

Im zweiten Teil des Assembler Sources werden die übergebenen Parameter "a" und "c" als integer addiert, und die Summe dann zurückgegeben.

 

.ifdef tag2

proc2:

    ; example for accessing and returning parameter

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

    ; return a + c

 

    MOVW R28, R10   ; move parameter stack pointer into Y

    LDD R26, Y+5  ; load parameter "a" into X (R26)

    LDD R27, Y+6

 

    LDD R30, Y+0  ; load byte parsmeter "c" into Z (R30)

    CLR R31       ; hi byte zero because parameter is byte

 

    ADD R26, R30  ; add Z to X

    ADC R27, R31

 

    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 X on stack

    ST   Z, R27

 

    ret

.endif