Disassembliamo?

Oggi mi sono divertito a disassemblare lo sketch Blink compilato per Atmega328P.
Questo è il programma in linguaggio macchina che viene spedito al microcontrollore:

   0:	jmp 0x061
   4:	jmp 0x073
   8:	jmp 0x073
   C:	jmp 0x073
  10:	jmp 0x073
  14:	jmp 0x073
  18:	jmp 0x073
  1C:	jmp 0x073
  20:	jmp 0x073
  24:	jmp 0x073
  28:	jmp 0x073
  2C:	jmp 0x073
  30:	jmp 0x073
  34:	jmp 0x073
  38:	jmp 0x073
  3C:	jmp 0x073
  40:	jmp 0x08F
  44:	jmp 0x073
  48:	jmp 0x073
  4C:	jmp 0x073
  50:	jmp 0x073
  54:	jmp 0x073
  58:	jmp 0x073
  5C:	jmp 0x073
  60:	jmp 0x073
  64:	jmp 0x073
  68:	nop 
  6A:	nop 
  6C:	.DW 0x024
  6E:	.DW 0x027
  70:	.DW 0x02A
  72:	nop 
  74:	nop 
  76:	.DW 0x025
  78:	.DW 0x028
  7A:	.DW 0x02B
  7C:	nop 
  7E:	nop 
  80:	.DW 0x023
  82:	.DW 0x026
  84:	.DW 0x029
  86:	cpc R0, R4
  88:	cpc R0, R4
  8A:	cpc R0, R4
  8C:	cpc R0, R4
  8E:	muls R16, R18
  90:	muls R16, R18
  92:	muls R16, R18
  94:	mulsu R16, R19
  96:	mulsu R16, R19
  98:	mulsu R16, R19
  9A:	muls R16, R17
  9C:	sbc R0, R4
  9E:	and R1, R0
  A0:	ld R4, Z
  A2:	muls R16, R17
  A4:	sbc R0, R4
  A6:	and R1, R0
  A8:	muls R16, R17
  AA:	sbc R0, R4
  AC:	and R1, R0
  AE:	nop 
  B0:	cpc R16, R16
  B2:	muls R16, R16
  B4:	.DW 0x001
  B6:	mulsu R16, R16
  B8:	cpc R0, R20
  BA:	nop 
  BC:	nop 
  BE:	nop 
  C0:	nop 
  C2:	clr R1
  C4:	out $3F, R1
  C6:	ser R28
  C8:	ldi R29, 0x08
  CA:	out $3E, R29
  CC:	out $3D, R28
  CE:	ldi R17, 0x01
  D0:	ldi R26, 0x00
  D2:	ldi R27, 0x01
  D4:	rjmp .+2 	; 0xD8
  D6:	st X+, R1
  D8:	cpi R26, 0x0F
  DA:	cpc R27, R17
  DC:	brne .-8 	; 0xD6
  DE:	call 0x212
  E2:	jmp 0x219
  E6:	jmp 0x000
  EA:	ldi R24, 0x0D
  EC:	ldi R22, 0x01
  EE:	call 0x1B4
  F2:	ret 
  F4:	ldi R24, 0x0D
  F6:	ldi R22, 0x01
  F8:	call 0x1D8
  FC:	ldi R22, 0xE8
  FE:	ldi R23, 0x03
 100:	ldi R24, 0x00
 102:	ldi R25, 0x00
 104:	call 0x125
 108:	ldi R24, 0x0D
 10A:	ldi R22, 0x00
 10C:	call 0x1D8
 110:	ldi R22, 0xE8
 112:	ldi R23, 0x03
 114:	ldi R24, 0x00
 116:	ldi R25, 0x00
 118:	call 0x125
 11C:	ret 
 11E:	push R1
 120:	push R0
 122:	in R0, 0x3F
 124:	push R0
 126:	clr R1
 128:	push R18
 12A:	push R19
 12C:	push R24
 12E:	push R25
 130:	push R26
 132:	push R27
 134:	lds R24, 0x104
 138:	lds R25, 0x105
 13C:	lds R26, 0x106
 140:	lds R27, 0x107
 144:	lds R19, 0x10E
 148:	adiw R24, 0x01
 14A:	adc R26, R1
 14C:	adc R27, R1
 14E:	mov R18, R19
 150:	subi R18, 0xFD
 152:	cpi R18, 0x7D
 154:	brcs .+8 	; 0x15E
 156:	subi R18, 0x7D
 158:	adiw R24, 0x01
 15A:	adc R26, R1
 15C:	adc R27, R1
 15E:	sts 0x10E, R18
 162:	sts 0x104, R24
 166:	sts 0x105, R25
 16A:	sts 0x106, R26
 16E:	sts 0x107, R27
 172:	lds R24, 0x100
 176:	lds R25, 0x101
 17A:	lds R26, 0x102
 17E:	lds R27, 0x103
 182:	adiw R24, 0x01
 184:	adc R26, R1
 186:	adc R27, R1
 188:	sts 0x100, R24
 18C:	sts 0x101, R25
 190:	sts 0x102, R26
 194:	sts 0x103, R27
 198:	lds R24, 0x10C
 19C:	lds R25, 0x10D
 1A0:	adiw R24, 0x01
 1A2:	sts 0x10D, R25
 1A6:	sts 0x10C, R24
 1AA:	lds R24, 0x10C
 1AE:	lds R25, 0x10D
 1B2:	ldi R18, 0x03
 1B4:	cpi R24, 0xD1
 1B6:	cpc R25, R18
 1B8:	brcs .+46 	; 0x1E8
 1BA:	lds R24, 0x108
 1BE:	lds R25, 0x109
 1C2:	lds R26, 0x10A
 1C6:	lds R27, 0x10B
 1CA:	adiw R24, 0x01
 1CC:	adc R26, R1
 1CE:	adc R27, R1
 1D0:	sts 0x108, R24
 1D4:	sts 0x109, R25
 1D8:	sts 0x10A, R26
 1DC:	sts 0x10B, R27
 1E0:	sts 0x10D, R1
 1E4:	sts 0x10C, R1
 1E8:	pop R27
 1EA:	pop R26
 1EC:	pop R25
 1EE:	pop R24
 1F0:	pop R19
 1F2:	pop R18
 1F4:	pop R0
 1F6:	out $3F, R0
 1F8:	pop R0
 1FA:	pop R1
 1FC:	reti 
 1FE:	in R25, 0x3F
 200:	cli 
 202:	lds R18, 0x100
 206:	lds R19, 0x101
 20A:	lds R20, 0x102
 20E:	lds R21, 0x103
 212:	in R24, 0x26
 214:	sbis $15, 0
 216:	rjmp .+12 	; 0x224
 218:	cpi R24, 0xFF
 21A:	breq .+8 	; 0x224
 21C:	subi R18, 0xFF
 21E:	sbci R19, 0xFF
 220:	sbci R20, 0xFF
 222:	sbci R21, 0xFF
 224:	out $3F, R25
 226:	mov R21, R20
 228:	mov R20, R19
 22A:	mov R19, R18
 22C:	clr R18
 22E:	add R18, R24
 230:	adc R19, R1
 232:	adc R20, R1
 234:	adc R21, R1
 236:	ldi R24, 0x02
 238:	lsl R18
 23A:	rol R19
 23C:	rol R20
 23E:	rol R21
 240:	dec R24
 242:	brne .-12 	; 0x238
 244:	movw R22, R18
 246:	movw R24, R20
 248:	ret 
 24A:	push R14
 24C:	push R15
 24E:	push R16
 250:	push R17
 252:	push R28
 254:	push R29
 256:	movw R14, R22
 258:	movw R16, R24
 25A:	call 0x0FF
 25E:	movw R28, R22
 260:	rjmp .+30 	; 0x280
 262:	call 0x0FF
 266:	sub R22, R28
 268:	sbc R23, R29
 26A:	ldi R24, 0x03
 26C:	cpi R22, 0xE8
 26E:	cpc R23, R24
 270:	brcs .+14 	; 0x280
 272:	sec 
 274:	sbc R14, R1
 276:	sbc R15, R1
 278:	sbc R16, R1
 27A:	sbc R17, R1
 27C:	subi R28, 0x18
 27E:	sbci R29, 0xFC
 280:	cp R14, R1
 282:	cpc R15, R1
 284:	cpc R16, R1
 286:	cpc R17, R1
 288:	brne .-40 	; 0x262
 28A:	pop R29
 28C:	pop R28
 28E:	pop R17
 290:	pop R16
 292:	pop R15
 294:	pop R14
 296:	ret 
 298:	sei 
 29A:	in R24, 0x24
 29C:	ori R24, 0x02
 29E:	out $24, R24
 2A0:	in R24, 0x24
 2A2:	ori R24, 0x01
 2A4:	out $24, R24
 2A6:	in R24, 0x25
 2A8:	ori R24, 0x02
 2AA:	out $25, R24
 2AC:	in R24, 0x25
 2AE:	ori R24, 0x01
 2B0:	out $25, R24
 2B2:	ldi R30, 0x6E
 2B4:	ldi R31, 0x00
 2B6:	ld R24, Z
 2B8:	ori R24, 0x01
 2BA:	st Z, R24
 2BC:	ldi R30, 0x81
 2BE:	ldi R31, 0x00
 2C0:	st Z, R1
 2C2:	ld R24, Z
 2C4:	ori R24, 0x02
 2C6:	st Z, R24
 2C8:	ld R24, Z
 2CA:	ori R24, 0x01
 2CC:	st Z, R24
 2CE:	ldi R30, 0x80
 2D0:	ldi R31, 0x00
 2D2:	ld R24, Z
 2D4:	ori R24, 0x01
 2D6:	st Z, R24
 2D8:	ldi R30, 0xB1
 2DA:	ldi R31, 0x00
 2DC:	ld R24, Z
 2DE:	ori R24, 0x04
 2E0:	st Z, R24
 2E2:	ldi R30, 0xB0
 2E4:	ldi R31, 0x00
 2E6:	ld R24, Z
 2E8:	ori R24, 0x01
 2EA:	st Z, R24
 2EC:	ldi R30, 0x7A
 2EE:	ldi R31, 0x00
 2F0:	ld R24, Z
 2F2:	ori R24, 0x04
 2F4:	st Z, R24
 2F6:	ld R24, Z
 2F8:	ori R24, 0x02
 2FA:	st Z, R24
 2FC:	ld R24, Z
 2FE:	ori R24, 0x01
 300:	st Z, R24
 302:	ld R24, Z
 304:	ori R24, 0x80
 306:	st Z, R24
 308:	sts 0x0C1, R1
 30C:	ret 
 30E:	cpi R24, 0x03
 310:	breq .+28 	; 0x32E
 312:	cpi R24, 0x04
 314:	brcc .+10 	; 0x320
 316:	cpi R24, 0x01
 318:	breq .+40 	; 0x342
 31A:	cpi R24, 0x02
 31C:	brne .+72 	; 0x366
 31E:	rjmp .+40 	; 0x348
 320:	cpi R24, 0x06
 322:	breq .+44 	; 0x350
 324:	cpi R24, 0x07
 326:	breq .+52 	; 0x35C
 328:	cpi R24, 0x04
 32A:	brne .+58 	; 0x366
 32C:	rjmp .+8 	; 0x336
 32E:	lds R24, 0x080
 332:	andi R24, 0x7F
 334:	rjmp .+6 	; 0x33C
 336:	lds R24, 0x080
 33A:	andi R24, 0xDF
 33C:	sts 0x080, R24
 340:	ret 
 342:	in R24, 0x24
 344:	andi R24, 0x7F
 346:	rjmp .+4 	; 0x34C
 348:	in R24, 0x24
 34A:	andi R24, 0xDF
 34C:	out $24, R24
 34E:	ret 
 350:	lds R24, 0x0B0
 354:	andi R24, 0x7F
 356:	sts 0x0B0, R24
 35A:	ret 
 35C:	lds R24, 0x0B0
 360:	andi R24, 0xDF
 362:	sts 0x0B0, R24
 366:	ret 
 368:	ldi R25, 0x00
 36A:	movw R30, R24
 36C:	subi R30, 0x66
 36E:	sbci R31, 0xFF
 370:	lpm R18, Z
 372:	movw R30, R24
 374:	subi R30, 0x7A
 376:	sbci R31, 0xFF
 378:	lpm R30, Z
 37A:	tst R30
 37C:	breq .+48 	; 0x3AE
 37E:	ldi R31, 0x00
 380:	lsl R30
 382:	rol R31
 384:	subi R30, 0x98
 386:	sbci R31, 0xFF
 388:	lpm R24, Z+
 38A:	lpm R25, Z
 38C:	movw R26, R24
 38E:	tst R22
 390:	brne .+16 	; 0x3A2
 392:	in R25, 0x3F
 394:	cli 
 396:	ld R24, X
 398:	com R18
 39A:	and R24, R18
 39C:	st X, R24
 39E:	out $3F, R25
 3A0:	ret 
 3A2:	in R25, 0x3F
 3A4:	cli 
 3A6:	ld R24, X
 3A8:	or R24, R18
 3AA:	st X, R24
 3AC:	out $3F, R25
 3AE:	ret 
 3B0:	push R16
 3B2:	push R17
 3B4:	push R29
 3B6:	push R28
 3B8:	push R0
 3BA:	in R28, 0x3D
 3BC:	in R29, 0x3E
 3BE:	mov R18, R24
 3C0:	ldi R19, 0x00
 3C2:	movw R30, R18
 3C4:	subi R30, 0x52
 3C6:	sbci R31, 0xFF
 3C8:	lpm R24, Z
 3CA:	movw R30, R18
 3CC:	subi R30, 0x66
 3CE:	sbci R31, 0xFF
 3D0:	lpm R17, Z
 3D2:	subi R18, 0x7A
 3D4:	sbci R19, 0xFF
 3D6:	movw R30, R18
 3D8:	lpm R16, Z
 3DA:	tst R16
 3DC:	breq .+58 	; 0x418
 3DE:	tst R24
 3E0:	breq .+8 	; 0x3EA
 3E2:	std Y+1, R22
 3E4:	call 0x187
 3E8:	ldd R22, Y+1
 3EA:	mov R30, R16
 3EC:	ldi R31, 0x00
 3EE:	lsl R30
 3F0:	rol R31
 3F2:	subi R30, 0x8E
 3F4:	sbci R31, 0xFF
 3F6:	lpm R24, Z+
 3F8:	lpm R25, Z
 3FA:	movw R26, R24
 3FC:	tst R22
 3FE:	brne .+12 	; 0x40C
 400:	in R25, 0x3F
 402:	cli 
 404:	ld R24, X
 406:	com R17
 408:	and R24, R17
 40A:	rjmp .+8 	; 0x414
 40C:	in R25, 0x3F
 40E:	cli 
 410:	ld R24, X
 412:	or R24, R17
 414:	st X, R24
 416:	out $3F, R25
 418:	pop R0
 41A:	pop R28
 41C:	pop R29
 41E:	pop R17
 420:	pop R16
 422:	ret 
 424:	call 0x14C
 428:	call 0x075
 42C:	call 0x07A
 430:	rjmp .-6 	; 0x42C
 432:	cli 
 434:	rjmp .-2 	; 0x434

