Forum: Mikrocontroller und Digitale Elektronik undefined reference to 'sreg'


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von S. R. (svenska)


Lesenswert?

Hi,

ich bastle gerade an einem größeren AVR-Projekt. Ursprünglich komplett 
in C geschrieben (avr-gcc unter Linux) ist die Performance des 
Hauptmoduls eher mäßig, also schreibe ich das Modul gerade auf Assembler 
um. Mit AVR-Assembler (und speziell avr-as) habe ich bisher nie 
gearbeitet, alles Neuland.

Minimalbeispiel (x.S):
1
#include <avr/io.h>
2
#define avrf r21 /* copy of SREG */
3
4
    in avrf, sreg ;1 /* store H, C */

Ich möchte also einfach nur SREG in ein (benamstes) Register speichern, 
wie es auch überall gemacht wird. Aber irgendwas funktioniert da nicht:
1
$ avr-gcc -mmcu=atmega8515 -std=gnu11 -Wall -Wextra -Os -c -o x.o x.S
2
$ avr-nm x.o|grep sreg
3
       U sreg
4
5
$ avr-gcc -mmcu=atmega8515 -std=gnu11 -Wall -Wextra -Os -o test.elf main.o x.o
6
x.o:(.text+0x0): undefined reference to `sreg'

Was zur Hölle mache ich falsch?

Gruß,
svenska

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

der Name sreg ist eben nicht vereinbart und deshalb unbekannt. Entweder 
Du gibst die absolute Adresse an oder sicherst das Statusregister 
mittels push auf den Stack und holst es mit pop zurück.

MfG

von S. R. (svenska)


Lesenswert?

Warum benutzt die halbe Welt dann "in r24, sreg" und es funktioniert?
In welchem Header wäre "sreg" denn definiert? (Mit SREG geht es auch 
nicht.)

von Thomas E. (thomase)


Lesenswert?

S. R. schrieb:
> Warum benutzt die halbe Welt dann "in r24, sreg" und es funktioniert?

Weil sie "common.h" einbindet.

von Christian S. (roehrenvorheizer)


Lesenswert?

Steht das in deiner 8515.inc nicht drin?
Hast Du sie eingebunden?

;***** Specify Device
.device AT90S8515

;***** I/O Register Definitions
.equ  SREG  =$3f
.equ  SPH  =$3e
.equ  SPL  =$3d
.equ  GIMSK  =$3b
.equ  GIFR  =$3a
.equ  TIMSK  =$39
.equ  TIFR  =$38
.equ  MCUCR  =$35

von Leo C. (rapid)


Lesenswert?

1
#include <avr/io.h>
2
#define avrf r21 /* copy of SREG */
3
    sreg = 0x3f
4
5
    in avrf,sreg ;1 /* store H, C */
1
$ avr-gcc -mmcu=atmega8515 -std=gnu11 -Wall -Wextra -Os -c -o x.o x.S
2
$ avr-objdump -d x.o
3
4
x.o:     file format elf32-avr
5
6
7
Disassembly of section .text:
8
9
00000000 <.text>:
10
   0:  5f b7         in  r21, 0x3f  ; 63
11
$

avr-gcc definiert bei Bedarf "__SREG__"

$ avr-gcc -mmcu=atmega1281 -S ser.c -o -
1
  .file  "ser.c"
2
__SP_H__ = 0x3e
3
__SP_L__ = 0x3d
4
__SREG__ = 0x3f
5
__RAMPZ__ = 0x3b
6
__tmp_reg__ = 0
7
__zero_reg__ = 1
8
  .text
9
.global  __vector_25
10
  .type  __vector_25, @function
11
__vector_25:
12
  push r1
13
  push r0
14
  in r0,__SREG__
15
  push r0
16
  clr __zero_reg__
17
  push r24
18
/* prologue: Signal */
19
/* frame size = 0 */
20
...

von S. R. (svenska)


Lesenswert?

Danke, schaue ich mir im Detail an.

Thomas E. schrieb:
> Weil sie "common.h" einbindet.
Wenn ich <avr/common.h> einbinde, ändert sich nichts.

Christian S. schrieb:
> Steht das in deiner 8515.inc nicht drin?
> Hast Du sie eingebunden?
Nein, das Beispiel ist komplett.
Ich dachte, dass <avr/io.h> ausreicht.
Aber gebracht hat das auch nichts.

Leo C. schrieb:
> #include <avr/io.h>
> #define avrf r21 /* copy of SREG */
>     sreg = 0x3f
>     in avrf,sreg ;1 /* store H, C */

Naja, da definierst du das Symbol selbst, dann ist es natürlich 
vorhanden... ich dachte nur, dass es eigentlich hätte definiert sein 
müssen.

_SREG_ scheint nur bei C-Quellen zu existieren.

von Leo C. (rapid)


Lesenswert?

S. R. schrieb:
> "_SREG_" scheint nur bei C-Quellen zu existieren.

Das existiert bei mir gar nicht.
Der Compiler definiert SREG (ohne die Unterstriche) so, daß der 
Assembler nichts damit anfangen kann:
1
$ avr-gcc -mmcu=atmega8515 -dM -E x.S |grep -i SREG
2
#define SREG_C (0)
3
#define SREG_H (5)
4
#define SREG_I (7)
5
#define SREG_N (2)
6
#define SREG_S (4)
7
#define SREG_T (6)
8
#define SREG_V (3)
9
#define SREG_Z (1)
10
#define AVR_STATUS_REG SREG
11
#define SREG _SFR_IO8(0x3F)
12
#define AVR_STATUS_ADDR _SFR_IO_ADDR(SREG)

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Leo C. schrieb:
> #define SREG_C (0)
> #define SREG_H (5)
> #define SREG_I (7)
> #define SREG_N (2)
> #define SREG_S (4)
> #define SREG_T (6)
> #define SREG_V (3)
> #define SREG_Z (1)
> #define SREG _SFR_IO8(0x3F)

Da sehe ich aber durchaus mir auch vom Assembler bekannt vorkommende 
Werte.
Die Bitpositionen der Test-Flags, wie auch die Position des 
sReg-Register.

MfG

von Jacko (Gast)


Lesenswert?

Bei allen avr-asm-Projekten habe ich bisher nur

das  xxxxdef.inc - File für den jeweiligen avr-µC eingebunden.
Habe bisher noch keine Register-Namen etc. aus dem zugehörigen
µC-Datenblatt vermisst.

Es fehlt also nur die Zeile:

.include "m8515def.inc"

Im Studio 7 wird es nur nervig, weil da schon nach der
Projekt-Eröffnung das *def.inc-File des angegebenen µCs
automatisch eingebunden wird. Nimmt man eine alte Studio-5
asm-Datei und macht kein Semikolon cor der Zeile
.include "xxxxdef.inc"
kommen beim Compile-Lauf endlose Warnings/Errors wegen
doppelter Definitionen...

Andersrum gesehen:
Bei Studio 7 dürfte dieser Fehler garnicht auftreten.

von S. R. (svenska)


Lesenswert?

Christian S. schrieb:
> Steht das in deiner 8515.inc nicht drin?

Falsche Datei, du meinst m8515def.inc. ;-)
Spielt aber auch keine Rolle, denn avr-as kann damit nichts anfangen.

Jacko schrieb:
> Es fehlt also nur die Zeile:
> .include "m8515def.inc"

Falscher Assembler. Ich benutze nicht AVR Studio.

Ich habe den Code jetzt auf AVRA umgeschrieben. Der nutzt die 
INC-Dateien und es baut. Damit ist das Projekt leider ein reines 
Assemblerprojekt geworden, was ich ursprünglich vermeiden wollte. Naja, 
dafür kann ich jetzt einigermaßen AVR-Assembler...

Im Prinzip ist das ein Rewrite des i8080-Emulators aus dem AVR-CP/M, der 
aber externes SRAM benutzt und ein gutes Stück schneller sein sollte. 
Die (unfertige) C-Version war doch arg langsam. Naja, dafür kann ich 
jetzt einigermaßen i8080-Assembler...

Jetzt muss ich nur noch UART-Treiber, HEX-Loader und Mini-BDOS-Emulator 
portieren, dann kann ich den Exerciser wieder starten...

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.