Forum: Mikrocontroller und Digitale Elektronik Sehr komisches AVR Assembler Problem. Nur drei Anweisungen!


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 ASM Typ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe grad ein Projekt mit einem xmega E und habe einen komischen 
Fehler gesucht. Nach ewigem Runterbrechen und Wegkürzen blieb folgender 
Codeblock übrig:

2:
rjmp 1f
nop
1:
rjmp 2b

1:
rcall blink
rjmp 1b

Natürlich macht dieser Codeblock allein keinen Sinn, er ist halt 
runtergekürzt. Was erwartet man? Natürlich eine Endlosschleife. Was 
passiert? Der rjmp 2b Befehl wird einfach nicht ausgeführt. Er springt 
direkt in die nächste Anweisung. In diesem Fall fängt er an zu blinken.

Habe ich irgendwo einen Denkfehler? So schwer ist der Code nämlich 
nicht!

Ein work-around ist folgender:

2:
rjmp 1f
nop
1:
nop
rjmp 2b

von Grobi (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
ASM Typ schrieb:
> 2:
> rjmp 1f
> nop
> 1:
> rjmp 2b
>
> 1:
> rcall blink
> rjmp 1b

ähh also assembler ist jetzt schon ein wenig was her, aber du siehst 
schon das du das label "1" hier mehrfach definiert hast? Schätze mal der 
compiler / assembler wird dir das "erste" label 1 "wegoptimieren".

von avr (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Grobi schrieb:
> Schätze mal der
> compiler / assembler wird dir das "erste" label 1 "wegoptimieren".

Nein das ist erlaubt. Mit f_orward und b_ackward wird die Sprungrichtung 
zum nächsten Label angegeben.

Was sagt denn das Disassembly?

von Grobi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
avr schrieb:
> Nein das ist erlaubt. Mit f_orward und b_ackward wird die Sprungrichtung
> zum nächsten Label angegeben.

... hmmm also grad mal probiert avr studio 4 ein asm test project:
1
two:
2
rjmp onef
3
nop
4
one:
5
rjmp twob
6
7
one:
8
rcall blink
9
rjmp oneb
10
11
blink:
12
nop
13
ret

->C:\mc\TestProjectASM001\main.asm(54): error: Duplicate label: 'one'
C:\mc\TestProjectASM001\main.asm(51): info: previous definition of 'one'

und nur die Zahl 1 oder 2 -> unexpected integer!

kann doch was nicht so wirklich richtig sein

von ASM Typ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Disassembler:

  94:       01 c0           rjmp    .+2
  96:       00 00           nop
  98:       fd cf           rjmp    .-6

von ASM Typ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
das mit 1b und 1f ist legitim. kann sein, dass es ein reines gnu 
assembler ding ist.

von ASM Typ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ohne diese Funktion sollte folgender Code identisch sein:

start:
rjmp bla
nop
bla:
rjmp start

blubb:
rcall blink
rjmp blubb

von Theor (Gast)


Bewertung
0 lesenswert
nicht lesenswert
@ ASM Typ

Hm. Laut der GNU Assemblerbeschreibung sollte der Code so ablaufen, wie 
Du es im ersten Post beschrieben hast.

Du könntest Dir ja mal den Assembleroutput (also das Listing) anschauen, 
ob der GNU AS das auch wie beschreiben in nicht-lokale Labels umsetzt. 
Vielleicht ist das ja nur ein Bug in einer bestimmten Version.


P.S. Es juckt mich, noch ein persönliche Wertung dieses "Features" 
hinzuzufügen. Aber die Anführungszeichen sollen hier mal reichen. :-)

von Grobi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
1
start:
2
rjmp bla
3
nop
4
bla:
5
rjmp start
6
7
blubb:
8
rcall blink
9
rjmp blubb
10
11
blink:
12
nop
13
ret

->

---- main.asm 
------------------------------------------------------------------------ 
-------------
1
44:       rjmp bla
2
+00000020:   C001        RJMP      PC+0x0002      Relative jump
3
45:       nop
4
+00000021:   0000        NOP                      No operation
5
@00000022: bla
6
47:       rjmp start
7
+00000022:   CFFD        RJMP      PC-0x0002      Relative jump
8
@00000023: blubb
9
50:       rcall blink
10
+00000023:   D001        RCALL     PC+0x0002      Relative call subroutine
11
51:       rjmp blubb
12
+00000024:   CFFE        RJMP      PC-0x0001      Relative jump
13
@00000025: blink
14
54:       nop
15
+00000025:   0000        NOP                      No operation
16
55:       ret
17
+00000026:   9508        RET                      Subroutine return

von fop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
hm, was kommt vor dem ausgelassenen Jump ?
Es gibt nämlich so was wie 'skip if' in AVR Assembler. Das bewirkt, dass 
unter festgelegten Umständen der folgende Befehl nicht ausgeführt wird.
Möglicherweise steht auch direkt vor dem Jump ein halber 2-Byte-Befehl, 
so dass der Jump nicht als solcher, sondern als 2. Hälfte des 
vorhergehenden Befehls interpretiert wird.

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
Grobi schrieb:
> kann doch was nicht so wirklich richtig sein

Ja. Der Fehler ist, daß du einen anderen Assembler verwendest.

Siehe 
https://sourceware.org/binutils/docs/as/Symbol-Names.html#Symbol-Names 
unter "Local Labels"

von M. H. (bambel2)


Bewertung
0 lesenswert
nicht lesenswert
ASM Typ schrieb:
> Natürlich macht dieser Codeblock allein keinen Sinn, er ist halt
> runtergekürzt. Was erwartet man? Natürlich eine Endlosschleife.

Ich kann dieses Verhalten mit deinem geposteten Code nicht 
nachproduzieren. Kann allerdings auch daran liegen, dass ich die 
Label-Namen geändert habe, da ich nicht den GNU-Assembler verwende. Bei 
mir sieht der produzierte Binärcode genau so aus wie bei "Grobi (Gast)" 
und funktioniert auch.

Hast du es mal mit anderen Labels probiert?
Es gibt zwei Möglichkeiten:
1) Du hast einen Assemberlfehler entdeckt.
2) Dein Code ist anders als dargestellt.