Buffo, vero? Uno sketch di neanche 10 righe in C diventa lunghettino in linguaggio macchina :sweat_smile:

come l'hai decompilato? hai semplicemente aperto l'hex?

Le prime istruzioni mi ricordano "Jump" dei Van Halen, oppure anche salta salta salta salta salta sin parar. :grin: :grin:

leo72:
Buffo, vero? Uno sketch di neanche 10 righe in C diventa lunghettino in linguaggio macchina :sweat_smile:

Non dimenticare che a quelle poche righe viene aggiunto il main.c e tutte le librerie del caso.

E lo potresti riconvertire in sketch?

PaoloP:
Le prime istruzioni mi ricordano "Jump" dei Van Halen, oppure anche salta salta salta salta salta sin parar. :grin: :grin:

In realtà quella serie di jmp altro non è che il vettore di interrupt, ovvero sono i salti diretti alle varie isr se presenti.

pablos:
E lo potresti riconvertire in sketch?

Non esiste nessun modo per convertire un programma in assembly in uno sketch.

astrobeed:

PaoloP:
Le prime istruzioni mi ricordano "Jump" dei Van Halen, oppure anche salta salta salta salta salta sin parar. :grin: :grin:

In realtà quella serie di jmp altro non è che il vettore di interrupt, ovvero sono i salti diretti alle varie isr se presenti.

