Sehr komisches AVR Assembler Problem. Nur drei Anweisungen!

Gast #5341882
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
Gast
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".
Gast
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
Gast
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. :-)
Gast
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
Gast
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.
Gast
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.
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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.