Vous êtes sur la page 1sur 56

3.

Embedded Programs
3.1 Introduction
3.1.1 High-Level Code
3.1.2 Machine Language
3.1.3 Assembly Language Code
3.2 Program translation process
3.3 Representation of programs and their execution flow
3.4 Fundamentals of assembly language and linking
3.4.1 Directives
3.4.2 Labels in Instructions
3.4.3 Source Executable Code
3.5 Mapping tasks in compilation
1
3.1 INTRODUCTION
 Programming provides us with the flexibility to use
the same hardware core for different applications.
 A device whose performance can be modified through
some sort of instructions is called a programmable or
configurable device
 Most I/O ports and peripherals are examples of these
blocks; their configuration should be part of our
program design
 Assembly programming for the MSP430
microcontrollers is introduced in this chapter
 The two most popular assemblers for the MSP430
are the IAR assembler by Softbaugh and Code
Composer Studio (CCS) from Texas Instruments 2
3.1 INTRODUCTION
 Programs are written using a programming language
with specific rules of syntax. These languages are
found in three main levels:
 Machine language,
 Assembly language, and
 High level language

 To illustrate the differences among them, let us


consider the code of an LED in the three levels

3
3.1 INTRODUCTION
oThe program toggles on and off an LED connected to
pin 0 of port 1 (P1.0) of the microcontroller, as
illustrated in Figure 3.1. Toggling is achieved by
changing the voltage level at the pin

Figure 3.1 Simplified hardware connection diagram for LED in board

4
3.1 INTRODUCTION
 The algorithm to achieve this goal is described by
the flowcharts of Figure 3.2, where (a) illustrates
the process in its general terms, and (b) expands
the different steps in more detailed actions.

Figure 3.2 Flow diagram for the blinking LED: a) General Concept; b) Expanded flow diagram 5
3.1.1 HIGH-LEVEL CODE
 Figure 3.3 shows a code in C language which executes
the desired task.
 Readers with some proficiency in C will understand
this source code without problem and associate it with
the flow graph. The compiler takes care of the “set up
stack” step.

Figure 3.3 C language code for LED toggling


3.1.1 HIGH-LEVEL CODE
 Despite this, high-level programming is more
independent of the hardware structure, closer to our
way of thinking, and easier to grasp.
 These are some of many reasons why this level is
preferred for most applications.
 A drawback is that this language is not understood by
the machine. We need tools, called compilers and
interpreters, to make the appropriate translation
 The final machine product depends on the compiler
used.
 Engineers also developed software tools called
debuggers to help correct programming errors,
usually called bugs; correcting them is called
debugging.
7
3.1.2 MACHINE LANGUAGE
 Since digital systems only “understand” zeros (0) and
ones (1), this is how the executable code, i.e., the set of
instructions executed by the CPU, is presented to the
system
 A program written in zeros and ones is a binary
machine language program. The example in Listing
3.2 of Figure 3.4 is for the flow graph of Figure 3.2
 The hex notation version in Listing 3.3, called hex
machine language, is the form in which debuggers
present machine language to users and also the
syntax with which embedded programmers deal with
this level

8
3.1.2 MACHINE LANGUAGE
 Here, each line represents an instruction machine
language is not user friendly and hence the need of
other programming levels
 Instructions for the MSP430 CPU consist of one, two
or three 16-bit words.
 The leading one is the instruction word, with
information relative to the instruction and operands.

9
Figure 3.4 Executable machine language code for the example of Figure 3.1
3.1.3 ASSEMBLY LANGUAGE CODE
 The first step toward a friendlier syntax was the assembly
language, compiled with assemblers
 instruction is now a machine instruction encoded in amore
“human like” form.
 Translating a machine instruction into its assembly form is to
disassembly and the software tool for this task is a disassembler.
 Figure 3.5 shows the assembly and hex versions of the
executable code

10
Figure 3.5 Assembly version for Figure 3.4-Hex machine version shown for comparison
3.2 PROGRAM TRANSLATION PROCESS
 High level languages arose to allow people to
program without having to know all the hardware
details of the computer
 An important feature is that an instruction in a high
level language would typically correspond to several
instructions in machine code
 mapping of each of the high level language
instructions into machine code and their
corresponding use of the functional units
 the programmer has in effect lost the ability to use
