I've an ATmega328P.
Register Summary Page 275 ATmega328P datasheet.
The first address is the I/O address, and the second is the data memory address.
I'm going to set all (D ports) Data Direction Registers To 1 and all (D ports) Port Registers to 1.
Using I/O addresses
int main(void)
{
asm("ldi 16,0xff"); //load 0xFF to the general purpose register 16
asm("out 0x0A,16"); //load register 16 data to PORTD
asm("ldi 16,0xFF"); //load 0xFF to the general purpose register 16
asm("out 0x0B,16"); //load register 16 data to PORTD
}
Next I'm going to set all (D ports) Data Direction Registers To 1 and half of (D ports) Port Registers to 1
Using memory addresses:
volatile unsigned char* DDRD = (unsigned char*)(0x2A);
volatile unsigned char* PORTD = (unsigned char*)(0x2B);
int main()
{
DDRD = 0xff;
PORTD = 0X0f;
}
The code is compiled to:
main:
lds r30, 0x102 #r30 = *(0x102) = 0x2A
lds r31, 0x103 #r31 = *(0x103) = 0x00
ser r24 #r24 = 0xff
st Z, r24 #*(0x002A) = r24 = 0xff DDRD Memory Address Is 0x2A
lds r30, 0x100 #r30 = *(0x102) = 0x2B
lds r31, 0x101 #r31 = *(0x102) = 0x00
ldi r24, 0xF #r24 = 0x0f
st Z, r24 #*(0x002B) = r24 = 0xff PORTD Memory Address Is 0x2B
ldi r24, 0
ldi r25, 0
ret
; End of function main
They both work properly. Why did they build the CPU to have instructions to deal with ports I/O addresses (like in, out instructions) while they already built a set of instructions that deal with memory space (like: lds, sts, ld, st?) Why are there still instructions like in and out? Why ddin't they just get rid of them as they are useless after they mapped the I/O ports in memory