www.mikrocontroller.net

Forum: Compiler & IDEs functionpointer & assembler


Autor: Martin -- (smartic)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin -- (smartic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin -- (smartic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Martin -- (smartic)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.