Forum: Compiler & IDEs functionpointer & assembler


von Martin -. (smartic)


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.

von kosmonaut pirx (Gast)


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

von Martin -. (smartic)


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

von kosmonaut pirx (Gast)


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

von Martin -. (smartic)


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

von Uhu U. (uhu)


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...

von Martin -. (smartic)


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

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.