the hardware in the most efficient way
 For most programmers, human-friendly
characteristics of high level language for computer
programming make it a “natural choice” for
embedded programming as well 11
3.2 PROGRAM TRANSLATION PROCESS
 C language has features that make it attractive for this
sort of applications
 Perhaps the most important one is that it allows the
programmer to manipulate memory locations with very
little overhead added
 Since input/output units can be treated as memory, C will
also allow the programmer to control them directly
 In general, you use C language for embedded systems
when one or more of the following reasons apply:
 tight control of each and every resource of the architecture is
not necessary;
 efficiency in the use of resources such as memory and power are
not a concern;
 ease of software reuse;
 company policy or user requirements;
 lack of knowledge of assembly language and of the particular
architecture. 12
3.2 PROGRAM TRANSLATION PROCESS

 On the other hand, you use assembly language for


embedded systems when one or more of the following
reasons apply:
 it is imperative or highly desirable that resources be
efficiently handled;
 there is an appropriate knowledge of the assembly
language and of the particular architecture;
 company policy or user requirements.

o In embedded systems, sometimes it becomes


imperative to work both aspects.
o Hence, unlike what we could design as “typical” C
programming, where the complete source is written
in the same language, compilers for embedded
systems provide methods to mix both languages. 13
3.2 PROGRAM TRANSLATION PROCESS
 A compiler is a program developed to translate a high-
level language source code into the machine code of the
system of interest
 For a variety of reasons, compilers are designed in
different ways
 Some produce machine code other than for the machine in
which they are running
 Others translate from one high level language into
another high level language or from a high level language
into assembly language
 The term cross-compiler is used to define these type of
translators
 When the embedded CPU itself cannot host a compiler, or
a compiler is simply not available to run on a particular
CPU, a cross-compiler is used and run on other machine 14
3.2 PROGRAM TRANSLATION PROCESS
 There are also optimizing compilers, i.e., compilers (or
cross-compilers) in which code optimizing techniques are
in place
 These are compilers designed to help the code execute
faster, and include techniques such as constant
propagation, inter-procedural analysis, variable or
register reduction, inline expansion, unreachable code
elimination, loop permutation, etc.
 In terms of software development, an Integrated
Development System or IDE is an application that
usually consists of an editor, a compiler, a linker, and a
debugger, all within the same package.
 The IDE may also include other programs such as a
graphical user interface or GUI, a spell checker, an auto-
completion tool, a simulator, and many other features. 15
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
 In this section we are going to discuss some general
rules of C programming and introduce certain
specifics of C programming for 8051 series of
microcontrollers.
i. Introduction to C Programming for Embedded
Systems
 Most common programming languages for embedded
systems are C, BASIC and assembly languages
 C used for embedded systems is slightly different
compared to C used for general purpose (under a PC
platform)
 Programs for embedded systems are usually expected to
monitor and control external devices and directly
manipulate and use the internal architecture of the
processor such as interrupt handling, timers, serial
communications and other available features 16
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
i. Introduction to C Programming for Embedded
Systems
 There are many factors to consider when selecting
languages for embedded systems
 Efficiency - Programs must be as short as possible and memory
must be used efficiently.
 Speed - Programs must run as fast as possible.
 Ease of implementation
 Maintainability
 Readability
 C compilers for embedded systems must provide ways to
examine and utilize various features of the
microcontroller's internal and external architecture; this
includes:
 Interrupt Service Routines
 Reading from and writing to internal and external memories
 Bit manipulation
17
 Implementation of timers / counters
 Examination of internal registers
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
i. Introduction to C Programming for Embedded
Systems
 Standard C compiler communicates with the hardware
components via the operating system of the machine but
the C compiler for the embedded system must
communicate directly with the processor and its
components
 For example consider this statement:
 Printf (" C - Programming for 8051\n");
 In standard C running on a PC platform, the statement
causes the string inside the quotation to be displayed on
the screen.
 The same statement in an embedded system causes the
string to be transmitted via the serial port pin (i.e TXD) of
the microcontroller provided the serial port has been
initialized and enabled. 18
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 - Another example:
 c=getch();
 In standard C running on a PC platform this causes
a character to be read from the keyboard on a PC.
 In an embedded system the instruction causes a
character to be read from the serial pin (i.e. RXD) of
the microcontroller.
ii.Template for Embedded C Program
 #include <reg66x.h>
