8.1. Creating an Executable Program from Assembly Code
The following figure shows an assembly program. You may create this program using a plain text editor, that is, a program that stores the text you see in the screen as a simple ASCII or UNICODE sequence of characters, with no information about style.
![](https://i-blog.csdnimg.cn/blog_migrate/afd59751a116406561e3e67e424a7c6d.png)
Example of Assembly Program
An assembly program is divided into sections each of them delimited by a sentence marking its start. The line .section .data
does not translate into any instruction, but instead is a mark to let the assembler know that the text appearing after contains data definitions. The words included in the program that are not translated into code but instead are order for the assembler are called directives.
In its second line, the program defines a string which is encoded as a sequence of ASCII values. The line contains the directive .asciz
followed by the string surrounded by double quotes which instructs the assembler to allocate space in memory and store the string in a specific location. This definition of a string is preceded by the word my_msg
followed by a colon. This is the way a label is defined in an assembly code. The name of the label has been chosen by the programmer as the way to refer to the string defined in that line. As you can see, this construction could be thought as the equivalent of declaring and defining a variable in a high level programming language, but in a much more simplified way.
The line containing the string .section .text
tells the assembler that the data definitions have finished and the following lines contain the assembly instructions (the code).
The following line contains one more directive declaring the word main
as a global symbol. This means that the location in the code with such label can be accessed from outside of the file. This is the mechanism used in assembly code to define the starting point of the program. By convention, the program will start in the instruction labelled with the name main
and such label must be declared global.
Once this program has been created with the editor in a file with name file.s
, the assembler is invoked with the following command:
avr-gcc -Wall -g -Os -DF_CPU=16000000UL -mmcu=atmega328p -o program file.s
and the executable with name program
is created. The assembler performs a set of steps similar to what a Java compiler does. If there is any syntactical error in the program, a message is shown in the screen and the program is not created. If the program is correctly written, the command finished with no message and the program has been created.
Any assembly program must then have following structure
:
;;; Data definitions go here
.section .data
;;; Code definition goes here
.section .text .global main main: ret .end
Remarks in the code can be included either with the prefix ;;
at the beginning of the line, or simply with ; in the middle of a line. The characters remaining in the line will be ignored by the assembler.
Based in this template, the program shown in the previous figure has executed the instructions:
push R24
push R25
ldi R24, lo8(my_msg) ldi R25, hi8(my_msg) push R25 push R24 call printf pop R0 pop R0 pop R25 pop R24 ret
The first two instructions are copying the content of two registers in the stack. This is because the program will finish with all registers containing the values that had at the beginning of the execution (except for R0), a convention that we will implement in all our programs. The instructions ldi
load specific values in registers R24
and R25
which are then uploaded in the stack. The subroutine printf
prints a message in the serial monitor and expects the address of that string in the stack.
The instructions pop R0
simply remove the values previously loaded in the stack so that it is restored to its initial state. The last two instruction restore the initial values of registers R25
and R24
respectively.
The following video shows how an AVR assembly program is created..
8.2. Data Definition
Assembly programs, as other programming languages, allow the definition of data structures with its content. However, this language is so close to the representation used by the microprocessor, that only simple data structures are allowed. The complex data structures offered by high level programming languages such as Java are translated in terms of simple memory definitions by the compiler.
All data definitions in an assembly program must be included in the data section which starts after the directive .section .data
. All the data defined in the section is stored in consecutive memory locations. If two variables are defined in contiguous lines, they will be stored next to each other in memory.
The main difficulty to manipulate data in assembly is that there is no information stored in memory to remember the type of data or its structure. At the level of machine level the microprocessor is simply manipulating bytes, with no notion whatsoever of the structures the programmer intended to define. No type checking of any sort is done, as no type information is retained. In other words, an assembly program may access the bytes that encode the letters of a string and treat them as integers, naturals, floating point or any other available format. The data manipulated by any instruction is only referred by its address.
8.2.1. Byte and Integer Definition
The definition of numeric valu