Hi StackOverflow community,
I am trying to program my old Arduino Duemilanove Board (Atmega 168V-10PU) in Assembler. I tried it a few times before but everytime the code was not executed. So i tried to program an equivalent test program in C, and it worked. Here it is:
// file led.c
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
while (1) {
asm("nop\n");
}
return 0;
}
The asm dump of the compiler results in (shortened),
ldi r24,lo8(-1) ; tmp44,
out 0x4,r24 ; MEM[(volatile uint8_t *)36B], tmp44
out 0x5,r24 ; MEM[(volatile uint8_t *)37B], tmp44
which works and activates the LED at Arduino Pin 13 (AVR pin PB5).
But when I use this asm file,
// file led.S
#include "avr/io.h"
.global main
main:
ldi r24, 0xFF
out DDRB, r24
out PORTB, r24
end:
jmp end
the compiler dump results in (shortened),
ldi r24, 0xFF
out ((0x04) + 0x20), r24
out ((0x05) + 0x20), r24
what might explain why nothing happens.
In addition here are the makefiles for the C version and the Assembler version
Thanks for helping!
EDIT: Here are also the full assembler dump files of the C version and the Assembler version
EDIT 2: I looked up the register addresses in the include file iom168.h, which references to iomx8.h, where it says #define PORTB _SFR_IO8 (0x05)
. The compiler follows the include chain
io.h -> iom168.h -> iomx8.h
io.h -> common.h -> sfr_defs.h
In sfr_defs.h is written:
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
A few more lines upwards the offset is defined:
#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
(Sorry for the formatting)
Any idea where this error comes from?