functionpointer & assembler

OP #638947
Lesenswert?
• ▲
▼
Hallo

Ich bin da auf etwas gestossen, auf das ich keine erklärung finde.

Ich möchte mit assembler einen funktionspointer in register laden.
Leider steht da immer die doppelte größe der eigentlichen addresse 
drinn.

Hier mal der asm code:

;~~ functionspointer in register laden ~~
        ldi  r16,lo8(Dispatcher)
        ldi  r17,hi8(Dispatcher)
;~~

;~~ function ~~
.global Dispatcher
Dispatcher:
  push  r16
  ldi    r16,counter
  inc    r16
  pop    r16
  ret
;~~

Zusammengebaut wird das Programm mit WinAvr unter avr-studio. Das 
programm hat einen C und Asm teil.

der aufruf:

avr-gcc.exe -I"C:\Programme\WinAVR\avr\include"  -mmcu=atmega32 
-mmcu=atmega32 -Wall -gdwarf-2 -DF_CPU=16000000UL -O0 -fsigned-char -MD 
-MP -MT ismr.o -MF dep/ismr.o.d  -x assembler-with-cpp -Wa,-gdwarf2 -c 
../ismr.S

macht daraus:

~~ functionspointer in register laden ~~
+000000BE:   EA00        LDI     R16,0xA0         Load immediate
+000000BF:   E011        LDI     R17,0x01         Load immediate
~~

~~ function ~~
+000000D0:   930F        PUSH    R16              Push register on stack
+000000D1:   E706        LDI     R16,0x76         Load immediate
+000000D2:   9503        INC     R16              Increment
+000000D3:   910F        POP     R16              Pop register from 
stack
+000000D4:   9508        RET                      Subroutine return
~~

wie man schön sehen kann wird mit r17/r16 die adresse 0x01A0 geladen, 
welche aber nicht die anzuspringenden adresse 0x00D0 ist. Halbiert man 
0x01A0 bekommt man 0x00D0.

Mein Frage: was ist da los?

Vielen dank für Antworten.
Gast #639003
Lesenswert?
• ▲
▼
moin,
das liegt daran, dass der assembler byte-weise adressiert. der avr dies 
aber word-weise tut. daher kannst du meines wissens nach mit dem gnu 
assembler (gas) keine symbole direkt für sowas benutzen. die adresse ist 
durch die byte-zählung immer doppelt so groß wie vom avr benötigt.
bye kosmo
OP #639300
Lesenswert?
• ▲
▼
Hi,
das klingt logisch. :-) Dank für die Antwort.

Was mich aber ein bischen stutzig macht ist, das wenn ich ein call/jmp 
und ähnliche Befehle verwende die Adresse richtig eingtragen wird.

Ich habe das Programm noch nicht auf der Hardware laufen lassen. Kann es 
sein, dass wenn ich die die Adresse manuell halbiere dies auf dem 
Simulator läuft, aber auf der Hardware nicht?

Gibt es eine Option für den Comiler der das beschriebene Problem lösen 
kann, oder vieleicht ein andere Comiler den ihr mir empfehlen könnt.?

thx
Martin
Gast #639303
Lesenswert?
• ▲
▼
hallo,

>Was mich aber ein bischen stutzig macht ist, das wenn ich ein call/jmp
>und ähnliche Befehle verwende die Adresse richtig eingtragen wird.

nun, da vermute ich mal ist der assembler so clever und weiß, dass er 
wordweise adressieren muss. beim manuellen vorgehen fehlt ihm darüber 
die kenntnis.

>Ich habe das Programm noch nicht auf der Hardware laufen lassen. Kann es
>sein, dass wenn ich die die Adresse manuell halbiere dies auf dem
>Simulator läuft, aber auf der Hardware nicht?

wie willst du das machen? abgesehen von vorgegebenen (festen) adressen 
für symbole ist mir kein weg bekannt zur halbierung.
zum vergleich simulator - hardware bin ich überfragt.

>Gibt es eine Option für den Comiler der das beschriebene Problem lösen
>kann, oder vieleicht ein andere Comiler den ihr mir empfehlen könnt.?

das betrifft den assembler, nicht den compiler.
aber: nope, mir ist nichts bekannt. aber es gab hier vor kurzem einen 
von mir angestossenen thread, da wurde sich am rande kurz über die 
unterschiedliche adressierugn von zwei verschiedenen assemblern 
beschwert :)

bye kosmo
OP #639403
Lesenswert?
• ▲
▼
hi,

> wie willst du das machen? abgesehen von vorgegebenen (festen) adressen
> für symbole ist mir kein weg bekannt zur halbierung.

da die doppelte adresse in den registern liegen, kann ich diese doch 
einfach halbieren und weiterverwerten. :-) Klappt soweit auch gut, aber 
nach meiner Meinung nicht keine ideale Lösung. :-(
Hät ja vieleicht sein können das jemand schon so ein ähnliches Problem 
geschickt gelöst hat.

gruß martin
#639508
Lesenswert?
• ▲
▼
Versuchs doch mal so:

;~~ functionspointer in register laden ~~
        ldi  r16,lo8(Dispatcher/2)
        ldi  r17,hi8(Dispatcher/2)

und sieh mal nach, ob es für Codeadressen spezielle Macros lo8 und hi8 
gibt - die könnten den Job ordentlich machen.

Diese Harvard-Architektur war mir schon immer suspekt...
OP #639933
Lesenswert?
• ▲
▼
Hi,

Dein Lösungsvorschlag sieht sauber aus. :-) Leider nimmt der assembler 
diese Zeilen nicht an.:-(.

Bin schon seit mehreren Tagen dabei ein List von Macros + Beschreibung 
im Netz zu finden, leider erfolglos. Einige konnte ich von dieser Seite 
www.mikrokontroller erhaschen. Vieleicht hat da jemand eine Idee wo ich 
solch eine Liste finden kann. :-). Was ich jetzt soweit weiss ist, das 
nicht alle verfügbaren Macros ohne zu mekkern gehen, z.b. .equ .def; Wie 
ich schon oben beschrieben habe nutzte ich den Assemblercode in einer 
extra Datei in einem C Programm.

bye Martin

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.