Assembler Neuling - komme nicht weiter

Gast #4465519
Lesenswert?

Hallo,

ich mache meine ersten Gehversuche mit C gemischt mit Assembler und 
brauche da Eure Hilfe.
Ich habe in meinem C-Programm ein Array, dessen Bytes ich in der 
asm-Funktion durchlaufen und damit was machen möchte. Es geht hier nicht 
um eine bestimmte Funktion, sondern nur ums Lernen! Ich möchte auch kein 
Inline-Assembler!

Wenn ich meinen Code kompiliere erhalte ich folgende Fehlermeldungen:

undefined reference to r25
undefined reference to r24
ld returned 1 exit status


Hier meine Code:


C-Datei main.c:

#include <avr/io.h>

extern void firstfunc_asm(uint8_t* pArray);

uint8_t myArray[2];

int main(void)
{
  myArray[0] = 128;
  myArray[1] =  64;

  firstfunc_asm((uint8_t*)myArray);
}


Assembler-Datei test_asm.s:

#include <avr/io.h>

.global firstfunc_asm

.section .text

firstfunc_asm:

  LDI XH, r25
  LDI XL, r24

  LD r1,X+

  ; do somethimg with r1 here
  ret


Was mache ich falsch?

Danke!
Gast #4465550
Lesenswert?

Halt: LDS r25, Adresse von myArray[0]. LD hat ein Pointerregister als 
Argument und das müsste man ja erstmal mit einem Pointer füllen.

LDS braucht ja 2 Clocks, macht vermutlich diese beiden Schritte in einem 
Befehl.
Gast #4465555
Lesenswert?

Hallo Sascha,

danke aber was ich hier mache ist ja auf R25 und R24 zuzugreifen, um den 
C-Pointer in das X-Register (für die indirekte Adressierung) zu 
bekommen.

Wenn man aus C heraus eine asm-Funktion aufruft, dann werden die 
Parameter der C-Funktion in den Registern R25:R24, R23:R22 usw. 
übergeben.
In meinem Fall würde also in R25 der high-Teil und in R24 der low-Teil 
der Adresse des Arrays übergeben.
Nun möchte ich indirekt adressieren und dazu verwende ich das 
X-Register, dass ich über LDI XH, r25 und LDI XL, r24 fülle. Somit 
müsste das X-Register jetzt auf das erste Byte im Array zeigen.
Dann möchte ich mit LF R1, X+ den Inhalt, auf den X nun zeigt in das 
Register 1 kopieren.

Nach meinem Wissensstand müsste das so funktionieren, Aber wie gesagt es 
werden diese Fehler angezeigt.
Gast #4465575
Lesenswert?

Hallo Peter,

danke aber das verstehe ich nicht. :-(
Was macht movw. r26, r24?

1. Frage:
Ist denn, wenn ich in der ASM-Funktion bin, im Register R25 die 
high-Adresse von myArray[0] und in R24 die low-Adresse von myArray[0]?

2.Frage:
Warum geht LDI XH, r25 und LDI XL, r24 nicht?
Ich wollte damit das X-Register auf die Adresse des Arrays setzen
Gast #4465603
Lesenswert?

Hi,

konnte mir selber helfen,

movw r26, r24 kopiert den Inhalt von r25:r24 nach r27:r26 (r27:r26 ist X 
Register) somit ist das, das was ich brauche (Danke Peter).
Habe es probiert und es klappt auch.

Ich würde aber gerne trotzdem wissen, warum ich das nicht so machen kann 
wie ich es gedacht habe mit:

LDI XH, r25
LDI XL, r24

Wo ist da mein Denkfehler?
Gast #4465606
Lesenswert?

T.Baumbach schrieb:
> Hallo Sascha,
>
> danke aber was ich hier mache ist ja auf R25 und R24 zuzugreifen, um den
> C-Pointer in das X-Register (für die indirekte Adressierung) zu
> bekommen.
>
> Wenn man aus C heraus eine asm-Funktion aufruft, dann werden die
> Parameter der C-Funktion in den Registern R25:R24, R23:R22 usw.
> übergeben.
> In meinem Fall würde also in R25 der high-Teil und in R24 der low-Teil
> der Adresse des Arrays übergeben.
> Nun möchte ich indirekt adressieren und dazu verwende ich das
> X-Register, dass ich über LDI XH, r25 und LDI XL, r24 fülle. Somit
> müsste das X-Register jetzt auf das erste Byte im Array zeigen.
> Dann möchte ich mit LF R1, X+ den Inhalt, auf den X nun zeigt in das
> Register 1 kopieren.
>
> Nach meinem Wissensstand müsste das so funktionieren, Aber wie gesagt es
> werden diese Fehler angezeigt.

Der Fehler ist ganz klar, du verwendest LDI und das funktioniert nur mit 
Konstanten Werten, siehe Link.

Du übergibst der ASM Funktion einen Pointer auf dein Array, also musst 
du vermutlich
LD r1, X verwenden, das lädt dir die Daten auf die der X-Pointer zeigt 
in dein r1 Register. Also dein myArray[0].

Mit LD r2, X+ lädst du dann myArray[1].

Ist aber ungetestet.

Aber sicher ist: LDI XH, r25 kann nicht funktionieren weil zweites 
Argument von LDI eine Konstante sein muss, kein Register und keine 
Speicherstelle.
Also nur sowas wie LDI r1, 255 kann funktionieren.
#4465617
Lesenswert?

T.Baumbach schrieb:

> Ich würde aber gerne trotzdem wissen, warum ich das nicht so machen kann
> wie ich es gedacht habe mit:
>
> LDI XH, r25
> LDI XL, r24
>
> Wo ist da mein Denkfehler?

Beim LDI. Das I steht für Immediate. Mit LDI lädt man eine Konstante 
in ein Register. Was du willst, ist ein Register-zu-Register Transfer. 
Der Opcode dafür heißt MOV. Bzw. MOVW für ein Registerpaar.

Leseempfehlung: 
http://www.atmel.com/images/atmel-0856-avr-instruction-set-manual.pdf


@Sascha: wenn du keine Ahnung vom Thema hast, dann schreib doch bitte 
nichts. Ich lese deinen Namen seit ein paar Tagen regelmäßig über Posts, 
die bezeigen daß du noch nicht mal die Problemstellung begriffen hast. 
Deine Hilfsbereitschaft ist zu loben, aber wenn du schon das Problem 
nicht begriffen hast, dann bist du eben gerade keine Hilfe sondern 
trägst nur zur (weiteren) Verwirrung des Fragestellers bei.

PS: das gilt nicht für deinen letzten Post. Aber für die beiden ersten.

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