void main(void)
{
// body of the program goes here
19
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

 the first line of the template is the C directive


“#include <reg66x.h>”
 this tells the compiler that during compilation, it
should look into this file for symbols not defined
within the program
 “reg66x.h” file simple defines the internal special
function registers and their addresses
 Note that in C numbers that are hexadecimal are
represented by the 0x.
 the next line in the template declares the beginning of the
body of the main part of the program
 the main part of the program is treated as any other
function in C program
 every C program should have a main function
20
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 functions are like “procedures” and “subroutines” in other
languages
 C function may be written in one of the following formats:
 it may require some parameters to work on
 it may return a value that it evaluates or determines
 it may neither require parameters nor return any value
 if a function requires any parameters, they are placed inside the
brackets following the name of the function
 if a function should return a value, it is declared just before the
name of the function
 when the word ‘void’ is used before the function name it
indicates that the function does not return any value
 when the word ‘void’ is used between the brackets it indicates
that the function does not require any parameters
 main function declaration:
 void main(void)
 therefore, indicates that the main function requires no 21
parameters and that it does not return any value.
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
iii. C Directives
 #include is one of many C directives. It is used to insert
the contents of another file into the source code of the
current file
 There are two slightly different form of using #include
directive:
#include < filename > or #include “filename”
 The first form (with the angle brackets) will search for the
include file in certain locations known to the compiler and
it is used to include standard system header files (such
are stdlib.h and stdio.h in standard C).
 The second form (with the double quotes) will search for
the file in the same directory as the source file and this is
used for header files specific to the program and usually
written by the programmer 22
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 All directives are preceded with a “#” symbol another
useful directive is a #define directive
 #define directive associates a symbolic name with some
numerical value or text
 The value of “ON” in the program can be defined as 0xFF
throughout the program using:
#define ON 0xFF
 This approach may be used to define various numerical
values in the program using more readable and
understandable symbols
 The advantage of using symbols rather than the actual
numerical values is that, if you need to change the value,
all you need to do is to change the number that is
assigned to the symbol in the define statement rather
than changing it within the program which in some cases
may be a large program and therefore tedious to do
23
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
 Example 1: Program to turn the LEDs on port 1 ON
(see Figure 3.6).
#include <reg66x.h>
void main(void)
{
P1 = 0xFF;
}

Figure 3.6 LEDs and Switches Interfaced to Port 1 and Port 0 of 8051 Microcontroller

 The body of the main function consists of just one


statement and that is P1=0xFF. This tells the
compiler to send the number 0xFF which is the
hexadecimal equivalent of 255 or in binary
(11111111) to port 1 which in turn causes the 8 LEDs
in port 1 to turn ON. 24
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

 Note that just like the line in the main body of the program,
every line of a C program must end with a semicolon (i.e. ;)
except in some special occasions.
 Alternative version of this program using directive #define.
#include <reg66x.h>
#define ON 0xFF
void main(void)
{
P1 = ON;
}
 In the above example the value of “ON” is defined as 0xFF
using:
#define ON 0xFF
 and the statement in the body of the program is then written as:
P1 = ON; 25
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

iv. Programming Time Delays


 For various reasons it might be necessary to include
some sort of time delay routine in most of the
embedded system programs
 Sophisticated and very accurate techniques using
timers/counters in the processor exist to achieve this
one simple approach (not involving timers) is to let
the processor count for a while before it continues
for(j=0; j<=255; j=j+1)
{
;
}
 Once the loop counter reaches the value of 255 the
program will exit the loop and continue execution 26
with the first statement following the loop section
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

 For a longer delays we can use a nested loop


structure, i.e. loop within the loop:
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}

 Note that with this structure the program counts to


255 x 255
v. Indefinite Loops
 Embedded system might be required to continuously
27
execute a section of a program indefinitely
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 To achieve this indefinite loop (loop without any exit
condition) can be used. The statement that performs
this is:
for(;;)
{
}
 Part of the program to be repeated indefinitely must
then be placed in between the curly brackets after
the for(; ;) statement.
vi. Variables in Embedded C
 Variables in C program are expected to change
within a program
 Variables in C may consist of a single letter or a
combination of a number of letters and numbers 28
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

 Spaces and punctuation are not allowed as part of a


