Forum: Mikrocontroller und Digitale Elektronik X-Pointer mit Speicheradresse füllen (inline)


von Rita (Gast)


Lesenswert?

Hallo,

ich habe eine beliebige Variable z.b. ein unsigned char oder unsigned 
short x und möchte per inline Assembler dessen Adresse in den X-Pointer 
laden.

Nun stehe ich auf dem Schlauch:
Die Adresse ist ein 16Bit Wert, ich kann aber nur XL oder XH mit ldi 
beladen. Muss ich die Adresse meiner Variablen &x noch irgendwie 
bearbeiten? Wie kriege ich den 16Bit wert in den Pointer? :)

Folgendes funktioniert bei mir leider nicht:
1
asm(
2
"ldi XH, %[VARH] \n\t"
3
"ldi XL, %[VARL] \n\t"
4
:
5
:[VARH] "i" (&x >> 8), [VARL] "i" (&x &0xFF)
6
);

Danke euch allen

von Peter D. (peda)


Lesenswert?

Am einfachsten wäre es, wenn Du die Aufgabe in einen sinnvollen Kontext 
stellen würdest (komplette Funktion).

Oftmals braucht man den Compiler nicht zu vergewaltigen, er findet 
selber eine Lösung. Man muß ihm nur ein reales Problem zu lösen geben.

von Stefan E. (sternst)


Lesenswert?

1
"ldi XH, hi8(%[VAR]) \n\t"
2
"ldi XL, lo8(%[VAR]) \n\t"

von Rita (Gast)


Lesenswert?

Die Aufgabe ist es, folgende Funktion in Assembler zu übersetzen, weil 
diese Zeitkritisch ist. Es ist die Berechnung einer Audioausgabe nach 
einem Sample (zwei Signale gleichzeitig) zur Audioausgabe:
1
inline void calcBuffer(WORD * DMA_Buffer){                      //Enen DMA Buffer neu füllen
2
  for(WORD j = 0; j < DMA_BUFFER_SIZE; j++){                    //Jede Buffer Position füllen
3
    g_asToene[0].wCounter += g_asToene[0].wStepSize;              //Schrittgröße addieren
4
    g_asToene[0].cPos += g_asToene[0].wCounter >> 10;              //Geteilt durch 1024 und Vorkommastelle addieren
5
    g_asToene[0].wCounter &= 0x3FF;                        //Modulo 1024; Rest merken
6
    g_asToene[1].wCounter += g_asToene[1].wStepSize;
7
    g_asToene[1].cPos += g_asToene[1].wCounter >> 10;
8
    g_asToene[1].wCounter &= 0x3FF;
9
    DMA_Buffer[j] = 
10
      ((((DWORD)g_awSample[g_asToene[0].cPos]*g_asToene[0].wVol)>>8) + 
11
      (((DWORD)g_awSample[g_asToene[1].cPos]*g_asToene[1].wVol)>>8));
12
  }
13
}

So weit bin ich bis jetzt. Es fehlt jetzt noch folgende Zeile im Code:
1
DMA_Buffer[j] = 
2
      ((((DWORD)g_awSample[g_asToene[0].cPos]*g_asToene[0].wVol)>>8) + 
3
      (((DWORD)g_awSample[g_asToene[1].cPos]*g_asToene[1].wVol)>>8));
1
WORD wCounter0, wCounter1;
2
  WORD wStepsize0, wStepsize1;
3
  BYTE cPos0, cPos1;
4
  WORD i = DMA_BUFFER_SIZE;
5
  
