\hypertarget{assembler_ass_intro}{}\doxysubsection{Introduction}\label{assembler_ass_intro}
There might be several reasons to write code for A\+VR microcontrollers using plain assembler source code. Among them are\+:


\begin{DoxyItemize}
\item Code for devices that do not have R\+AM and are thus not supported by the C compiler.
\item Code for very time-\/critical applications.
\item Special tweaks that cannot be done in C.
\end{DoxyItemize}

Usually, all but the first could probably be done easily using the \mbox{\hyperlink{inline_asm}{inline assembler}} facility of the compiler.

Although avr-\/libc is primarily targeted to support programming A\+VR microcontrollers using the C (and C++) language, there\textquotesingle{}s limited support for direct assembler usage as well. The benefits of it are\+:


\begin{DoxyItemize}
\item Use of the C preprocessor and thus the ability to use the same symbolic constants that are available to C programs, as well as a flexible macro concept that can use any valid C identifier as a macro (whereas the assembler\textquotesingle{}s macro concept is basically targeted to use a macro in place of an assembler instruction).
\item Use of the runtime framework like automatically assigning interrupt vectors. For devices that have R\+AM, \mbox{\hyperlink{mem_sections_sec_dot_init}{initializing the R\+AM variables}} can also be utilized.
\end{DoxyItemize}\hypertarget{assembler_ass_tools}{}\doxysubsection{Invoking the compiler}\label{assembler_ass_tools}
For the purpose described in this document, the assembler and linker are usually not invoked manually, but rather using the C compiler frontend ({\ttfamily avr-\/gcc}) that in turn will call the assembler and linker as required.

This approach has the following advantages\+:


\begin{DoxyItemize}
\item There is basically only one program to be called directly, {\ttfamily avr-\/gcc}, regardless of the actual source language used.
\item The invokation of the C preprocessor will be automatic, and will include the appropriate options to locate required include files in the filesystem.
\item The invokation of the linker will be automatic, and will include the appropriate options to locate additional libraries as well as the application start-\/up code ({\ttfamily crt}{\itshape X\+XX}{\ttfamily .o}) and linker script.
\end{DoxyItemize}

