C Arduino汇编程序编程:什么都没有发生

C Arduino汇编程序编程:什么都没有发生,c,assembly,arduino,avr-gcc,C,Assembly,Arduino,Avr Gcc,大家好,我的社区 我正在尝试用汇编语言编程我的旧Arduino Duemilanove板(Atmega 168V-10PU)。我以前试过几次,但每次代码都没有执行。所以我试着用C语言编写一个等价的测试程序,它成功了。这是: // file led.c #include <avr/io.h> int main(void) { DDRB = 0xFF; PORTB = 0xFF; while (1) { asm("nop\n"); }

大家好,我的社区

我正在尝试用汇编语言编程我的旧Arduino Duemilanove板(Atmega 168V-10PU)。我以前试过几次,但每次代码都没有执行。所以我试着用C语言编写一个等价的测试程序,它成功了。这是:

// file led.c
#include <avr/io.h>

int main(void)
{

    DDRB = 0xFF;
    PORTB = 0xFF;

    while (1) {
        asm("nop\n");
    }

    return 0;
}
它工作并激活Arduino引脚13(AVR引脚PB5)处的LED

但是当我使用这个asm文件时

// file led.S
#include "avr/io.h"

.global main

main:
    ldi r24, 0xFF
    out DDRB, r24
    out PORTB, r24

 end:
    jmp end
编译器转储会导致(缩短)

什么可以解释为什么什么都没发生

此外,下面是和的makefile

谢谢你的帮助

编辑:这里还有和的完整汇编程序转储文件

编辑2:我在include文件iom168.h中查找了寄存器地址,该文件引用了iomx8.h,其中显示
#define PORTB\u SFR\u IO8(0x05)
。编译器遵循包含链

io.h -> iom168.h -> iomx8.h
io.h -> common.h -> sfr_defs.h
sfr_defs.h中写道:

#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
定义了向上偏移的几行:

#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
#  if __AVR_ARCH__ >= 100
#    define __SFR_OFFSET 0x00
#  else
#    define __SFR_OFFSET 0x20
#  endif
#endif
(很抱歉格式化)
知道这个错误是从哪里来的吗?

您应该使用helper宏
\u SFR\u IO\u ADDR()
\u SFR\u MEM\u ADDR()
分别使用i/o和内存指令访问SFR,因为它们在两个名称空间中有不同的地址。默认值显然是内存映射,但不要指望它

因此,您的代码可能如下所示:

#包括“avr/io.h”
.全球主要
主要内容:
本地设计院r24,0xFF
输出SFR IO地址(DDRB),r24
输出地址(端口B),r24
完:
jmp端
或者,您可以切换到内存映射访问:

#包括“avr/io.h”
.全球主要
主要内容:
本地设计院r24,0xFF
sts-SFR-MEM地址(DDRB),r24
sts-SFR-MEM地址(端口B),r24
完:
jmp端

很明显,DDRB和PORTB在汇编文件中的解析方式不同,因此您可能使用了错误的io.h版本,这些版本可能是定义的?我刚刚在汇编程序源文件的开头添加了#define u SFR _offset0x00。在asm转储中,它现在显示出
out((0x04)+0x00)、r24
out((0x05)+0x00)、r24
,并且工作正常。
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
#  if __AVR_ARCH__ >= 100
#    define __SFR_OFFSET 0x00
#  else
#    define __SFR_OFFSET 0x20
#  endif
#endif