On va étudier ici l’assembleur du ATMEGA328P à 16MHz, on va découvrir ici quelques mnémoniques:
- sbi : set bit , 1 cycle d’horloge
- cbi : clear bit , 1 cycle d’horloge
- rjmp : saut relatif , 2 cycles d’horloge
- jmp : jump (saut) , 3 cycles d’horloge
- nop ; non opération , un cycle d’horloge
void setup() {
// Configure la broche 10 (PORTB2) en sortie
DDRB |= (1 << PB2);
}
void loop() {
// Boucle en assembleur pour basculer la broche 10
asm volatile (
"sbi %[port], %[bit] \n\t" // Met la broche à HIGH (1 cycle)
"cbi %[port], %[bit] \n\t" // Met la broche à LOW (1 cycle)
"rjmp .-4 \n\t" // Saute en arrière de 2 instructions (2 cycles)
:
: [port] "I" (_SFR_IO_ADDR(PORTB)), [bit] "I" (PB2)
);
}
plus lisible ! on retrouve les addresses DDRB dans me datasheet de l’ATMEGA328P
void setup() {
// L'adresse I/O de DDRB est 0x04
// On veut le bit 2 (valeur = 1 << 2 = 4)
asm volatile (
"ldi r24, 4 \n\t" // Valeur à écrire dans DDRB
"out 0x04, r24 \n\t" // DDRB = 0x04
);
}
void loop() {
asm volatile (
"start: \n\t"
"sbi 0x05, 2 \n\t" // PORTB.2 = 1
"cbi 0x05, 2 \n\t" // PORTB.2 = 0
"jmp start \n\t" // Boucle
);
}
Les adresses I/O importantes (ATmega328P)
| Registre | Adresse I/O | Description |
|---|---|---|
| DDRB | 0x04 | Data Direction Register B |
| PORTB | 0x05 | Data Register B (sortie) |
| PINB | 0x03 | Input Pins Address B (entrée) |
| DDRD | 0x0A | Port D Direction |
| PORTD | 0x0B | Port D Data |
void setup() {
// L'adresse I/O de DDRB est 0x04
// On veut le bit 2 (valeur = 1 << 2 = 4)
asm volatile (
"ldi r24, 4 \n\t" // Valeur à écrire dans DDRB
"out 0x04, r24 \n\t" // DDRB = 0x04
);
}
void loop() {
asm volatile (
"start: \n\t"
"sbi 0x05, 2 \n\t" // PORTB.2 = 1
"nop \n\t"
"nop \n\t"
"nop \n\t"
"cbi 0x05, 2 \n\t" // PORTB.2 = 0
"jmp start \n\t" // Boucle
);
}

setup()
ldi r24, 4 ; 1 cycle (Load Immediate)
out 0x04, r24 ; 1 cycle (Output to I/O)
; TOTAL setup: 2 cycles = 125 ns
loop()
start:
sbi 0x05, 2 ; 2 cycles (Set Bit I/O)
nop ; 1 cycle (No Operation)
nop ; 1 cycle (No Operation)
nop ; 1 cycle (No Operation)
cbi 0x05, 2 ; 2 cycles (Clear Bit I/O)
jmp start ; 3 cycles (Jump)
; TOTAL loop: 10 cycles = 625 ns
Timing détaillé (16 MHz Arduino) :
| Instruction | Cycles | Durée (ns) | Temps cumulé (ns) | État broche |
|---|---|---|---|---|
sbi 0x05,2 | 2 | 125 | 125 | HIGH |
nop | 1 | 62.5 | 187.5 | HIGH |
nop | 1 | 62.5 | 250.0 | HIGH |
nop | 1 | 62.5 | 312.5 | HIGH |
cbi 0x05,2 | 2 | 125 | 437.5 | LOW |
jmp start | 3 | 187.5 | 625.0 | LOW |
Retour à sbi | – | – | 625.0 | LOW |
Langage Machine a gauche et Assembleur AVR à droite
; Toutes les versions produisent : 9A 25 ; sbi 0x05, 2 00 00 00 ; nop nop nop 98 25 ; cbi 0x05, 2 0C 94 00 00 ; jmp start (adresse relative)
