【问题标题】:Compiling an Assembly Program using avr-gcc使用 avr-gcc 编译汇编程序
【发布时间】:2015-07-13 10:32:16
【问题描述】:

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

【问题讨论】:

  • 您是否将其与 C 程序生成的程序集进行了比较?例如DDRB = 0xff;, while (1) PORTB = 0xff;
  • @BrettHale 是的,我现在也包含了成功编译的 C 程序。
  • 这两个程序是不等价的。 C 版本将PORTB 初始化为零,而汇编版本则不会。
  • 链接器是否了解全局init 符号?你不应该让main 成为全球性的吗?
  • 好评@BrettHale 在重写程序几次后,我完全忘记了它。不幸的是,它没有解决我的问题。

标签: c assembly microcontroller avr avr-gcc


【解决方案1】:

首先我想知道您可以使用命令行进行组装!对我来说它根本行不通!

那么你想要实现什么?使用 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 根本不知道额外的用户 init 方法。

【讨论】:

  • 感谢您的精彩回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多