我正在尝试使用avr-gcc编译一个简单的汇编程序,以便在Attiny85上运行。不幸的是,该计划根本不起作用。上传和编译时我没有错误。我知道程序本身应该可以工作,因为它可以使用C.所以我错过了什么?
编译和上传:
avr-gcc blinky.S -mmcu=attiny85 -Os -g -o blinky.out
avr-objcopy -O ihex blinky.out blinky.hex
sudo avrdude -p attiny85 -c usbasp -P usb -e -U flash:w:blinky.hex
blinky.S
#define F_CPU 1000000L
#include <avr/io.h>
.section text
.org 0
.global init
rjmp init
init:
ldi r23,0x00
ldi r24,0xFF
out _SFR_IO_ADDR(DDRB), r24
out _SFR_IO_ADDR(PORTB), r23
rjmp main
.org 0x020
.global main
main:
out _SFR_IO_ADDR(PORTB), r24
rjmp main
输出:
Philipps-MacBook-Pro:Desktop philippbraun$ sh script.sh attiny85 blinky.S
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e930b
avrdude: erasing chip
avrdude: safemode: Fuses OK
avrdude done. Thank you.
COMPILING AS ASSEMBLY FILE
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e930b
avrdude: erasing chip
avrdude: reading input file "blinky.hex"
avrdude: input file blinky.hex auto detected as Intel Hex
avrdude: writing flash (46 bytes):
Writing | ################################################## | 100% 0.03s
avrdude: 46 bytes of flash written
avrdude: verifying flash memory against blinky.hex:
avrdude: load data flash data from input file blinky.hex:
avrdude: input file blinky.hex auto detected as Intel Hex
avrdude: input file blinky.hex contains 46 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.03s
avrdude: verifying ...
avrdude: 46 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done. Thank you.
以下C程序编译成功!
#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = 0xFF; // PORTB is output, all pins
PORTB = 0x00; // Make pins low to start
for (;;) {
PORTB = 0xFF; // invert all the pins
//_delay_ms(5000); // wait some time
}
return 0;
}
答案 0 :(得分:2)
首先,我想知道您可以使用命令行进行汇编!对我来说它根本不起作用!
那么你想要实现什么?使用stdlib支持编译(irq跳转表,在开始时跳转到main?或者你想手动完成所有操作?
手工完成:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85 -nostdlib
使用stdlib获取跳转表:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85
如果您在没有跳转表的情况下使用它,则应使用avr-as而不是avr-gcc!
所以我用手工制作的版本尝试了你的代码,我的程序集只是空的!为什么呢?
你有一个错字:
.section text
错了!
使用:
.section .text
我的转储看起来像这样:
00000000 <init>:
0: 8f ef ldi r24, 0xFF ; 255
2: 87 bb out 0x17, r24 ; 23
4: 0d c0 rjmp .+26 ; 0x20 <main>
...
00000020 <main>:
20: 88 bb out 0x18, r24 ; 24
22: fe cf rjmp .-4 ; 0x20 <main>
这里什么都没眨眼!
下一篇:为什么在这里使用.org?如果你向init添加一些大于0x020的代码大小,它将被main覆盖!所以只需删除那些脏线!
#include <avr/io.h>
ldi r23,0x00
ldi r24,0xFF
out _SFR_IO_ADDR(DDRB), r24
main:
out _SFR_IO_ADDR(PORTB), r24
out _SFR_IO_ADDR(PORTB), r23
rjmp main
结果:
00000000 <__ctors_end>:
0: 70 e0 ldi r23, 0x00 ; 0
2: 8f ef ldi r24, 0xFF ; 255
4: 87 bb out 0x17, r24 ; 23
00000006 <main>:
6: 88 bb out 0x18, r24 ; 24
8: 78 bb out 0x18, r23 ; 24
a: fd cf rjmp .-6 ; 0x6 <main>
为什么你使用.global
?没有人在您定义的符号init
和main
上外部引用。
因此,如果您使用带有stdlib的版本,则只需要导出main以使其通过启动代码可见。但是如果你想这样做,就无法在main之前使用init
。据我所知,avr-libc根本不知道额外的用户初始化方法。