I'm trying to write a program in assembly to toggle the on-board LED of the Arduino MEGA2560 in assembly.
To do so I just have to indicate the direction of the pin (13 in this case which is PB7) as output and then set that pin as High or Low.
I understand that there are two registers related with this problem. one is the port's direction register (DDRB) and the register for the state of the pins (PORTB)
So I'm trying to understand what number or address those register have so I can assign values to them in assembly. I went into the C++ library in which those constants are defined (iomxx0.h) and for example DDRB is defined the following way:
#define DDRB _SFR_IO8(0x04)
#define DDB7 7
#define DDB6 6
#define DDB5 5
#define DDB4 4
#define DDB3 3
#define DDB2 2
#define DDB1 1
#define DDB0 0
I'm curious about knowing if the register's address is 0x04? and if that is the case, what is _SFR_IO8() doing?
That's a macro. You can find its definition in the headers if you are curious:
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
and
#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
Furthermore,
#define _SFR_IO_ADDR(sfr) ((sfr) - __SFR_OFFSET)
#define _SFR_MEM_ADDR(sfr) (sfr)
On AVR you can access SFRs either with the usual memory read/write or with in/out instructions. However, the addresses depend on the access method. These macros exist to help you with that. In your case 0x04 is the IO address and 0x24 is the memory mapped address.