使用avr-gcc编译汇编程序

时间:2015-07-13 10:32:17

标签: c assembly microcontroller avr avr-gcc

我正在尝试使用av​​r-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;
}

1 个答案:

答案 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?没有人在您定义的符号initmain上外部引用。

因此,如果您使用带有stdlib的版本,则只需要导出main以使其通过启动代码可见。但是如果你想这样做,就无法在main之前使用init。据我所知,avr-libc根本不知道额外的用户初始化方法。