The AVR has several different "address spaces" that are accessible by different instructions.
The math, logic, and mov instructions use 0 to 31 to access the CPU "general purpose registers." These instructions can use "r0" to "r31" as names to address the registers, which makes your program a lot clearer.
There are also IO registers SEPARATE from the CPU registers, numbered from 0 to 63. These can be access by the IN and OUT instructions, and the first 32 can be accessed by some special purpose IO instructions like SBI and CBI.
There is an EEPROM address space, 0 to EEPROMsize, accessed via a peripheral.
There is a FLASH Memory address space, 0 to FLASHsize, accessible by the LPM instruction, and by the instruction decoder.)
Finally, there is a "Data" address space that goes from 0 to RAMEND that includes the CPU registers (at 0 to 31), the IO registers (IOREG 0 at 32, IOREG 63 at 95, and RAM at addresses 64 to 127 (on a tiny13. The transition points change for different chips. Some newer chips are "different.") The whole "data" address space can be accessed by the LD and ST instruction family, but they take two cycles and some are two instruction words long.
So...
mov 18,7 ; move CPU register 7 to CPU register 18
out 18,7 ; output CPU register 7 to IO register 18
sbi 18,7 ; set bit 7 of IO register 18
subi 18,7 ; subtract the value 7 from cpu register 18
lds 18,7 ; move data memory 7 (aka cpu reg 7) to cpu register 18 (takes 2 cycles and 2 words.)
A bit confusing - which is why you really SHOULD use the symbolic names:
mov r18,r7 ; move CPU register 7 to CPU register 18
out PORTB,r7 ; output CPU register 7 to portb
sbi PORTB,PB7 ; set bit 7 of portb
subi r18,7 ; subtract the value 7 from cpu register 18
lds r18,mydata ; load ram location mydata into cpu reg 18
There are also a bunch of illegal combinations:
mov 18,mydata ; mov only does CPU reg to CPU reg.
out 100,7 ; IO Register 100 is too big.
sbi TIMSK0,7 ; TIMSK0 is an IOREG, but out-of-range for SBI.
I drew this at one point. It might help.