non ci avevo pensato, questo spiega perchè tutte quelle jump con lo stesso indirizzo :slight_smile:

lesto:
come l'hai decompilato? hai semplicemente aperto l'hex?

No, ho usato un softwarino che fa solo il disassemblatore. Cerca in Arch vavrdisasm (lo trovi in AUR, se hai yaourt lo installi velocemente).
Ho compilato lo sketch e poi ho disassemblato l'hex che il compilatore crea in /tmp/buildxxxxxxxxxx.

Alle altre domande ha già risposto astrobeed.

Uno sketch di neanche 10 righe in C diventa lunghettino in linguaggio macchina

Alcune volte però, può succedere anche il contrario :slight_smile:

Se parliamo di tutto quello che Arduino aggiunge allo sketch, allora posso darti benissimo ragione. XD

Il programma in linguaggio macchina deve inizializzare tutto e poi fa le 10 righe di C. Prova una volta di aggiungere alle 10 righe di C tutte le fiunzioni che vengono chiamate e aggiunte in automatico.
Ciao Uwe

Se parliamo di tutto quello che Arduino aggiunge allo sketch, allora posso darti benissimo ragione.

Vero, ma ci sono casi nei quali la semplice programmazione in assembly riesce ad essere più corta (in termini di numero di istruzioni scritte) rispetto al suo corrispondente ad alto livello. Pensa solo a certi tipi di aritmetica in base due per il calcolo di puntatori che usano spesso moltiplicazioni/divisioni per 2, che vengono svolte semplicemente facendo ROL o ROR (rolling), che insieme a istruzioni di branch (e non "jump") possono realizzare cicli efficientissimi di poche istruzioni...ma ora che ci penso, che te le dico a fare ste cose? Sto parlando con uno che disassemblava i giochi del commodore a 14 anni... :smiley:

