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?
out ((0x04) + 0x00), r24andout ((0x05) + 0x00), r24and it works.