Das dekompilierte Assembler-Listing in Kombination mit dem verwendeten 
Source-Code würde, wie bereits gesagt, helfen.

von ASM Typ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe es bereits mit festen Labels versucht. Der Codeblock wird 
zuverlässig immer übersprungen. Getestet habe ich es aber nur auf dem 
xmega E.

von ASM Typ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe auch ein neues Projekt gemacht, nur mit diesem Code. Nach dem 
Code dann ein sbi als Kontrollfunktion. Auch hier wird der Codeblock 
immer übersprungen...

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
Da ergibt alles keinen Sinn. Der gezeigte Code
1
2:
2
    rjmp 1f
3
    nop
4
1:
5
    rjmp 2b

ergibt - mit dem GNU Assembler für AVR assembliert - zweifellos eine 
Endlosschleife. Mit einen anderen Assembler dürfte er gar nicht 
assemblierbar sein.

So sieht es bei mir aus:
1
/tmp $cat test.S
2
        .section .text
3
        .org 0
4
2: 
5
        rjmp 1f
6
        nop
7
1: 
8
        rjmp 2b
9
/tmp $avr-gcc -o test.elf test.S
10
/tmp $avr-objdump -d test.elf 
11
12
test.elf:     file format elf32-avr
13
14
15
Disassembly of section .text:
16
17
00000000 <__ctors_end>:
18
   0:   01 c0           rjmp    .+2             ; 0x4 <__ctors_end+0x4>
19
   2:   00 00           nop
20
   4:   fd cf           rjmp    .-6             ; 0x0 <__ctors_end>

Ganz klar eine Endlosschleife. Das erste rjmp springt zu Adresse 4, das 
zweite zurück zu Adresse 0.

Also: wo kommt der gezeigte Code her? Wie hast du die Funktion getestet?

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]
  • [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.