variable name
 C is a case sensitive language (therefore I and i are
treated as two separate variables)
 In a C program variables must be declared
immediately after the curly bracket marking the
beginning of a function to declare a variable, its type
must be defined, it provides information to the
compiler of its storage requirement
 Some of the more common types supported by C are
listed in the table below

29
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
Type Size Range
unsigned char 1 byte 0 to 255
(signed) char 1 byte -128 to 127
unsigned int 2 bytes 0 to 65535
(signed) int 2 bytes -32768 to 32767
bit 1 bit 0 or 1 (RAM bit-addressable part of memory only)
sbit 1bit 0 or 1 (SFR bit-addressable part of memory only)
sfr 8bit RAM addresses 80h-FFh only

•Definition of type of a variable in a C program is an important factor in


the efficiency of a program
•Depending on the type of a variable the compiler reserves memory
spaces for that variable
•Consider the following guidelines when selecting the type of variables
if speed is important and sign is not important, make every
variable unsigned
unsigned char is the most common type to use in programming 30
8051 microcontroller as most registers in the processors are of size 8-
bits (i.e one byte)
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 Program to indefinitely flash all LEDs on
Example 2:
port 1 at a rate of 1 second
#include <reg66x.h>
void main(void)
{
unsigned char i,j;
for(;;)
{
P1 = 0xFF; /* Turn All LEDs ON */
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}
P1 = 0x00; /* Turn All LEDs OFF */
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}
} 31
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
vii. C Functions
 When a part of a program must be repeated more than
once, a more efficient way of implementing is to call the
block to be repeated a name and simple use the name
when the block is needed
 This leads to implementation of C function in the program
 The function (block) must be declared before the main
program and defined, normally immediately after the
main program is ended
 Rules for function declaration are same as for declaration
of main function
void DELAY (void)
 The above function declaration informs the compiler that
there will be a function called DELAY, requiring no
parameters and returning no parameters 32
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW

 The name of a function must follow the rules for the


name of a variable - the function name may not have
spaces, or any punctuation
 A use of functions is advisable as functions make
programs shorter and readable, a shorter program
also requires less space in the memory and therefore
better efficiency
 The function is called in the main program using
function name and appropriate parameters (if any)
 Example 3: In this example program from Example
2, to indefinitely flash all LEDs on port 1 at a rate of
1 second is rewritten using function to generate time
delay 33
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
#include <reg66x.h>
void DELAY(void);
void main(void)
{
for(;;)
{
P1 = 0xFF; /* Turn All LEDs ON */
DELAY(); /* Wait for 1 second */
P1 = 0x00; /* Turn All LEDs OFF */
DELAY();
}
}
void DELAY(void)
{
unsigned char i, j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}
}
34
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
viii. Other Loops in C
 Two other loops exist in C language - <do…while>
