Is there a difference between using the r1 register or the data address 0x1?

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ATmega328P datasheet says:

each register is also assigned a data memory address, mapping them directly into the first 32 locations of the user data space.

Which suggests I can either use `r1` in my assembly file or load/store to data address `0x1`? They both accomplish the same thing?

If every instruction is also executed in 1 clock cycle then does it even make a difference in performance?

This topic has a solution.
Last Edited: Tue. Mar 1, 2022 - 02:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The r00-r31 registers are computation registers and must be accessed as such for opcodes,  but also have the lowest addresses, other registers like PORTC, DDRA, are accessible (take a good look at the memory map listing in section 36).

Why would you access r00-r31 other than using opcodes? Perhaps to copy a block of them elsewhere?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Feb 28, 2022 - 08:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:

I don't believe so ---the r00-r31 registers are computation registers and must be accessed as such, other registers like PORTC, DDRA, are accessible (take a good look at the memory map) listing in section 36

My original quote is actually talking about cpu gp registers, not i/o registers like DDR.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

My original quote is actually talking about cpu gp registers, not i/o registers like DDR.

I saw I misread your original & was trying a cut/paste update.  You can read the r00-r31 using other means, though the need would be low (opcodes usually direct & most efficient).

The memory map listing in section 36 gives a good guide.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Feb 28, 2022 - 08:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
If every instruction is also executed in 1 clock cycle t

Well that's a bit misguided:

Show us how you would increment R1 using only it's SRAM location in just one clock cycle.

 

NB: The ASM would be: INC R1

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On "traditional" AVRs, you can access the CPU registers (R0-R31) as memory locations 0-31.  This goes away in the xMega architecture CPUs (including AVR-Dx and xTiny)

 

Since the only operations that work on "memory" are essentially "load" and "store", this is not a particularly useful observation.

"LDS R1, R2" is twice as many cycles and twice as many bytes as "MOV R1, R2"
It had some very limited application in the very old AVRs that didn't have any RAM - you could use Z as an index register for very small arrays, or similar.

IIRC, there's also some clever "clear all registers" code involving X, for the small set of people who think there is a good reason to clear all the registers.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:
"LDS R1, R2" is twice as many cycles and twice as many bytes as "MOV R1, R2"

Why is that? aren't LDS and MOV both 1 clock?

 

Are you referring to the fact that we first have to store R2 in memory if using LDS?

Last Edited: Mon. Feb 28, 2022 - 11:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Check the datasheet (there may be slight opcode timing variations depending on the chip core)

Of course, some datasheets also get copied/pasted with wrong info, or not updated...so it is a bit of a dice game

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah I see so it's not always 1 clock, thanks for the image.

Last Edited: Mon. Feb 28, 2022 - 11:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:
It had some very limited application in the very old AVRs that didn't have any RAM - you could use Z as an index register for very small arrays, or similar.

Still of perhaps limited application, but consider that the mechanism allows you to pass a parameter by address, even if a C "register" variable.  Probably I'm a bit more into that being a CodevisionAVR user where that can be explicit. 

 

We'll have to ask the ASM gurus if/how it has been seen.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The main reason for using the memory addr. of the registers is when you want to move multiple registers in or out of RAM (flash). That make much smaller (and cleaner) code by using pointers.

You can make a general mem copy function.

On newer AVR's you don't have that option, if you want to get something into R14 you need to use a instruction that is dedicated for R14, so the same code can't load R12 up if you just change a pointer

I guess you can live with it on xmegas that have plenty of flash, but it is really stupid that the newer small chips don't have it.

Most of my ASM code use it so I can't just use the never chips.