3
\$\begingroup\$

Let's say I need to test a port pin like this:

sbic  PIND,2

This should work, but in C I would definitely made a #define INPUT ((PORTD&(1<<2))!=0). Is something similar possible in assembler? Something like

.def  INPUT = PIND,2   ; this is not work!

Sorry for the stupid question. Just started to assembler after years of C-coding...

\$\endgroup\$
  • \$\begingroup\$ Macros. \$\endgroup\$ – Ignacio Vazquez-Abrams Feb 26 '16 at 19:10
  • \$\begingroup\$ Can you not just use a #define? e.g. #define INPUT PIND,2, then sbic INPUT. \$\endgroup\$ – Tom Carpenter Feb 26 '16 at 19:11
  • \$\begingroup\$ Or possibly .equ? \$\endgroup\$ – Tom Carpenter Feb 26 '16 at 19:14
  • 1
    \$\begingroup\$ Most people work in C, dropping to inline assembly when required. It's not all that common to work in pure assembly with modern microcontrollers. \$\endgroup\$ – Ignacio Vazquez-Abrams Feb 26 '16 at 19:25
  • 1
    \$\begingroup\$ Given that assembler isn't going to be portable anyway, I see no reason not to use #defines. \$\endgroup\$ – Tom Carpenter Feb 26 '16 at 19:28
1
\$\begingroup\$

You have three options.

1. Using #defines

AVR Studio passes the code through the AVR ASM Preprocessor. This does similar things to the C/C++ Preprocessor, but works on assembly. Given you are writing in pure assembly, the code is not going to be portable, so you might as well leverage the capabilities of AVR Studio (and in fact anything using AVR libc). You can simply use a define like in C:

#define SOMEPIN PINC,2

sbic SOMEPIN;

You could even go for something more advanced to deal with being able to use input, output, and direction registers. Something along the lines of:

#define CONCAT(a,b,c) a##b##,##c ; Helper for concatenation
#define SOMEPIN(p) CONCAT(p,C,2) ; Define as xC,2

sbic SOMEPIN(PIN)  ; Expands to 'sbic PINC,2', and then to 'sbic 0x##,2'
sbi  SOMEPIN(DDR)  ; Expands to 'sbi  DDRC,2'

Some may say that is abusing the pre-processor, but if it helps you understand the code better, so be it.

2. Just the Bit

This one is possibly easier in that it doesn't require the pre-processor. Rather than defining the entire command, just define the bit you want, but also include what port you are interested in the name. For example:

.equ SOMEPIN_D = 2;

sbic PIND, SOMEPIN_D;

That way if you know the name of the pin (SOMEPIN_D), you can easily remember which port/pin/ddr register it belongs to as it is part of the name.

3. Macros

@Ignacio mentioned this in the comments. You may be able to use macros to do what you want, though it has been several years since I wrote anything in pure assembler, so I can't immediately say how.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ This as much more than I expected :) Thank you very much for such detailed answer! \$\endgroup\$ – Roman Matveev Feb 26 '16 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.