dalubar:
ma ora che ci penso, che te le dico a fare ste cose? Sto parlando con uno che disassemblava i giochi del commodore a 14 anni... :smiley:

Ah ah ah
Te lo ricordi XD

L'assembly è stato il mio primo linguaggio "serio" (dopo il BASIC Commodore). Mi piaceva perché grazie ad esso potevo spremere tutto, ma proprio TUTTO, dal mio C16. Grazie ad esso la velocità di esecuzione aumentava di decine/centinaia di volte rispetto al BASIC e si potevano manipolare direttamente i registri del TED (il chip deputato alla gestione dell'audio e del video) per fargli fare cose impensabili in Basic, come ad esempio effetti arcobaleno sull'overscan dell'immagine (il "bordo" laterale). Oppure virus infilati nella routine di interrupt del computer... bei tempi :sweat_smile:

Oppure virus infilati nella routine di interrupt del computer... bei tempi

Abbiamo in comune il "primo amore" per l'assembly del 6502/6510... il mio commodore 64 suonava melodie con effetti speciali mentre faceva tutt'altro grazie a interrupt e SID...ora che ci penso qualche mese fa ho fatto la stessa cosa su un ATtiny84, impiegando i 2 timer per generare effetti "speciali" sulle note...magari un giorno lo pubblico. :slight_smile:

