passing 16-bit parameters to Atmel Macroassembler

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

I saw some old posts on this topic but no resolution.

Some people said that you can't pass 16-bit parameters to a Macro.

But you certainly can. Here are some examples that work:

 


; LOAD Z-REGISTER IMMEDIATE
.MACRO LDZI   
LDI R30, LOW(@0)
LDI R31, HIGH(@0)
.ENDMACRO
LDZI ARRAY_START_ADDRESS ;  ARRAY_START_ADDRESS IS AN ARRAY DECLARED IN DSEG. THIS WORKS FINE
.EQU PHOTOCELL_QUIESCENT_VOLTAGE=1019

LDZI PHOTOCELL_QUIESCENT_VOLTAGE        ; NOW WE ARE GETTING IT TO ACCEPT 16-BIT CONSTANTS DECLARED WITH AN .EQU AND IT WORKS FINE

So when the code in the .MACRO is LDI it seems to work fine with either 16-bit addresses passed as a parameter or 16-bit constants declared by an .EQU

It also allows you to pass the address of a label in your code, for example

 

 RESUME1: ....SOME ASM CODE....
 
 LDZI RESUME1
 
 
 PUSHZ_BIGENDIAN
 

I use the above to push a return address on the stack when I want a subroutine call to return to different places

depending on the outcome of a calculation, and it works fine.

So it seems we can pass 16-bit constants, RAM variable addresses or code labels fine.

 

But this does not work:

 

.MACRO SUBTRACT16
SBI R22,LOW(@0)
SBCI R23,HIGH(@0)
.ENDMACRO
.EQU PHOTOCELL_QUIESCENT_VOLTAGE=1017
SUBTRACT16 PHOTOCELL_QUIESECENT_VOLTAGE

But this does work:

 

.MACRO SUBTRACT16
LDI R30,LOW(@0)
LDI R31,HIGH(@0)
SUB R22,R30
SBC R23,R31
.ENDMACRO

 

 

so my question is: Why does it work when the  .MACRO receiving the parameter is just doing an LDI with it

and does not work if it is using the passed parameter as an immediate with some other instruction that would normally

happily accept such immediate constants outside of the .MACRO?

 

What are the rules and where can I find them written down?

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

The only documentation is the user manual, it isn't very detailed. 

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

CANCEL CANCEL!

 

I found the answer to my own question.

 

Further experiments show that you CAN pass 16-bit parameters to all instructions that normally accept immediate constants.

 

The problem with my code above that did not work is that there is no "subtract immediate" instruction in the ATMEGA.

SBI means "SET BIT IN IO REGISTER" !

 

You have to use two instances of SBCI, with carry clear for the first one, to do a 16-bit subtract.

 

Now it seems that you can pass 16-bit parameters to .MACROs in all circumstances!

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

Yet another revision of the above:

 

There IS indeed a "Subtract Immediate" (with no carry instruction on the ATMEGA)

 

It's somewhat further down the list.

 

Some mnemonics are so similar it was confusing me. Here they are:

 

SBI    = set bit in I/O register

SBIC  = Skip if bit in IO register is cleared

SBCI = subtract immediate with carry

SUBI = subtract immediate

SUB  = subtract two registers

SBC = subtract two registers with carry

 

I guess I need some more caffeine

 

Last Edited: Sat. Aug 19, 2017 - 08:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There seem to be some issues with macros that work in "normal" AVRs but no longer work with Xmegas or newer AVRs, I started a test USART project about a week ago for someone here but the macros failed.

 

Since I no longer care I haven't investigated further. surprise Maybe one day I will.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly