Directly assignng a variable name to a specific (GPR/GPIO) register

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

Coming from an assembly language (and still preferring it) background, I liked AVR for the 32 GPR and the 3 GPIO registers.  I know which volatile variables are the backbone of my operation and which (if any) will need to be sent to SRAM, but Studio 6 likes throwing most everything into SRAM.  How do I fill R2 through 17 (non-crushable) and GPIO0 through 2 ?

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

I'm not sure I understand. Do you mean something like this?

#define	scroll_n_bits r10		;
#define	old_switch_status r9	;
#define	rownum	r8				;Row number
#define	reform_cntr	r7			;Reform counter
#define	a_reg r6				;Fake A reg
#define	b_reg r5				;Fake B reg
#define	c_reg r4				;Fake C reg
#define	time_scaler	r3			;Scaler for 100mS timer ticks
#define	hundreds r2				;Hundreds for HTOD8 and DTOH8
#define	tens r1					;Tens for HTOD8 and DTOH8
#define	units r0				;Units for HTOD8, DTOH8 and LPM instructionjavascript:void(0)

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

When you use a High-Level Language (such as 'C') you delegate this stuff to the compiler - so you should not try to interfere with it yourself...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

but Studio 6 likes throwing most everything into SRAM.  How do I fill R2 through 17 (non-crushable) and GPIO0 through 2 ?

Technically, "Studio 6" isn't a compiler.

 

>>You<< need to choose a toolchain acceptable to >>you<<.  If you want an AVR toolchain that allows low registers to be allocated to register variables, then choose CodeVision.

 

That said, GCC does a darned good job of code generation for the price.  While giving up full control may rankle in the beginning, overall the application should be competitive in size/space to more "crafted" implementations.

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

It is possible to do this in avr-gcc, however there is no guarantee that some other module will not use that same register for its own purposes. If that happens, your value will be clobbered mercilessly. As the others have said, let the compiler do the work.

Regards,
Steve A.

The Board helps those that help themselves.

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

It is possible to do this in avr-gcc,

The command line option is -ffixed-N where N is 0..31

 

That tells the compiler not to use that register during its own code generation. You can then later:

int foo asm("r16");

int main(void) {
    
}

And that assigns the global variable "foo" to r16/r17 (I'm assuming you built with -ffixed-16 -ffixed-17).

 

However suppose your C code calls a library function like strcpy() or printf() or whatever. How do you know whether they may not already be using R16/R17? The fact is that the code of all such functions comes to you prebuilt (it's all in libc.a) and when the compiler author built that for you he didn't use -ffixed-16 etc. so the compiler might just happen to have used r16 and r17 in there. So you might store something to "foo" then call printf() then find that "foo" no longer holds what you put there.

 

You can inspect assembly listings of the entire code and look for instances of R16/R17 being used in library code but really. As Andy says:

When you use a High-Level Language (such as 'C') you delegate this stuff to the compiler - so you should not try to interfere with it yourself...

A good C compiler will recognize what the heavily accessed things are and will attempt to keep values cached in its own collection of registers anyway. In fact if you start reserving registers like R16/R17 you "cramp its style" and while "foo" might be a fast access it could be at the expense of swathes of other code now operating less efficiently.

 

You just have to learn to trust the C compiler. If you are seeing it storing a lot of stuff in RAM that ought to be cached to registers you probably haven't got the Optimization setting correct!