dalubar:

Oppure virus infilati nella routine di interrupt del computer... bei tempi

Abbiamo in comune il "primo amore" per l'assembly del 6502/6510... il mio commodore 64 suonava melodie con effetti speciali mentre faceva tutt'altro grazie a interrupt e SID...ora che ci penso qualche mese fa ho fatto la stessa cosa su un ATtiny84, impiegando i 2 timer per generare effetti "speciali" sulle note...magari un giorno lo pubblico. :slight_smile:

DEVI pubblicarlo! Altrimenti che mano diamo all'opensource :wink:

interessante il blink visto cosi',
pensare che ci sia gente che vedendo quella sequenza di numeri e lettere riesca a capire anche cosa significhino mi fa impazzire :slight_smile:

Testato:
interessante il blink visto cosi',
pensare che ci sia gente che vedendo quella sequenza di numeri e lettere riesca a capire anche cosa significhino mi fa impazzire :slight_smile:

Devi solo imparare i codici mnemonici, i registri e gli indirizzi. Alla fine, leggere un "ldi R24, 0x0D" oppure un a=13 è la stessa cosa.

0x0D ci siamo, gli altri due da dove escono ? :slight_smile:

Un registro è come una variabile, ho messo "a" tanto per mettere un carattere qualsiasi :stuck_out_tongue: