Page 245 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 245

222                                    Chapter 8 Programming in C and C++


            Compilers are used for different purposes than are assemblers. Studies have shown
        that a typical programmer can generate about ten lines of documented, debugged code per
        day, regardless of whether the program is written in a high-level language or an assembly
        language. Because a high-level language generates about an order of magnitude more
        machine instructions per line, a high-level language program should be an order of
        magnitude shorter (in the number of lines) and an order of magnitude cheaper to write
        than an assembly language program that does the same job.
            However, a high-level language compiler usually produces inefficient code. For
        example, an instruction STAA LOCI might be immediately followed by the instruction
        LDAA LOCI in the compiler output. As the compiler generates code from each line of
        the program, line by line, the last operation of one line can generate the STAA
        instruction, and the first machine code generated by the next line might be the LDAA
        instruction, for the same variable. The compiler is usually unable to detect such an
        occurrence and to simplify the code produced by it. Such inefficient code is quite
        acceptable in a large computer where the slow execution and large memory space needed
        to store the program are traded against the cost of writing the program. Hardware is cheap
        and programmers are expensive, so this is a good thing. In a very small computer, which
        might be put in a refrigerator to control the cooling cycle or keep the time, memory
        space is limited because the whole computer is on just one chip. Inefficient code is
        unacceptable here because there is not much room for code and the cost of writing the
        program is comparatively small. The company that uses high-level languages for small
        microcomputers will not be able to offer all the features that are crammed into a
        competitor's product that is programmed in efficient assembly language; or, if it offers
        the same features, its product will cost more because more memory is needed.
            Some compilers are called optimizing. They use rules to detect and eliminate the
        unnecessary operations such as the STAA and LDAA pair described above. They can be
        used to generate more efficient code than that generated by nonoptimizing compilers. But
        even these optimizing compilers produce some inefficient code. You should examine the
        output of an optimizing compiler to see just how inefficient it is, and you should ignore
        the claims as to how optimal the code is. Compilers are more powerful, and using them
        is like driving a car with an automatic transmission, whereas using assemblers is like
        driving a car with a standard transmission. An automatic transmission is easy to drive
        and appeals to a wider market. A standard transmission is more controlled and enables
        you to get the full capabilities out of the machine.
            We now consider the differences between the compiler and the interpreter. An
        interpreter is rather like a compiler, being written to convert a high-level language into
        machine code. However, it converts a line of code one line at a time and executes the
        resulting code right after it converts it from the high-level language program. A pure
        interpreter stores the high-level language program in memory, rather than the machine
        code for the program, and reads a line at a time, interprets it, and executes it. A popular
        high-level language for interpreters is JAVA, and a JAVA program appears below, doing
        the same job as the previous programs in C. By design, it has the same syntax as C,
            An interpreter reads and executes the source code expression dprd += v[i] *
        w[ i 3 twice. A compiler interprets each source code expression just once, reading it and
        generating its machine code. Later the machine executes the machine code twice.
        Interpreters are slow. However, it is easy to change the program in memory and execute
   240   241   242   243   244   245   246   247   248   249   250