6
  asm (
7
  /*variablen laden*/
8
  "lds %A[C0], %[AC0]      \n\t"          //Counter 0 laden
9
  "lds %B[C0], %[AC0]+1    \n\t"          //..
10
  "lds %A[C1], %[AC1]      \n\t"          //Counter 1 laden
11
  "lds %B[C1], %[AC1]+1    \n\t"          //..
12
  "lds %A[S0], %[AS0]      \n\t"          //Stepsize 0 laden
13
  "lds %B[S0], %[AS0]+1    \n\t"          //..
14
  "lds %A[S1], %[AS1]      \n\t"          //Stepsize 1 laden
15
  "lds %B[S1], %[AS1]+1    \n\t"          //..
16
  "lds %[P0], %[AP0]      \n\t"          //Position 0 laden
17
  "lds %[P1], %[AP1]      \n\t"          //Position 1 laden
18
  
19
  /*Vorberechnung ausführen*/
20
  "REPEAT:          \n\t"
21
  "add %B[C0], %B[S0]      \n\t"          //Stepsize addieren
22
  "adc %A[C0], %A[S0]      \n\t"          //... hier mit carry
23
  "mov __tmp_reg__, %A[C0]  \n\t"          //Counter high temporär kopieren
24
  "andi %A[C0], 0x03      \n\t"          //Module 1024 auf Counter
25
  "lsr __tmp_reg__      \n\t"          //Kopie /2 (eigentlich durch 1024, aber die unteren 8 Byte sind ja schon gelöscht)
26
  "lsr __tmp_reg__      \n\t"          //kopie /2 
27
  "add %[P0], __tmp_reg__    \n\t"          //Addition zur Position
28
  "add %B[C1], %B[S1]      \n\t"          //Stepsize addieren
29
  "adc %A[C1], %A[S1]      \n\t"          //... hier mit carry
30
  "mov __tmp_reg__, %A[C1]  \n\t"          //Counter high temporär kopieren
31
  "andi %A[C1], 0x03      \n\t"          //Module 1024 auf Counter
32
  "lsr __tmp_reg__      \n\t"          //Kopie /2 (eigentlich durch 1024, aber die unteren 8 Byte sind ja schon gelöscht)
33
  "lsr __tmp_reg__      \n\t"          //kopie /2
34
  "add %[P1], __tmp_reg__    \n\t"          //Addition zur Position
35
  
36
  "st X+, __tmp_reg__      \n\t"          //Highbyte speichern
37
  "st X+, __tmp_reg__      \n\t"          //Lowbyte speichern
38
  
39
  "sbiw %[I], 1        \n\t"          //Schelife - 1
40
  "brne REPEAT        \n\t"
41
  
42
  /*variablen speichern*/
43
  "sts %[AC0],%A[C0]      \n\t"          //Counter 0 speichern
44
  "sts %[AC0]+1,%B[C0]    \n\t"          //..
45
  "sts %[AC1],%A[C1]      \n\t"          //Counter 1 speichern
46
  "sts %[AC1]+1,%B[C1]    \n\t"          //..
47
  "sts %[AP0],%[P0]      \n\t"          //Position 0 speichern
48
  "sts %[AP1],%[P1]      \n\t"          //Position 1 speichern
49
  
50
  : [C0] "=r" (wCounter0)
51
    , [C1] "=r" (wCounter1)
52
    , [S0] "=r" (wStepsize0)
53
    , [S1] "=r" (wStepsize1)
54
    , [P0] "=r" (cPos0)
55
    , [P1] "=r" (cPos1)
56
    , [I] "=r" (i)
57
  : [AC0] "i" (&g_asToene[0].wCounter)
58
    , [AC1] "i" (&g_asToene[1].wCounter)
59
    , [AS0] "i" (&g_asToene[0].wStepSize)
60
    , [AS1] "i" (&g_asToene[1].wStepSize)
61
    , [AP0] "i" (&g_asToene[0].cPos)
62
    , [AP1] "i" (&g_asToene[1].cPos)
63
    , [DM] "i" (&g_DmaBuffer2[0])
64
    , [SAMPLE] "i" (&g_awSample[0])
65
  : "memory"
66
  );

von Rita (Gast)


Lesenswert?

Danke Stefan! Das scheint zu klappen!

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
Noch kein Account? Hier anmelden.