Programming microcontrollers in ASM or C & how it's done

Just to clarify on these topics:

If I were to program a microcontroller in ASM I would use an assembler, of course. The assembler would compile the code into opcodes (machine code?)(generally 1:1 ratio) which would then be converted into HEX file. It is this file that is actually read into memory and used to program the controller? I read that the HEX file contains the actual location the data (part of that data frame) is to be stored in memory as well as the data to be written there.

If I were program a microcontroller in C (or some other language) what are the restrictions? It would be necessary that you use a C compiler, of course. But, is it that we must use a C compiler that is specifically designed to work with microcontrollers or a specific architecture?

I know that different architectures have varying instruction sets that are incompatible with others, but how is this dealt with and how does all this relate to a CPU that exists in a computer?

I have surely confused topics here and possibly embarrased muself, but I have been reading on these topics for a while today and wanted to clarify everything at one to mitigate further confusion.

Thank you,

A compiler can (for the purpose of your question) be divided in two parts:

• The first part reads your code, analyzes it and checks it for errors, and does all kinds of clever things with it that have no relation with the target computer

• The second part takes the output of the first part and translates it into a sequence of machine instructions (either in textual form, or in binary form, or both).

The second part is specific for the CPU on which your program must run. If you want to run on a PIC 16F, you must have a compiler that generates machine instructions for that specific chip, and often the compiler will need to know the exact chip for which you are compiling.

For an AVR, ARM, Cortex, MIPs, etc CPU you will need a different compiler. There are compilers that contain the second part (the back-end) for more than one target. In that case you must somehow specify which of the back-ends must be used.

If I were to program a microcontroller in ASM I would use an assembler, of course. The assembler would compile the code into opcodes (machine code?)(generally 1:1 ratio) which would then be converted into HEX file.

Depends on the specific assembler. Using gas as an example, no. It creates an ELF file from source, and then objcopy is used to extract the relevant ELF sections into HEX files.

It is this file that is actually read into memory and used to program the controller?

And this one depends on the programmer. The exact file format required or possible varies from programmer to programmer.

I read that the HEX file contains the actual location the data (part of that data frame) is to be stored in memory as well as the data to be written there.

Correct.

If I were program a microcontroller in C (or some other language) what are the restrictions?

C requires the availability of a stack which requires SRAM on the target device, but if the device has enough registers and is capable enough then it is possible to craft the C compiler such that it uses the registers as a replacement for SRAM used in the stack.

It would be necessary that you use a C compiler, of course. But, is it that we must use a C compiler that is specifically designed to work with microcontrollers or a specific architecture?

The compiler must be able to generate machine code (or assembly code, if subsequent processing by an assembler is permitted/required) that is specific to the target architecture. Additionally, devices within the same architecture may have differences from each other, and the compiler can possibly be instructed to either take advantage of or ignore these differences. E.g. some AVR devices have hardware multipliers, but it is not required for the C compiler to use them, which increases binary portability among AVR devices.

• Are all of the registers available (32 for at least the Atmega32) available for use by the programmer? Or are some of the registers used by the CPU exclusively? I suppose you would have to be cognizant of the controller you are using and the compiler used because strange things would happen if you used the registers to emulate a stack and attempted to dynamically control them yourself. – sherrellbc Nov 6 '13 at 23:04
• I did not know that C requires the use of a stack. I thought it was just that the C standard requires an automatic memory allocation system (typically a stack) along with a dynamic memory allocation system (heap) - but the implementations were variable. – sherrellbc Nov 6 '13 at 23:05
• @sherrellbc: The compiler defines register availability (avr-gcc, IAR). – Ignacio Vazquez-Abrams Nov 6 '13 at 23:42
• @sherrellbc - You are correct. The target specific compiler will be designed around the nature and capabilities of the particular microcontroller in question. If the architecture efficiently supports a stack then the compiler will most likely use it in the conventional manner. There are some not so friendly architectures too. Take 8051 for example. It's use of stack for data is rather inefficient so the Keil C51 compiler uses stack for call and returns but allocates data variables from a pool of memory where they have a model like normal global variables. – Michael Karas Nov 6 '13 at 23:45
• @sherrellbc: "Are all of the registers available (32 for at least the Atmega32) available for use by the programmer?" No, in C, you're not using registers at all. You write a high level code, where you're using variables, and the compiler will allocate registers and memory storage to hold those variables. The compiler knows which registers can be used for what, and it's the optimization phase during compilation, when the compiler makes the decisions about the allocation. How good the compiler is at this, has a tremendous effect on the resulting code. – Laszlo Valko Nov 7 '13 at 0:27