ChipCenter Questlink
SEARCH CHIPCENTER
Search Type:
Search for:




Knowledge Centers
Product Reviews
Data Sheets
Guides & Experts
News
International
Ask Us
Circuit Cellar Online
App Notes
NetSeminars
Careers
Resources
FAQ
EE Times Network
Electronics Group Sites


Programming: To C or Not to C
by Robert Ashby

Most of the programming that I do at work involves low-cost (less than $5) 8-bit processors. We put out a lot of different projects a year. I would estimate that we did at least 50 projects last year that involved programming these microcontrollers. One of the most frequently asked questions that I get from vendors or colleagues is "What language do you program in? C?" I then have to disguise a smirk when I see the shocked look I get when I respond that most of our projects are programmed in assembly.

The shocked look is because of how many projects that we do at work. We manage several projects at a time, and will do more than 60 projects throughout the year. This can seem daunting since each project will have, on average, 10,000+ lines of code. That's a lot of eyestrain! However, programming in C isn't always the best solution in the World of Robert. It may not be the best choice for your world either. This isn't because I have a secret desire to excel as a masochist. It is because of the trade-offs you encounter when programming in C. Let's take a look at what those trade-offs are.

As you likely know, microprocessors run on machine language. There is some more breaking down on processor function that we can do, but for this article it will suffice to say that code needs to be expressed in a binary format for the processor to perform it. The C language isn't the next step up from machine language. There is a step in between called assembly language. It involves some mnemonics that can vary dramatically from processor to processor. The C language is a higher language that is more universal between processors and closer to the natural way that we might explain code operation. This C language is converted by a C compiler into the assembly language for that processor. This conversion has some costs associated with it. We will look at a quick summary of the trade-offs and then look into a couple of real-life examples.

Using C Language

Advantages:

  • More universally understood code
  • Quicker adaptability to radically different processors
  • Easier to learn since the code doesn't vary as much from one processor to the next
  • Development of large projects can sometimes be quicker
  • Protections for code space and RAM are often built in

Disadvantages:

  • Generally speaking, it will run slower
  • It tends to use more resources (RAM and ROM) than assembly does
  • Optimization can be minimal on small processors
  • Because of limited resources, you can easily cause unforeseen problems

Using Assembly Language

Advantages:

  • Code can be highly optimized
  • In small processors, it's sometimes the simpler and quicker way to go
  • Since resource manipulation is more direct, resource corruption can be more easily noticed

Disadvantages:

  • Architectural differences between processors can't dramatically change languages from processor to processor; therefore code isn't as easily ported from one processor to another
  • Development of large projects from scratch can take more time
  • You need to pay more attention to resource protection
  • Your peers might look you upon as odd when you program in assembly

To illustrate my point, I thought that I might use the C language as it is compiled in my computer. I have written a small program that doesn't do anything more useful than illustrate my point.

    //C program for pointless illustrations
    {
    int num3=0;
    int num4=0;
    int sum2;
    sum2=num3+num4;
    return;
    }
    int main(int argc, char* argv[])
    {
    int num1=0;
    int num2=0;
    int sum1;
    sum1=num1+num2;
    addnumber();
    return 0;
    }
    //end of C program
    

This program seems fairly simple, and I'm sure that you could code a simple program that would add these numbers without too much overhead. Let's take a look to see how this code breaks down after being compiled. There are line numbers next to the compiled code and address locations next to the program assembly code.

    //Here is the program as it compiles into assembly
    6: void addnumber()
    7: {
    00401010 push ebp
    00401011 mov ebp,esp
    00401013 sub esp,4Ch
    00401016 push ebx
    00401017 push esi
    00401018 push edi
    00401019 lea edi,[ebp-4Ch]
    0040101C mov ecx,13h
    00401021 mov eax,0CCCCCCCCh
    00401026 rep stos dword ptr [edi]
    8: int num3=0;
    00401028 mov dword ptr [ebp-4],0
    9: int num4=0;
    0040102F mov dword ptr [ebp-8],0
    10: int sum2;
    11: sum2=num3+num4;
    00401036 mov eax,dword ptr [ebp-4]
    00401039 add eax,dword ptr [ebp-8]
    0040103C mov dword ptr [ebp-0Ch],eax
    12: return;
    13: }
    15: int main(int argc, char* argv[])
    16: {
    0040B460 push ebp
    0040B461 mov ebp,esp
    0040B463 sub esp,4Ch
    0040B466 push ebx
    0040B467 push esi
    0040B468 push edi
    0040B469 lea edi,[ebp-4Ch]
    0040B46C mov ecx,13h
    0040B471 mov eax,0CCCCCCCCh
    0040B476 rep stos dword ptr [edi]
    17: int num1=0;
    0040B478 mov dword ptr [ebp-4],0
    18: int num2=0;
    0040B47F mov dword ptr [ebp-8],0
    19: int sum1;
    20: sum1=num1+num2;
    0040B486 mov eax,dword ptr [ebp-4]
    0040B489 add eax,dword ptr [ebp-8]
    0040B48C mov dword ptr [ebp-0Ch],eax
    21: addnumber();
    0040B48F call @ILT+5(addnumber) (0040100a)
    22: return 0;
    0040B494 xor eax,eax
    23: }
    //end of assembly conversion
    

This is probably a little more involved than what you had pictured to be necessary to perform two additions. It does do a great job to illustrate some of the extra overhead in code that is added when you use a C compiler. The reason why we see so much overhead is necessary for your computer to work with several with virtually any combination of subroutines, interrupts, or set of instructions. You need to make sure that memory is properly allocated and registers are saved at all times to prevent data corruption. These precautions can build up to be a lot of overhead. I counted at least 20 instructions above that could have been eliminated. That's a lot of overhead when the entire program is a little more than 30 instructions.

There were some neat advantages to this example though. We were able to write a simple program without having to know anything about the architecture of the processor. We didn't need to have any knowledge about the eax register, etc.

Small microcontrollers will have the same type of resources that your computer has. The big difference between your microcontroller and your computer is measured in the millions. It's memory size. You won't always have the luxury of pushing and popping everything every time you make a subroutine call. You won't always have the clock cycles to spare, or have the ROM space to burn. These restrictions might push you into a bigger and more expensive processor when it really isn't necessary. However, if you decide to use assembly language, then you will have to handle your own memory management and learn a little more about the processor that you are going to use.

It will take careful consideration of your particular situation to decide which path to choose. The best solution may even be a combination of C language and assembly language.

Don't be afraid of the assembly world. It hasn't gone the way of the dinosaur. Higher languages have their place, and they allow users to create more and more complex programs and applications. Lower level languages do require a little more work, but also allow great opportunities to stretch resources to a maximum and dramatically increase performance. Consider the old ways if you need to save a few dollars, or want to create a very high performance application.

Embedded Engineering

Guides and Experts   Analog Avenue   EDA Tools   PLD   DSP   EDA   Embedded Systems   Power   Test
Click here to get your listing up.

Copyright © 2003 ChipCenter-QuestLink
About ChipCenter-Questlink  Contact Us  Privacy Statement   Advertising Information  FAQ