使用 avr-gcc 编译汇编程序
Compiling an Assembly Program using avr-gcc
我正在尝试在 Attiny85 上使用 avr-gcc 将一个简单的汇编程序编译为 运行。不幸的是,该程序根本不起作用。而且我在上传和编译时没有出错。我知道程序本身应该可以工作,因为它使用 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;
}
首先我想知道您可以使用命令行进行汇编!对我来说根本行不通!
那么你想要达到什么目的?使用 stdlib 支持进行编译( irq jump table,在开始时跳转到 main?还是你想全部手动完成?
全部手工完成:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85 -nostdlib
使用stdlib获取跳转table:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85
如果你在没有跳转的情况下使用它table你应该使用 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 根本不知道额外的用户初始化方法。
我正在尝试在 Attiny85 上使用 avr-gcc 将一个简单的汇编程序编译为 运行。不幸的是,该程序根本不起作用。而且我在上传和编译时没有出错。我知道程序本身应该可以工作,因为它使用 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;
}
首先我想知道您可以使用命令行进行汇编!对我来说根本行不通!
那么你想要达到什么目的?使用 stdlib 支持进行编译( irq jump table,在开始时跳转到 main?还是你想全部手动完成?
全部手工完成:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85 -nostdlib
使用stdlib获取跳转table:
avr-gcc -xassembler-with-cpp x.s -mmcu=attiny85
如果你在没有跳转的情况下使用它table你应该使用 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 根本不知道额外的用户初始化方法。