Help in Assembly Language

I am playing with some assembly language in the Arduino environment and are looking to do the same in the Arduboy environment.

I am making progress with the actual code itself on a ‘bare-bones’ Arduino but struggling to understand how I move this to the Arduboy environment. Obviously I can use the asm volatile command and code away but how do I know what registers are being used at the point in time so I do not overwrite values that may still be needed?

I can see in the Arduboy2 docs that R28 and R29 are being used in the draw…() functions. How were these determined to be free? I assume that I can use them too but what if I need more?

Hi @filmote, if you haven’t seen it yet this information about the calling convention may be useful: https://gcc.gnu.org/wiki/avr-gcc See the section on Register Layout in particular.

I recommend to read this

https://www.nongnu.org/avr-libc/user-manual/inline_asm.html

Nice … this explains it well. Its interesting that in the drawBitmap ‘Sprite_Plus_Mask’ uses R28 and R29 which must be restored to their original values when they could have used R30 and R31. I wonder why? A little more digging and I might understand it.

This looks really useful as I am looking at how to inline some functions.

Actually, all 3 pointer registers, X (r27:r26), Y (r29:r28) and Z (r31:r30) are being used. X and Z are declared as output operands.

I didn’t write the code (I only cleaned it up a bit) but I assume trying to also declare the usage of Y caused problems with running out of registers, so instead it is preserved by pushing and popping. I can’t say for certain but it may be that Y could have been declared and either X or Z saved instead.

Just a suggestion:
It’s helpful that whenever you mix in assembly, that you also include the functionally equivalent code for the high level language (C++) you are using, as commented out code. This makes it easier to quickly port to a different processor instruction set. The person porting can then use the HLL source to get things going, and then re-code in assembly later if necessary.

The HLL source also sometimes helps document what the function does in a more readable way.

Thanks Scott

I am going to spend a little time pulling this code apart - not because I think I can do better but more that it is complex enough example that I think I will learn from it. I need to read up more on the use of registers overall.

This will probably be my approach anyway … write something in C++ before trying to optimise it with some assembly. I haven’t really got any specific uses in mind for the assembly. I am just interested as I haven’t done any since my 6502 days …

1 Like

The link suggested by @Mr.Blinky is one of my favourites.

I also recommend this for learning AVR opcodes:
https://www.microchip.com/webdoc/avrassembler/avrassembler.wb_instruction_list.html

And this for understanding GCC’s inline asm syntax:
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

Also I’ve got a feeling I might know why you want to learn assembly.
(Hopefully you’ll know what I mean if I say that I get the feeling you’ve hit a bump in the road.)

You’re welcome to look at the version I wrote for Pokitto’s port of the Arduboy2 library:


In fact, @MLXXXp, would you be interested in me adding this code as a comment to the original Arduboy2 library?
As you say, it might help future porters.

1 Like

I don’t mind. How close is it to the assembly, from a flow and variable naming point of view? (I haven’t yet examined or compared your code.)

However, if one were to port without the assembly optimisation, using the SpritesB class code might be a better option.

I’d say about 80-90% similar.
As far as I remember I kept all or most of the variable names the same to make it easier to create a near 1:1 relation.

1 Like

No … probably not directly for the game you are thinking but it may come in handy.

I see you what you did there!

2 Likes