Page 152 - Embedded Microprocessor Systems Real World Design
P. 152
support its free-spending ways. The same goes for speed: Some compilers just
cannot seem to generate fast code.
Optimization
Optimizing compilers attempt to produce the most efficient code and can make
the difference between an application that works and one that does not. An opti-
mizing compiler works by eliminating unnecessary machine code. For example, if
the code tests a variable to see whether a bit is set and then tests the variable
again to check a different bit, a nonoptimizing compiler might read the variable
twice. An optimizing compiler might read the variable once, store it in a register,
and knowing that the variable has not been changed, use the value in the register
when the second check is done. But beware; this can cause problems. If the vari-
able actually is a hardware register, a change between the first and second checks
would go undetected in the optimized version. For this reason, most optimizing
compilers allow optimization to be turned off for sections of code, and they allow
you to define memory-mapped hardware that is treated differently than ordinary
RAM. Some compilers, especially for microcontrollers, permit you to optimize for
speed or size, but there sometimes is a catch: You can optimize only the entire
program. No compiler directives let you turn optimization on and off. To offset
that, microcontroller compilers typically have a way to define hardware-specific
addresses, such as I/O ports, forcing the compiler not to optimize when accessing
these locations.
If your application requires floating-point calculations, be sure the floating-point
libraries are small enough to fit the available space and that they run fast enough.
If you have a hardware floating-point processor, of course, be sure the compiler can
take advantage of it.
Assembly Support
Many applications still require assembly language for things like initialization, inter-
rupts, or specialized (fast) I/O. The development compiler should make it fairly
easy to include assembler files (possibly as inline code) into the software.
Another assembly-language related issue occurs when using microcontrollers.
Due to the limited stack size, high-level languages typically do not pass parameters
to assembly functions using the stack but instead use an area in RAM. This usually
is an overlay area shared with other functions-the information no longer is needed
when the function is finished. When writing a function in the HLL, the compiler
takes care of getting dynamic variables out of the RAM overlay area, initializing
the variables within the function, and restoring everything when the function is
finished. If you must link assembler functions into HLL code, you need to take
care of all these details. Thus, be sure the HLL compiler has a welldefined inter-
face to the assembler and a welldocumented procedure for defining the functions
Software Design 133