Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 5314
Скачиваний: 0
8. Assembly language 229
tst memory
TeST memory for zero
tsta
TeST Accumulator for zero
Code suitable macros. Why do you think this approach might not be such a good idea?
CHAPTER 9
High-Level Language
All the programs we have written in the last six chapters have been in symbolic assembly language. Whilst assembly-level software is a quantum step up from pure machine-level code (see page 198) nevertheless there is still a one-to-one relationship between machine and assemblylevel instructions. This means that the programmer is forced to think in terms of the MCU’s internal structure – that is of registers and memory
– rather than in terms of the problem algorithm. Although most assemblers have a macro facility, whereby several machine-level instructions can be grouped to form pseudo high-level instructions, this is only tinkering with the di culty. What is this di culty with machine-oriented language? In order to improve the e ectiveness, quality and reusability of a program, the coding language should be independent of the underlying processor’s architecture and should have a syntax more oriented to problem-solving.
We are not going to attempt to teach a high-level language in a single short chapter. However, after completing this chapter you will:
•Understand the need for a high-level language.
•Appreciate the advantages of using a high-level language.
•Understand the problems of using a high-level language for embedded microcontroller applications.
•Be able to write a short program in C.
The di culty in coding large programs in a computer’s native language was clearly appreciated within a few years of the introduction of commercial systems. Apart from anything else, computers quickly became obsolete with monotonous regularity, and programs needed to be rewritten for each model introduction. Large applications programs, even at that time, required many thousands of lines of code. Programmers were as rare as hen’s teeth and worth their weight in gold. It was quickly deduced that for computers to be a commercial success, a means had to be found to preserve the investment in scarce programmers’ time. In developing a universal language, independent of the host hardware, the opportunity would be taken to allow the programmer to express the code in a more natural syntax related to problem-solving rather than in terms of memory, registers and flags.
234 The Quintessential PIC Microcontroller
Fig. 9.2 Onion skin view of the steps leading to an executable program.
it is likely to be a team e ort, with all the di culties in integrating the code and foibles of several people. A great deal of self-discipline and skill is demanded of such personnel, as is attention to documentation. Even with all this, the final result cannot be easily transplanted to machines with other processors, needing a nearly complete rewrite.
In the early 1970s, Ken Thompson – an employee at Bell Laboratories
– developed the first version of the UNIX operating system. This was written in assembler language for a DEC PDP7 minicomputer. In an attempt to promote the use of this operating system (OS) within the company, some work was done in rewriting UNIX in a high-level language. The language CPL (Combined Programming Language) had been developed jointly by Cambridge and London universities in the mid-1960s, and has some useful attributes for this area of work. BCPL (Basic CPL) was a somewhat less complex but more e cient variant designed as a compiler-writing tool in the late 1960s. The language B (after the first letter in BCPL) was developed for the task of rewriting UNIX for the DEC PDP11 and was essentially BCPL with a di erent syntax.
Both BCPL and B only used one type of object, the natural size machine word – 16 bits for the PDP-11. This typeless structure led to di culties in dealing with individual bytes and floating-point computation. C (the second letter of BCPL) was developed in 1972 to address this problem, by
9. High-Level Language 235
creating a range of objects of both integer and floating-point types. This enhanced its portability and flexibility. UNIX was reworked in C during the summer of 1973, comprising around 10,000 lines of high-level code and 1000 lines at assembly level. It occupied some 30% more storage than the original version.
Although C has been closely associated with UNIX, over the intervening years it has escaped to appear in compilers running under virtually every known OS, from mainframe CPUs down to single-chip MCUs. Furthermore, although originally a systems programming language, it is now used to write applications programs ranging from Computer Aided Design (CAD) packages down to the intelligence behind smart egg-timers!
For over 10 years the o cial definition was the first edition of The C Programming Language, written by the language’s originators Brian W. Kernighan and Dennis M. Ritchie. It is a tribute to the power and simplicity of the language that over the years it has survived virtually intact, resisting the tendency to split into dialects and new versions. In 1983 the American National Standards Institute (ANSI) established the X3J11 committee to provide a modern and comprehensive definition of C to reflect the enhanced role of this language. The resulting definition, known as Standard or ANSII C, was finally approved during 1990.
Apart from its use as the language of choice for embedded MPU/MCU circuits, C (together with its C++ and Java object-oriented o spring) is without doubt the most popular general-purpose programming language at the time of writing. It has been called by its detractors a high-level assembler. However, this closeness of C to assembly-level code, together with the ability to mix code based on both levels in the one program, is of particular benefit for embedded targets.
The main advantages of the use of high-level language as source code for embedded targets are:
•It is more productive, in the sense that it takes around the same time to write, test and debug a line of code irrespective of language. By definition, a line of high-level code is equivalent to several lines of assembly code.
•Syntax is more oriented to human problem-solving. This improves productivity and accuracy, and makes the code easier to document, debug, maintain and adapt to changing circumstances.
•Programs are easier to port to di erent hardware platforms, although they are rarely 100% portable. Thus they are likely to have a longer productive life, being relatively immune to hardware developments.
•As such code is relatively hardware-independent, the customer base is considerably larger. This gives an economic impetus to produce extensive support libraries of standard functions, such as mathematical and communication modules, which can be reused in many projects.
236 The Quintessential PIC Microcontroller
Of course there are disadvantages as well, specifically when code is being produced to run in poorly resourced MPU/MCU-based circuitry.
•The code produced is less space-e cient and often runs more slowly than native assembly code.
•The compiler is much more expensive than an assembler. A professional product will often cost several thousand pounds/dollars.
•Debugging can be di cult, as the actual code executed by the target processor is the generated assembler code. The processor does not execute high-level code directly. Products that facilitate high-level debugging are, again, very expensive.
Program 9.1 is an example of a C function (a function is C’s counterpart to a subroutine) that evaluates the relationship:
n
sum = k
k=1
for example, if n = 5 then we have:
sum = 5 + 4 + 3 + 2 + 1
In the implementation n is the integer passed to the function, which computes and returns the integer sum as defined. The program implements this task by continually adding n to the pre-cleared sum, as n is decremented to zero.
Let us dissect it line by line. Each line is labelled with its number. This is for clarity in our discussion and is not part of the program.
Line 1: This line names the function (subroutine) summation and declares that it returns an unsigned long integer (a 16-bit unsigned object in the compiler used to illustrate this chapter) and expects an unsigned integer (a 8-bit unsigned object) to be passed to it called n.
Line 2: A left brace { means begin. All begins must be matched by an end, which is designated by a right brace }. It is good practice
Program 9.1 A simple function coded in C.
1:unsigned long summation(unsigned int n)
2:{
3:unsigned long sum = 0;
4:while(n>0)
5:{
6:sum = sum + n;
7:--n;
8:}
9:return sum;
10:}