Assembler Funktion absolut

Gast #3506945
Lesenswert?

Hallo,
ich habe im Bootloader ein paar Funktionen an absoluten Adressen.
zb.:
1
function1:
2
    nop
3
    nop
4
    ret
5
function2:
6
    nop
7
    nop
8
    ret

Diese Funktionen liegen zb. an der Adresse 0x1000 und 0x2000.

Ich habe nun in einem *.S in meiner Application die gleichen Funktinonen 
noch einmal.

Wie kann ich function1 und function2 im .S file definieren damit der 
Compiler (GCC) direkt function1 aus 0x1000 verwendet.

In meinem .S File habe ich eine Funktion die mit rcall function1 und 
function2 aufruft.
1
test:
2
    rcall function1
3
    rcall function1
4
    ret

Kann man diese Beiden Funktionen iregendwie Symbolisch definieren?

Gruß
Sebastian
#3506961
Lesenswert?

Letzten Endes interessiert den Assembler an einem
1
    rcall function1
die Bezeichnung 'function1' nur insofern, als er sie benutzt um in 
seinen Tabellen nachzusehen, welche Adresse sich dahinter verbirgt. Wenn 
der Prozessor den Code ausführt, dann hat er da sowieso eine Zahl 
stehen.

D.h. die Frage lautet eigentlich: muss ich hier einen symbolischen Namen 
benutzen, der sich aus dem Code heraus zu einer Zahl umsetzen lässt, 
oder kann ich selbst da auch eine Zahl benutzen.
Und die Antwort lautet: Selbstverständlich kannst du hier auch eine Zahl 
benutzen! Das ist sogar die viel grundlegendere Form
1
   rcall 0x1000
alles darüber hinausgehende, wie zb die Verwendung von symbolischen 
Namen, um eine Stelle im Code zu kennzeichnen, ist ja nur ein 'Service', 
den dir der Assembler anbietet.


Du wirst aber wahrscheinlich die Zahl nicht direkt im Code benutzen, 
sondern dir selber einen symbolischen Namen dafür definieren, zb mit den 
MItteln, die dir der Assembler dafür anbietet. Eine davon ist es, ein 
Label zu benutzen. Eine andere ist ein .equ
1
.equ function1 = 0x1000
2

3
...
4

5
  rcall function1
(Firma: guloshop.de) #3507414
Lesenswert?

Oliver schrieb:
> rcall springt relativ zum Programmcounter, da wird ein rcall 0x1000
> nicht das gewünschte Ergebnis liefern.

Sicher?
Der Assembler übersetzt normalerweise die absolute Adresse in eine 
relative. Ich habs für rcall nicht getestet, aber bei rjmp läuft das so.

Wenn an Word-Adresse 123 der Befehl
  rjmp 123
steht, dann macht der Assembler ein "rjmp -1" draus, jedenfalls was den 
Maschinencode angeht. Im Quelltext entspricht das einem
  rjmp PC
Gast #3507809
Lesenswert?

Hallo,
danke für eure Antworten.
1
.equ function1, 0x1000

Das war es. Manchmal sieht man den die einfachsten Sachen nicht ;).

Ich nehme rcall weil es nur ein kleiner Mega8 ist. (da muss man auch 
etwas am Speicher sparen).

Gruß
Sebastian
Gast #3507863
Lesenswert?

Markus Weber schrieb:
> Sicher?
> Der Assembler übersetzt normalerweise die absolute Adresse in eine
> relative. Ich habs für rcall nicht getestet, aber bei rjmp läuft das so.

Ich hatte es getestet, weil ich mir auch nicht sicher war, ob der 
Asssembler bei direkten Adressangaben auch umrechnet. Das Ergebnis habe 
ich allerdings falsch interpretiert.
Meine Assembler-Funktion wird von einer C-Funktion aus aufgerufen.
Das hier ist der Assembler-Code:
1
#include <avr/io.h>
2

3
.global myfunc
4
myfunc:
5

6
  push  r18
7
  push  r19
8
  push  r20
9
  push  r21
10
  call 0x1000
11
  rcall 0x1000
12
  pop  r21
13
  pop  r20
14
  pop  r19
15
  pop  r18
16
  ret
17
  
18
  .org 0x100
19
function3:
20
  rcall 0x1000
21
  ret
22
  
23
  .org 0x1000
24
func:
25
ret;

Und das wird da draus:
1
00000076 <myfunc>:
2
#include <avr/io.h>
3

4
.global myfunc
5
myfunc:
6

7
  push  r18
8
      76:  2f 93         push  r18
9
  push  r19
10
      78:  3f 93         push  r19
11
  push  r20
12
      7a:  4f 93         push  r20
13
  push  r21
14
      7c:  5f 93         push  r21
15
  call 0x1000
16
      7e:  0e 94 00 08   call  0x1000  ; 0x1000 <__stack+0xba1>
17
  rcall 0x1000
18
      82:  f9 d7         rcall  .+4082     ; 0x1076 <func>
19
  pop  r21
20
      84:  5f 91         pop  r21
21
  pop  r20
22
      86:  4f 91         pop  r20
23
  pop  r19
24
      88:  3f 91         pop  r19
25
  pop  r18
26
      8a:  2f 91         pop  r18
27
  ret
28
      8c:  08 95         ret

Wie man sieht rechnet der Assembler zwar um, aber bezogen auf das 
aktuelle Segment. Der rcall-Sprung geht also nicht nach 0x1000, sondern 
nach 0x1076.

Oliver
Gast #3507888
Lesenswert?

Hi

>Wie man sieht rechnet der Assembler zwar um, aber bezogen auf das
>aktuelle Segment. Der rcall-Sprung geht also nicht nach 0x1000, sondern
>nach 0x1076.

Kann er gar nicht. rcall kann keine fast 4k entfernte Ziele anspringen. 
Das Ziel von rcall muss im Bereich -2k<=PC<+2k liegen. Der Assembler 
müsste hier eine Fehlermeldung abgeben.

MfG Spess

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