and <while>. Instructions to generate single loop
delay using those two loop techniques are given
below
i=0;
do
{
i=i+1;
} while(i<=255);
i=0;
while(i<=255)
{
i=i+1;
35
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
Example 4: Program from Examples 2 and 3 is rewritten and modified so that LEDs on port 1 flash with 1 s
time delay only 10 times.
#include <reg66x.h>
void DELAY(void);
void main(void)
{
unsigned char N;
N=0;
do
{
P1 = 0xFF; /* Turn All LEDs ON */
DELAY(); /* Wait for 1 second */
P1 = 0x00; /* Turn All LEDs OFF */
DELAY();
N=N+1;
} while(N<10);
}
void DELAY(void)
{
unsigned char i,j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
36
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

ix. Making Decisions in the Program


 An important feature of any embedded system is the
ability to test the value of any parameter in the
system and based on the outcome of this test take an
appropriate action
 The parameter tested must be a program variable
and C construct usually employed to perform test is
the <if> statement - effect of this statement is
illustrated on the flowchart below

37
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

 - C instructions to achieve this action are


if(condition)
{
Perform Action A
}
else
{
Perform Action B
}
x. ? Operator
 In the C program operator <?> can be used as a short
hand version of the ‘if’ statement discussed above.
 Flowchart and line of code provided below explain
the effect of using this operator 38
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

oA = (B > C) ? X : Y; in other words “if B is greater


than C then let A=X otherwise let A=Y”
Example 5: Program to operate the LEDs attached to
port 1 as a BCD (Binary Coded Decimal) up counter. A
BCD up counter is one, which counts in binary from 0
to 9 and then repeats from 0 again
39
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
#include <reg66x.h>
void DELAY(void);
void main(void)
{
unsigned char N=0;
for(;;)
{
P1 = N; /* Turn All LEDs ON */
DELAY(); /* Wait for a while */
N=N+1;
if(N>9)
{
N=0;
}
}
}
void DELAY(void)
{
unsigned char i,j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
} 40
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
xi.Arrays
 Arrays are used when it is necessary to store larger
number of data of same type into consecutive memory
locations where they can easily be accessed by the
program at some later stage
 As any other data in the program, array must be declared
at the beginning of the main program
 Upon reading this declaration compiler will reserve
appropriate number of memory locations to store the
array elements
unsigned char T[20]
o This array declaration will cause the compiler to reserve
20 consecutive memory locations and call it T
o Note that number inside the square brackets indicates the
size of declared array 41
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
Example 6: Two versions of the program that reads the state of the switches on port 0 and operates
the LEDs on port 1 accordingly. For example if switch S0 is pressed, program will turn LED0 ON,
if S2 and S3 are pressed, then LED 2 and 3 must turn ON and so on.
// version 1
#include <reg66x.h>
void main(void)
{
for(;;)
{
P1=P0;
}
}
// version 2
#include <reg66x.h>
#define SWITCHES P0
#define LEDS P1
void main(void)
{
for(;;)
{
LEDS = SWITCHES;
} 42
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR EXECUTION FLOW
Example 7: This program monitors switch S0 attached to the pin 0 of port 0. When this
switch is pressed, it flashes the single LED attached to pin 0 of port 1 ten times.
Previously discussed bit masking technique is used to test the value of switch S0.
#include <reg66x.h>
#define ON 0x01
#define OFF 0x00
#define mask 0x01 // 00000001
void DELAY(void);
void main(void)
{
unsigned char S0;
unsigned char N;
for(;;)
{
S0=P0&mask; // masking bits
while(S0) // wait for key press
{
for(N=0;N<10;N++)
{
P1=ON;
DELAY();
P1=OFF;
DELAY();
}
S0=P0&mask;
}
}
}
void DELAY(void)
{
unsigned char i,j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
; 43
}
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

 Another way to access a single pin on any port of


8051 is to make use of special sbit data type.
 This data type provides access to bit-addressable
SFRs and bit-addressable memory space within the
processor.
 Line: sbit S0=P0^0; creates an sbit type variable S0
that points to pin 0 of port 0
 Using bit addressing ability of 8051 C compiler,
alternative version of the program can be written

44
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
#include <reg66x.h>
#define ON 0xFF
#define OFF 0x00
sbit S0 = P0^0;
void DELAY(void);
void main(void)
{
unsigned char N;
for(;;)
{
while(S0)
{
for(N=0;N<10;N++)
{
P1=ON;
DELAY();
P1=OFF;
DELAY();
}
}
}
}

45
Note that because there is no way to indirectly address registers in the 8051, addresses
for sbit type variables must be declared outside of any functions within the code
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING
 Although simpler to read than machine form, the
code of Figure 3.5, which is a pure assembly listing,
still has unfriendly notes.
 For example, the user needs the memory map to
identify addresses 0x0022 and 0x0021, and
knowledge of machine instruction lengths to know
how many bytes the PC should jump.
 A friendlier version is found in Figure 3.7, written
with IAR assembler syntax. This is part of a
complete source file.
 Each line in the source file is a source statement.

46
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

Figure 3.7 Assembly language code for Figure 3.4

47
Figure 3.8 Example of a list file line
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

 Now assembly instructions have the format


illustrated below; only the original instruction fields,
mnemonics and operands, are compulsory.
 Mnemonics cannot start on the first column.

 In fact, every source statement has the same format,


all fields being in general optional.
 The mnemonics may be a machine instruction
mnemonics or a directive.
 Operands must always go after a mnemonic.

 Observe that the machine language and instruction


mnemonics have not changed
48
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

 But now there are new features in the listing that


make it easier to read.
 Namely, we find comments, labels, symbolic names,
and directives.
 On the first column we can only have a comment
(starting with the semicolon), a label, a C-type
preprocessor directive, or a blank
 Assembling is done with a two pass assembler, which
runs over the source code more than once to resolve
constants and labels
 The assembler receives the source file and outputs an
object f ile, as well as other optional files
49
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

3.4.1 Directives
 Directives are for the assembler only
 They do not translate into machine code or data to be
loaded into the microcontroller memory
 They serve to organize the program, create labels
and symbolic names, and so on
 Directives depend on the assembler, but instructions
belong to the CPU architecture and are independent
of the assembler
• Comments: Anything on a line after and including a
semicolon (;) is a comment
• Names: These are names given to numbers, expressions,
hardware devices, and so on
• Labels: These always start on the first column
• Directives EQU, #define, #include and ORG: The code
50
example of Figure 3.7 introduces some directives
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
 Example 3.8 Even if the source file is not yet
complete, let us look at what happens when the
assembly code of Figure 3.7 is processed.
 Labels DELAY and LED, as well as the symbolic
name COUNTER are identified as 50000 (=C350h), 1
(=01h), and R15, respectively.
 All other symbolic names found, such as P1DIR and
P1OUT, are defined in the header file.
 For other labels, the value will be generated, and the
ORG directive allows us to understand the process.
 ORG 0F800h is used just before the beginning of the
source code
 Therefore the first machine language instruction
4031 0300 following the directive goes to that
51
address, 0F800h
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

 The result can be appreciated with the list file, as


partially illustrated below:

 The assembly listing has the label RESET for this


first instruction, so RESET becomes 0F800h.
 Similarly, the label StopWDT takes the value F804h,
which is the address where the instruction is stored.
 Every label attached to an instruction will be then
assigned the value of the corresponding instruction
address.
52
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

3.4.2 Labels in Instructions


o Always use a label for
 Entry statement of the main code and of an Interrupt Service
Routine (ISR). The label takes the value of the reset vector or
interrupt vector.
 Entry statement of a subroutine. The label can be used to call
the subroutine using it in immediate addressing mode in the
call instruction, for example call #Label.
 Instruction to which reference is made, for example for a jump.

Labels are also useful as highlights for instructions, even


if no reference is needed
Example 3.9 Continuing with the same listing used in
example 3.8, the reader can verify that the label Mainloop
will be equal to 0xF80E. The label is used for jump
instructions and can be used as any other integer 53
constant with addressing modes as illustrated next.
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

 mov.w #Mainloop, R6 (immediate mode for Mainloop)


yields R6 = F80Eh. mov.w Mainloop,R6 (direct or
symbolic mode forMainloop) yields R6 = 403F.
 Call #Mainloop (immediate mode for Mainloop) calls
a subroutine with entry line at address 0xF80E.
Hence, the CPU pushes the PC onto the top of the
stack (TOS) and then loads it with 0xF80E.
 Call Mainloop (direct or symbolic mode for Mainloop)
will push the PC onto the TOS and load it with
0x403F.
 In this particular example, there will be an error
since the values at PC must be even. The CPU will
reset.
54
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING
3.4.3 Source Executable Code
 The executable code is the set of CPU executable source
statements, namely, the instructions.
 It is the most important part of the source file.
 It consists of the main code and, optionally, subroutines
and Interrupt Service Routines. Important characteristics
to consider are
i. Label for Entry line: Names like “RESET”, “INIT”,
“START” are common, but any one will do. This label
serves to load the reset vector.
ii. and peripherals configuration: This task includes
 stack initialization,
 configuration of the watchdog timer,
 configuration of peripherals and I/O ports as needed
iii. Main routine or algorithms: The instructions for the
intended program. 55
3.5 MAPPING TASKS IN COMPILATION
 When multiple tasks are mapped to the same processor,
they have to be scheduled to alternate their execution.
 Multi-task generation produces code that uses an
underlying multi-task engine in order to manage and
schedule such tasks.
 Two possible approaches for dynamic multitasking:
RTOS-based multi-tasking and interrupt-based multi-
tasking
 The approach predominantly-used is RTOS-based multi-
tasking, in which user tasks are executed on top of an off-
the-shelf RTOS and scheduled by the RTOS scheduler.
 Sometimes performance and resource constraints hinder
using a complete RTOS. In such a case, an alternative of
interrupt-based multi-tasking can be applied
56

Vous aimerez peut-être aussi