atmega 8535 icall

Gast #3355073
Lesenswert?

Hallo Forum, habe ein kleines Problem. Folgendes Programm:

lpm tmp1,z+
lpm tmp2,z+
push zl
push zh
mov zl,tmp1
mov zh,tmp2
icall
pop zh
popzl
ret

Ich hab eine Tabelle in der Sprungadressen zu verschiedenen 
Unterprogrammen gespeichert sind. Ich lese also so eine Adresse mit lpm 
nach tmp1(R16) und tmp2(R17) aus. Danach bringe ich zl und zh auf den 
Stapel um diesen zu retten. Danach speichere ich tmp1/2 nach zl/zh. Wenn 
ich icall aufrufe springt dieser aber nich zu der durch das Z-Register 
adressierten Adresse sonder zu Adresse 9 im Programmspeicher. Kann mir 
jemand sagen warum?
Gast #3355139
Lesenswert?

Ich habe, sagen wir z.B., das Unterprogramm "Test".
Im Programmspeicher steht dann:
test:
  Befehl 1
  Befehl 2
      .

      .
  Befehl X

In die Tabelle las ich dann folgendes durch den Assembler ein schreiben:

.db low(test),high(test),12,0

danach lasse ich die zwei Speichstellen durch die ersten zwei 
lpm-Befehle auslesen. Siehe oben
Gast #3355196
Lesenswert?

Jetzt weiß ich was gemeint ist. Ich lade den Anfang der Tabelle in das 
Z-Register und addiere die Sprunweite die benötigt wird dazu und dann 
gehts oben weiter. Das mit der Sprungweite usw. funktioniert im 
Simulator. In den Z-Rgistern steht ja auch dann die richtige Adresse, 
nur sobald der Simulator zum icall-Befehl kommt springt er falsch, also 
immer zur Adresse 9, obwohl zuvor die richtige Adresse im Register 
gestanden hat. Er überträgt also nicht den Z-Registerinhalt sondern 
einen Wert den der Simulator sich aus den Fingnägle saugt.
Gast #3355270
Lesenswert?

Haben Sie das Problem nur in der virtuellen Welt, sprich im Simulator? 
Und wenn ja, in welchem?

Bei mir läuft real, es wird 'B' ausgegeben:

  ldi  ZH,high(Tabelle*2)
  ldi  ZL,low(Tabelle*2)
  adiw  ZL,2
  lpm  tmp0,z+
  lpm  tmp1,z+
  movw  ZL,tmp0
  icall
  rjmp  pc

Tabelle:
.db  low(Test1),high(Test1)
.db  low(Test2),high(Test2)
.db  low(Test3),high(Test3)

Test1:
  ldi  tmp0,'A'
  rcall  disp_byte
  ret

Test2:
  ldi  tmp0,'B'
  rcall  disp_byte
  ret

Test3:
  ldi  tmp0,'C'
  rcall  disp_byte
  ret
Gast #3355925
Lesenswert?

Hallo, tschuldigung für meine späte Antwort. Ich denke ich habe den 
Fehler gefunden. Manchmal sollte man doch nichts ausschließen. Ich hab 
Ihr Programm abgetippt, welches auch im Simu funktioniert. Danach länger 
auf die Suche gegangen. Habe mir selber ins Bein geschossen. Ich greife 
gleichzeitig noch auf den Programmspeicher zu um Daten ins Ram 
einzulesen, diese Adressen muß man mit z.B. low(test*2), high(test*2) 
kodieren. Anders bei den Sprungadressen, diese werden nicht mit *2 
kodiert. Aber ich habe es trotzdem gemacht und habe es Tagen übersehen. 
Gott wie blind kann man sein. Ich danke für die schnelle Antwort, die 
mir zum Schluß den richtigen Stups gegeben hat.

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