Ich versuche, das folgende einfache Assemblerprogramm zu kompilieren, aber es gibt ein Problem mit dem Compiler, dass ich seinen Grund nicht finden und beheben kann.
Also hier ist der Code:
1 #define __SFR_OFFSET 0
2 #include <avr/io.h>
3
4
5 rjmp Init
6
7 .global Init
8
9 Init: sbi _SFR_IO_ADDR(PORTB),5
10 rjmp In
und wann ich es mit kompilieren werde
avr-as -c -mmcu=atmega168a -o ledON.o ledON.s
Ich bekomme diesen Fehler:
ledON.s: Assembler messages:
ledON.s:9: Error: constant value required
ledON.s:9: Error: `,' required
ledON.s:9: Error: constant value required
ledON.s:9: Error: garbage at end of line
Ich habe auch den Code ein wenig geändert, wie Sie oben sehen können, aber es gibt immer noch einen Fehler
1 ;#define _SFR_OFFSET 0
2 #include <avr/io.h>
3
4 rjmp Init
5
6 .global Init
7
8 Init: sbi PORTB,0x05
9 rjmp Init
ledON.s: Assembler-Meldungen:
ledON.s:8: Fehler: konstanter Wert erforderlich
Irgendwelche Ideen?
Ich habe herausgefunden, wie man ohne Fehlermeldungen zusammenbaut.
Die angezeigten Fehlermeldungen werden dadurch verursacht, dass der C-Präprozessor nichtavr-as
aufgerufen wird und die Zeilen daher als normale Kommentare gelesen werden.#include
Erstellen Sie eine Datei ledON.S
und achten Sie auf das GROSSBUCHSTABEN S
im Dateinamen. Der Großbuchstabe S
zeigt an, dass der C-Präprozessor zuerst aufgerufen werden muss. Erstellen Sie die Datei mit folgendem Inhalt:
#include <avr/io.h>
init: sbi _SFR_IO_ADDR(DDRB),0x05 ; Configure port B pin 5 as output
ret
.global main
main:
call init
loop:
sbi _SFR_IO_ADDR(PORTB),0x05 ; Toggle output pin HIGH
cbi _SFR_IO_ADDR(PORTB),0x05 ; Toggle output pin LOW
rjmp loop
Der main
Teil wird im Quellcode benötigt, dort befindet sich normalerweise das Hauptprogramm. Wenn Sie es entfernen, wird niemals richtiger Code ausgeführt und der Compiler wird sich darüber beschweren. Code in einer aufgerufenen Routine init
sollte explizit von aufgerufen werden main
. Obwohl der Stift umschaltet, ist dies in der Praxis zu schnell, um es mit bloßem Auge zu sehen. Wenn Sie mit einem Oszilloskop überprüfen, sehen Sie eine Rechteckwelle (ich schätze auf 25% Arbeitszyklus).
Dann assemblieren Sie den Quellcode mit:
avr-gcc -mmcu=atmega168a ledON.S -o ledON.o
Wiederum avr-gcc
ist es erforderlich, den C-Präprozessor aufzurufen.
Um das Ergebnis des zusammengestellten Programms zu überprüfen, führen Sie den folgenden Befehl aus:
avr-objdump -C -d ./ledON.o
Und die resultierende Disassemblierungsliste sieht so aus:
./ledON.o: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 34 00 jmp 0x68 ; 0x68 <__ctors_end>
4: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
8: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
10: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
14: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
18: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
1c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
20: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
24: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
28: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
2c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
30: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
34: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
38: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
3c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
40: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
44: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
48: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
4c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
50: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
54: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
58: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
5c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
60: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
64: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
00000068 <__ctors_end>:
68: 11 24 eor r1, r1
6a: 1f be out 0x3f, r1 ; 63
6c: cf ef ldi r28, 0xFF ; 255
6e: d4 e0 ldi r29, 0x04 ; 4
70: de bf out 0x3e, r29 ; 62
72: cd bf out 0x3d, r28 ; 61
74: 0e 94 42 00 call 0x84 ; 0x84 <main>
78: 0c 94 47 00 jmp 0x8e ; 0x8e <_exit>
0000007c <__bad_interrupt>:
7c: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>
00000080 <init>:
80: 25 9a sbi 0x04, 5 ; 4
82: 08 95 ret
00000084 <main>:
84: 0e 94 40 00 call 0x80 ; 0x80 <init>
00000088 <loop>:
88: 2d 9a sbi 0x05, 5 ; 5
8a: 2d 98 cbi 0x05, 5 ; 5
8c: fd cf rjmp .-6 ; 0x88 <loop>
0000008e <_exit>:
8e: f8 94 cli
00000090 <__stop_program>:
90: ff cf rjmp .-2 ; 0x90 <__stop_program>
INTERMEZZO
Sie werden feststellen, dass der Assembler automatisch den Stapelzeiger und das Statusregister in initialisiert
__ctors_end
. Außerdem wirdrjmp
am Ende des Codes automatisch ein hinzugefügt. Das Standardverhalten eines von gcc-avr zusammengestellten Programms beim Beenden ist:
- Unterbrechungen ausschalten (
_exit
,cli
)- endlose leere Schleife, die nichts tut (
__stop_program
,rjmp .-2
)
ledON.S: Assembler messages: ledON.S:8: Error: number must be positive and less than 32
Solche Fehler bedeuten meiner Meinung nach, dass das I/O-Register nicht editierbar ist.rjmp
. Das main
Etikett ist ein erforderlicher Bestandteil des Programms, wenn Sie es entfernen, erhalten Sie eine Fehlermeldung. Normalerweise befindet sich dort das Hauptprogramm.avr-gcc
ruft avr-as
nach dir.
Jippie
avr-as
verwenden Sie, meine unterstützt das-c
Flag nicht, was macht es?FN
-c
Flag bekomme ich den gleichen Fehler :sJippie
FN
Jippie