Note that the invokation of the C preprocessor will be automatic when the filename provided for the assembler file ends in {\ttfamily }.S (the capital letter \char`\"{}s\char`\"{}). This would even apply to operating systems that use case-\/insensitive filesystems since the actual decision is made based on the case of the filename suffix given on the command-\/line, not based on the actual filename from the file system.

As an alternative to using {\ttfamily }.S, the suffix {\ttfamily }.sx is recognized for this purpose (starting with G\+CC 4.\+3.\+0). This is primarily meant to be compatible with other compiler environments that have been providing this variant before in order to cope with operating systems where filenames are case-\/insensitive (and, with some versions of {\ttfamily make} that could not distinguish between {\ttfamily }.s and {\ttfamily }.S on such systems).

Alternatively, the language can explicitly be specified using the {\ttfamily -\/x assembler-\/with-\/cpp} option.\hypertarget{assembler_ass_example}{}\doxysubsection{Example program}\label{assembler_ass_example}
The following annotated example features a simple 100 k\+Hz square wave generator using an A\+T90\+S1200 clocked with a 10.\+7 M\+Hz crystal. Pin P\+D6 will be used for the square wave output.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <\mbox{\hyperlink{io_8h}{avr/io.h}}>}     ; Note [1]}
\DoxyCodeLine{}
\DoxyCodeLine{work    =   16      ; Note [2]}
\DoxyCodeLine{tmp =   17}
\DoxyCodeLine{}
\DoxyCodeLine{inttmp  =   19}
\DoxyCodeLine{}
\DoxyCodeLine{intsav  =   0}
\DoxyCodeLine{}
\DoxyCodeLine{SQUARE  =   PD6     ; Note [3]}
\DoxyCodeLine{}
\DoxyCodeLine{                ; Note [4]:}
\DoxyCodeLine{tmconst= 10700000 / 200000  ; 100 kHz => 200000 edges/s}
\DoxyCodeLine{fuzz=   8           ; \# clocks in \mbox{\hyperlink{group__avr__interrupts_gad28590624d422cdf30d626e0a506255f}{ISR}} until TCNT0 is set}
\DoxyCodeLine{}
\DoxyCodeLine{    .section .text}
\DoxyCodeLine{}
\DoxyCodeLine{    .global main                ; Note [5]}
\DoxyCodeLine{main:}
\DoxyCodeLine{    rcall   ioinit}
\DoxyCodeLine{1:}
\DoxyCodeLine{    rjmp    1b              ; Note [6]}
\DoxyCodeLine{}
\DoxyCodeLine{    .global TIMER0\_OVF\_vect         ; Note [7]}
\DoxyCodeLine{TIMER0\_OVF\_vect:}
\DoxyCodeLine{    ldi inttmp, 256 -\/ tmconst + fuzz}
\DoxyCodeLine{    out \_SFR\_IO\_ADDR(TCNT0), inttmp ; Note [8]}
\DoxyCodeLine{}
\DoxyCodeLine{    in  intsav, \_SFR\_IO\_ADDR(SREG)  ; Note [9]}
\DoxyCodeLine{}
\DoxyCodeLine{    sbic    \_SFR\_IO\_ADDR(PORTD), SQUARE}
\DoxyCodeLine{    rjmp    1f}
\DoxyCodeLine{    \mbox{\hyperlink{group__deprecated__items_ga014ef751e83f97569c06f3cdd888f3f7}{sbi}}  \_SFR\_IO\_ADDR(PORTD), SQUARE}
\DoxyCodeLine{    rjmp    2f}
\DoxyCodeLine{1:  \mbox{\hyperlink{group__deprecated__items_ga08ee265dc07048dbb5a8b6c84551d520}{cbi}}  \_SFR\_IO\_ADDR(PORTD), SQUARE}
\DoxyCodeLine{2:}
\DoxyCodeLine{}
\DoxyCodeLine{    out \_SFR\_IO\_ADDR(SREG), intsav}
\DoxyCodeLine{    \mbox{\hyperlink{group__avr__interrupts_ga3b991e8168db8fc866e31f9a6d10533b}{reti}}}
\DoxyCodeLine{}
\DoxyCodeLine{ioinit:}
\DoxyCodeLine{    \mbox{\hyperlink{group__deprecated__items_ga014ef751e83f97569c06f3cdd888f3f7}{sbi}}  \_SFR\_IO\_ADDR(DDRD), SQUARE}
\DoxyCodeLine{}
\DoxyCodeLine{    ldi work, \mbox{\hyperlink{group__avr__sfr_ga11643f271076024c395a93800b3d9546}{\_BV}}(TOIE0)}
\DoxyCodeLine{    out \_SFR\_IO\_ADDR(TIMSK), work}
\DoxyCodeLine{}
\DoxyCodeLine{    ldi work, \mbox{\hyperlink{group__avr__sfr_ga11643f271076024c395a93800b3d9546}{\_BV}}(CS00)      ; tmr0:  CK/1}
\DoxyCodeLine{    out \_SFR\_IO\_ADDR(TCCR0), work}
\DoxyCodeLine{}
\DoxyCodeLine{    ldi work, 256 -\/ tmconst}
\DoxyCodeLine{    out \_SFR\_IO\_ADDR(TCNT0), work}
\DoxyCodeLine{}
\DoxyCodeLine{    \mbox{\hyperlink{group__avr__interrupts_gaad5ebd34cb344c26ac87594f79b06b73}{sei}}}
\DoxyCodeLine{}
\DoxyCodeLine{    ret}
\DoxyCodeLine{}
\DoxyCodeLine{    .global \_\_vector\_default        ; Note [10]}
\DoxyCodeLine{\_\_vector\_default:}
\DoxyCodeLine{    \mbox{\hyperlink{group__avr__interrupts_ga3b991e8168db8fc866e31f9a6d10533b}{reti}}}
\DoxyCodeLine{}
\DoxyCodeLine{    .end}
\end{DoxyCode}


\begin{DoxyParagraph}{Note \mbox{[}1\mbox{]}}

\end{DoxyParagraph}
As in C programs, this includes the central processor-\/specific file containing the IO port definitions for the device. Note that not all include files can be included into assembler sources.

\begin{DoxyParagraph}{Note \mbox{[}2\mbox{]}}

\end{DoxyParagraph}
Assignment of registers to symbolic names used locally. Another option would be to use a C preprocessor macro instead\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#define work 16 }}
\end{DoxyCode}


\begin{DoxyParagraph}{Note \mbox{[}3\mbox{]}}

\end{DoxyParagraph}
Our bit number for the square wave output. Note that the right-\/hand side consists of a C\+PP macro which will be substituted by its value (6 in this case) before actually being passed to the assembler.

\begin{DoxyParagraph}{Note \mbox{[}4\mbox{]}}

\end{DoxyParagraph}
The assembler uses integer operations in the host-\/defined integer size (32 bits or longer) when evaluating expressions. This is in contrast to the C compiler that uses the C type {\ttfamily int} by default in order to calculate constant integer expressions. ~\newline
 In order to get a 100 k\+Hz output, we need to toggle the P\+D6 line 200000 times per second. Since we use timer 0 without any prescaling options in order to get the desired frequency and accuracy, we already run into serious timing considerations\+: while accepting and processing the timer overflow interrupt, the timer already continues to count. When pre-\/loading the {\ttfamily T\+C\+C\+N\+T0} register, we therefore have to account for the number of clock cycles required for interrupt acknowledge and for the instructions to reload {\ttfamily T\+C\+C\+N\+T0} (4 clock cycles for interrupt acknowledge, 2 cycles for the jump from the interrupt vector, 2 cycles for the 2 instructions that reload {\ttfamily T\+C\+C\+N\+T0}). This is what the constant {\ttfamily fuzz} is for.

\begin{DoxyParagraph}{Note \mbox{[}5\mbox{]}}

\end{DoxyParagraph}
External functions need to be declared to be {\ttfamily }.global. {\ttfamily main} is the application entry point that will be jumped to from the ininitalization routine in {\ttfamily crts1200.\+o}.

\begin{DoxyParagraph}{Note \mbox{[}6\mbox{]}}

\end{DoxyParagraph}
The main loop is just a single jump back to itself. Square wave generation itself is completely handled by the timer 0 overflow interrupt service. A {\ttfamily sleep} instruction (using idle mode) could be used as well, but probably would not conserve much energy anyway since the interrupt service is executed quite frequently.

\begin{DoxyParagraph}{Note \mbox{[}7\mbox{]}}

\end{DoxyParagraph}
Interrupt functions can get the \mbox{\hyperlink{group__avr__interrupts_avr_signames}{usual names}} that are also available to C programs. The linker will then put them into the appropriate interrupt vector slots. Note that they must be declared {\ttfamily }.global in order to be acceptable for this purpose. This will only work if {\ttfamily $<$\mbox{\hyperlink{io_8h}{avr/io.\+h}}$>$} has been included. Note that the assembler or linker have no chance to check the correct spelling of an interrupt function, so it should be double-\/checked. (When analyzing the resulting object file using {\ttfamily avr-\/objdump} or {\ttfamily avr-\/nm}, a name like {\ttfamily \+\_\+\+\_\+vector\+\_\+{\itshape N}} should appear, with {\itshape N} being a small integer number.)

\begin{DoxyParagraph}{Note \mbox{[}8\mbox{]}}

\end{DoxyParagraph}
As explained in the section about \mbox{\hyperlink{group__avr__sfr__notes}{special function registers}}, the actual IO port address should be obtained using the macro {\ttfamily \+\_\+\+S\+F\+R\+\_\+\+I\+O\+\_\+\+A\+D\+DR}. (The A\+T90\+S1200 does not have R\+AM thus the memory-\/mapped approach to access the IO registers is not available. It would be slower than using {\ttfamily in} / {\ttfamily out} instructions anyway.) ~\newline
 Since the operation to reload {\ttfamily T\+C\+C\+N\+T0} is time-\/critical, it is even performed before saving {\ttfamily S\+R\+EG}. Obviously, this requires that the instructions involved would not change any of the flag bits in {\ttfamily S\+R\+EG}.

\label{assembler_ass_isr}%
\Hypertarget{assembler_ass_isr}%
\begin{DoxyParagraph}{Note \mbox{[}9\mbox{]}}

\end{DoxyParagraph}
Interrupt routines must not clobber the global C\+PU state. Thus, it is usually necessary to save at least the state of the flag bits in {\ttfamily S\+R\+EG}. (Note that this serves as an example here only since actually, all the following instructions would not modify {\ttfamily S\+R\+EG} either, but that\textquotesingle{}s not commonly the case.) ~\newline
 Also, it must be made sure that registers used inside the interrupt routine do not conflict with those used outside. In the case of a R\+A\+M-\/less device like the A\+T90\+S1200, this can only be done by agreeing on a set of registers to be used exclusively inside the interrupt routine; there would not be any other chance to \char`\"{}save\char`\"{} a register anywhere. ~\newline
 If the interrupt routine is to be linked together with C modules, care must be taken to follow the \mbox{\hyperlink{FAQ_faq_reg_usage}{register usage guidelines}} imposed by the C compiler. Also, any register modified inside the interrupt sevice needs to be saved, usually on the stack.

\begin{DoxyParagraph}{Note \mbox{[}10\mbox{]}}

\end{DoxyParagraph}
As explained in \mbox{\hyperlink{group__avr__interrupts}{Interrupts}}, a global \char`\"{}catch-\/all\char`\"{} interrupt handler that gets all unassigned interrupt vectors can be installed using the name {\ttfamily \+\_\+\+\_\+vector\+\_\+default}. This must be {\ttfamily }.global, and obviously, should end in a {\ttfamily reti} instruction. (By default, a jump to location 0 would be implied instead.)\hypertarget{assembler_ass_pseudoops}{}\doxysubsection{Pseudo-\/ops and operators}\label{assembler_ass_pseudoops}
The available pseudo-\/ops in the assembler are described in the G\+NU assembler (gas) manual. The manual can be found online as part of the current binutils release under \href{http://sources.redhat.com/binutils/}{\texttt{ http\+://sources.\+redhat.\+com/binutils/}}.

As gas comes from a Unix origin, its pseudo-\/op and overall assembler syntax is slightly different than the one being used by other assemblers. Numeric constants follow the C notation (prefix {\ttfamily 0x} for hexadecimal constants), expressions use a C-\/like syntax.

Some common pseudo-\/ops include\+:


\begin{DoxyItemize}
\item {\ttfamily }.byte allocates single byte constants
\item {\ttfamily }.ascii allocates a non-\/terminated string of characters
\item {\ttfamily }.asciz allocates a \textbackslash{}0-\/terminated string of characters (C string)
\item {\ttfamily }.data switches to the .data section (initialized R\+AM variables)
\item {\ttfamily }.text switches to the .text section (code and R\+OM constants)
\item {\ttfamily }.set declares a symbol as a constant expression (identical to {\ttfamily }.equ)
\item {\ttfamily }.global (or {\ttfamily }.globl) declares a public symbol that is visible to the linker (e. g. function entry point, global variable)
\item {\ttfamily }.extern declares a symbol to be externally defined; this is effectively a comment only, as gas treats all undefined symbols it encounters as globally undefined anyway
\end{DoxyItemize}

Note that {\ttfamily }.org is available in gas as well, but is a fairly pointless pseudo-\/op in an assembler environment that uses relocatable object files, as it is the linker that determines the final position of some object in R\+OM or R\+AM.

Along with the architecture-\/independent standard operators, there are some A\+V\+R-\/specific operators available which are unfortunately not yet described in the official documentation. The most notable operators are\+:


\begin{DoxyItemize}
\item {\ttfamily lo8} Takes the least significant 8 bits of a 16-\/bit integer
\item {\ttfamily hi8} Takes the most significant 8 bits of a 16-\/bit integer
\item {\ttfamily pm} Takes a program-\/memory (R\+OM) address, and converts it into a R\+AM address. This implies a division by 2 as the A\+VR handles R\+OM addresses as 16-\/bit words (e.\+g. in an {\ttfamily I\+J\+MP} or {\ttfamily I\+C\+A\+LL} instruction), and can also handle relocatable symbols on the right-\/hand side.
\end{DoxyItemize}

Example\+: \begin{DoxyVerb}	ldi	r24, lo8(pm(somefunc))
	ldi	r25, hi8(pm(somefunc))
	call	something
\end{DoxyVerb}


This passes the address of function {\ttfamily somefunc} as the first parameter to function {\ttfamily something}. 