 In this video, we're going to explain how to create AVR assembly programs. The initial ingredient is to write our code. Let's suppose we write our code in something called file1.s in a file that has to have a format which we call plain text. So you need a plain text editor to edit the file and include your code there. Typically, an assembly program will be written across several of these files. Let's say it's file1, but also file2.s, all of them with extension.s to denote that is assembly code, all the way to perhaps filen.s. So suppose you have written your code in a set of files like this one. Remember all of them with plain text. Typically, what you use, the type of tool you use to write these files is called an IDE or Integrated Development Environment which is the typical tool that allows you to edit, compile, and do some other operations over the program. The next step is to take all these files and process them all together by a tool which is called the assembler. Or an alternative name, generic, is the compiler. This program basically what it does is it reads each and every one of these files and performs a translation process. This translation, if everything is correct, then it will end up producing what we call an executable file. That despite the name executable, it still is not exactly ready to be executed by our AVR architecture. And as I said before, this is if everything goes correctly. However, if there is any sort of error detected in this translation and by error what I mean is something that was improperly written in any of these files then this compiler will return back to you with a message and typically what happens is that you need to go back to these files, find the error, and attempt the translation again. So invoke the assembler again. Typically, this assembler can be invoked either through something called the command line interface which is just a window in which we can type a bunch of commands or sometimes the IDE itself allows a very easy way to invoke this translation process typically by a menu option or a button. In this command line interface, typically what happens is that you provide options that instruct the assembler to perform the translation following certain specific values like, for example, you specify the type of CPU you want the code translated to or other a bit more obscure parameters like the memory management unit or what kind of output file you want, etc. So think of this assembler or translator as a very versatile program that can do lots of things and the way you specify which ones to do are through these options that are included in the command you type in the command line interface or CLI. Now, if the program has been translated correctly as I said before, it's not quite ready to be executable by the Arduino board. There are two additional steps. First, there needs to be another translation step but this one produces another file which is in binary format as well and it's also executable. This is just to perform a necessary translation from one executable format to the other. This one is closer to the board and can be almost immediately uploaded and at the same time run in the board. So, as you can see from the initial file to the Arduino board executing your program or the AVR chip executing your program, you still have a few steps. First, an initial state of translation in which we detect a few errors, then we produce an executable file. That executable file needs to be translated again to specific binary executable format and then finally we need another program which will push that executable program all the way to the board typically through the USB cable and as soon as the program is installed on the board it starts executing immediately. Now, let's take a look at the structure of a assembly program. Typically, an assembly program which again is created in this plain text file has two sections. The first section is denoted by a line that says .section.data. So, whenever the assembly, the assembler here perform the translation, find this line, we are instructing the assembler to take whatever comes next as data definition. So, what we're doing here is telling the assembler what kind of data are we going to be manipulating with our assembly program. Whenever the assembler finds the line saying .section.text, what we're saying is that the following text in this file will contain the code and typically what happens is we finish the file with one line that says .n. Now, all these three lines is what we call directives. The reason why we call them directives is because these lines are not specifically instructions that are going to be executed by the board here but instead instructions that are going to be interpreted by the assembler. The assembler is going to do different things whenever any of these three things are found. Now, let's look a little bit more into detail what do we mean by data. The data section is typically used to define the type of data structures that are going to be manipulated by the program. An example would be the following line. Let's say we say my msgcolon.s-a-s-c-i-z my first program .n. And here what we have is a line with three elements. The first one followed by the column is what we call a label. And a label is to identify and refer to the data that we are declaring here. Another way of looking at this the purpose of the data section is to define data that is going to eventually end up in memory. Well, this label will allow us to refer to the address where this data is eventually being stored. The second word we find here, it's a directive. And as in the case of these three directives over here, it doesn't translate into anything explicitly that is going to be executed by the microprocessor, instead it's a message telling the assembler that what it comes next is a string which is going to be defined using the ASCII code. And not only that, but it's going to have a zero stored at the end in memory. And finally, as you can see here we have the data. So another way of looking at this is that you have three elements. This label is telling you where is the data going to be stored. This directive is telling you how is the data going to be stored. In this case is going to be a string. And finally, what is it that we are storing? And eventually, as we said before, this data ends up in memory. Now, let's look at the code section which is the second section we have here. Remember, after the assembly, assembler detects this line over here. And typically the structure of this section is, first, some sort of label again, same structure of label we have here, we also have it here, denoting the start of the program. In principle, the start of the program, by convention, it's a label that we write with the name main, and typically is preceded by another directive that makes this symbol global. So this directive over here must be written before this label main. And the purpose of this directive is to make the symbol main accessible. In other words, so that from outside of this program, somebody can call this routine with name main. After this label, we typically write instructions. Let's say, for example, we start with push R24 and push R27. A few more instructions. These instructions may have labels here, like, for example, begin, colon, and colon. More instructions. Maybe then we have pop R27 pop R24. And finally instruction ret. So this is a typical instruction of the, sorry, a typical structure of the instructions in the code. Sometimes we start with the push instructions because what we're doing here is saving temporary values. Think of the stack as something in which we put some temporary values that we don't want to forget about. And these two instructions over here are restoring those temporary values. So typically, what we do is the first instructions in the program are to preserve certain values of certain registers. And the last instructions of the program are to restore those values from the stack. And as you can see, the order in which we save and restore these objects is symmetric. First, we take register 24 and 27. So we put it on top of the stack. The stack will then look like this. Here is R 24 on top of that R 27 and the stack pointer would point here. And then at the end, what we do is exactly the opposite with pop R 27. So the value stored in the stack would be loaded into R 27. These value R 24 would be loaded into R 24. And then we finish the execution of the program restoring the initial value of these registers. So this is a policy that needs to be observed by the code. And this is the structure of a generic AVR assembly program.