With the arduino IDE assembler and C can be mixed. However, this does not give the optimization that someone is usually looking for by using assembler. For example: the "blink sketch" below, written in C will normally compile to a program that is 492 bytes long.
But, if the .o file created during this process by the IDE is converted to Assembler, tweeked a little bit, and loaded into the Arduino with avrdude. The resulting program will only be 30 bytes long, 1/16 the size ! The Arduino IDE adds a lot of overhead when compiling a sketch. With this method, the C compiler is writing the assembly language. All programs are converted to assembler ( machine code) before they are uploaded into the Arduino.
Here is an example of the sketch:
First the C sketch optimized for assembler. It is not calling any C library functions, and is programming registers directly, as someone writing in assembler would do, but it is all in Arduino C, no assembler is used.
// A blink sketch for Arduino Uno , running @ 16MHZ
// 1 second blink on Arduino pin 9 using timer1 for delay
// LED is connected to pin 9 (not pin 13). Square wave output.
void setup()
{
DDRB |= 0x02; // (0x04) Set pin PB1 (1 << DDB1) as output (pinMode(9, OUTPUT)
TCCR1A = 0x40; // (0x80) (1 << COM1A0) set Timer1 output on pin 9 to toggle mode
TCCR1B = 0x0d; // (0x81) (1 << WGM12) set TCT mode; (1 << CS10) | (1 << CS12) set prescaller to 1024
OCR1A = 7812; // (0x89) Compare value 7812 gives 1 hz - (toggle mode divides output by 2)
}
void loop()
{
}
Second: An avr-objdump of the .o object file created by the the Arduino IDE when it compiled the above sketch:
Timer1_blink.cpp.o: file format elf32-avr
Disassembly of section .text.setup:
00000000 :
0: 81 e0 ldi r24, 0x01 ; 1
2: 83 bf out 0x33, r24 ; 51
4: 21 9a sbi 0x04, 1 ; 4
6: 80 e4 ldi r24, 0x40 ; 64
8: 80 93 80 00 sts 0x0080, r24
c: 8d e0 ldi r24, 0x0D ; 13
e: 80 93 81 00 sts 0x0081, r24
12: 84 e8 ldi r24, 0x84 ; 132
14: 9e e1 ldi r25, 0x1E ; 30
16: 90 93 89 00 sts 0x0089, r25
1a: 80 93 88 00 sts 0x0088, r24
1e: 08 95 ret
Disassembly of section .text.loop:
00000000 :
0: 08 95 ret
This file has all the assembly language needed for the sketch, but needs to be tweaked before it can be assembled into a .hex file.
Here is the edited file. The ret instruction at the end of setup is removed. The ret instruction for loop has been changed to a "relative jump to the label "loop:" . Everything that is not an assembler instruction is edited or commented out.
;Timer1_blink.cpp.o: file format elf32-avr
;Disassembly of section .text.setup:
;00000000 :
ldi r24, 0x01
out 0x33, r24
sbi 0x04, 1
ldi r24, 0x40
sts 0x0080, r24
ldi r24, 0x0D
sts 0x0081, r24
ldi r24, 0x84
ldi r25, 0x1E
sts 0x0089, r25
;Disassembly of section .text.loop:
;00000000 :
loop:
rjmp loop
This file is assembled to a .hex file and uploaded with avrdude into the Arduino. (the Arduino IDE also uses avrdude to upload sketches)