avr - Atmel Studio AVR 操作数超出范围

标签 avr atmelstudio

我正在开发一个小程序,以学习如何在 Atmel Studio GCC 中混合 C 和汇编。基本上我正在编写一个 C 程序来启动汇编中的堆栈指针。当我构建它时,我不断收到错误“操作数超出范围”。我已经在程序中多次启动堆栈指针,但无法让它在该程序的“.s”文件中工作。我已经让程序与“.s”文件中的不同寄存器一起工作,所以我不认为这是两个文件之间的连接。任何帮助将不胜感激。

主.c:

    #define F_CPU 16000000

    #include <avr/io.h>
    #include <util/delay.h>

    extern void setStackPointer(void);

    int main(void)
    {
        DDRB |= 0x20;
        setStackPointer();
        while (1) 
        {
            PORTB = 0x20;
            _delay_ms(500);
            PORTB = 0x00;
            _delay_ms(500);
        }
    }

汇编器1.s:

    #define _SFR_ASM_COMPAT 1
    #define _SFR_OFFSET 0
    #include <avr/io.h>

    .global setStackPointer

    setStackPointer:
                ldi r18, lo8(RAMEND-0x20)
                out SPL, R18
                ldi R18, hi8(RAMEND-0x20)
                out SPH, R18
                ret

最佳答案

这里有几个问题。

首先,乔·布莱克爵士的评论是正确的:没有理由 从 RAMEND 中减去 0x20。我的意思是,除非你想分开 32 RAM 末尾的字节...

其次,自己设置堆栈指针是没有意义的。在大多数 最新的AVR,包括ATmega328P,SP会自动初始化 由硬件通过 RAMEND 实现。 C.f.数据表。如果不是的话 足够了,它由 C 运行时再次初始化,正常运行 如果您编译,则链接到您的程序(即使是 100% 汇编程序) 与 gcc 一起使用。

三、来自avr-libc documentation :

For more backwards compatibility, insert the following at the start of your old assembler source file:

#define __SFR_OFFSET 0

This automatically subtracts 0x20 from I/O space addresses, but it's a hack, so it is recommended to change your source: wrap such addresses in macros defined here, as shown below. After this is done, the __SFR_OFFSET definition is no longer necessary and can be removed.

编写该代码的推荐方法是:

setStackPointer:
    ldi r18, lo8(RAMEND)
    out _SFR_IO_ADDR(SPL), r18
    ldi r18, hi8(RAMEND)
    out _SFR_IO_ADDR(SPH), r18
    ret

如果你真的想使用旧的技巧,请写

#define __SFR_OFFSET 0

在程序的开头。并且注意双 宏名称开头加下划线。

关于avr - Atmel Studio AVR 操作数超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47598918/

相关文章:

c - AVR IO 端口不能是全局的

c++ - Atmel Studio 中的 Arduino 产量

c - 在 ARM Cortex M0 uart 控制台使用 printf() 打印 float

带有加载引脚的 AVR isp 连接

avr - 如何使用 avr-gcc 将变量绑定(bind)到未使用的 AVR I/O 寄存器?

compiler-construction - LLVM 对 AVR 的支持如何适用于不同的语言?

c - 需要帮助使用 printf 处理 CHAR 字符串

c - AVR gcc,奇怪的数组行为

无需 Arduino 库的 Arduino 编程 - Atmel Studio

c - 带有软件断点的 Atmel-Ice 调试(SAMD21、SWD)