Quelques infos sur le désassemblage d'un programme arduino
Il faut dans Fichier→Préférences, cocher Afficher les résultats détaillés pendant compilation ET téléversement
Question d'un étudiant sur le tdethindus1 pour calculer la valeur de l'octet d'instruction de l'EEPROM 25C040, quelle est l'écriture la plus efficace?
Processus de génération du binaire exécutable Arduino: https://github.com/arduino/Arduino/wiki/Build-Process
Emplacement du .hex généré: https://stackoverflow.com/questions/11607834/where-are-the-hex-files-compiled-by-arduino
Jeu d'instruction de l'ATMEGA328P: http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf
- test_disassembly.ino
unsigned char genere_value8(unsigned short int addr) { return ( 3 | (((addr>>8)&1)<<3)); } unsigned char genere_value8_2(unsigned short int addr) { return ( 3 | (((addr&0x100))>>5)); } unsigned short int genere_value16(unsigned short int addr) { return ( ((3 | (((addr>>8)&1)<<3))<<8) | (addr&0xff) ); } unsigned short int genere_value16_2(unsigned short int addr) { return ( ((3 | (((addr&0x100)>>5)<<8))) | (addr&0xff)); } // the setup routine runs once when you press reset: void setup() { } // the loop routine runs over and over again forever: void loop() { unsigned short int add=0; add= PINB; add|= (PINB<<8); add=(genere_value8(add)); PORTB=add>>8; PORTB=add&0xff; add= PINB; add|= (PINB<<8); add=(genere_value16(add)); PORTB=add>>8; PORTB=add&0xff; add= PINB; add|= (PINB<<8); add=(genere_value16_2(add)); PORTB=add>>8; PORTB=add&0xff; }
la compilation du sketch dans l'IDE arduino indique:
/usr/share/arduino/hardware/tools/avr/bin/avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o /tmp/build3959672033620118453.tmp/test_disassembly.cpp.elf /tmp/build3959672033620118453.tmp/test_disassembly.cpp.o /tmp/build3959672033620118453.tmp/core.a
GARDER L'IDE ARDUINO OUVERTE, sinon les fichiers temporaires sont effacés.
Pour obtenir le code désassemblé à partir du .o ou du .elf: http://forum.arduino.cc/index.php?topic=73638.0
<ARDUINOPATH>/hardware/tools/avr/bin/avr-objdump -D <BUILDPATH>/<PROJECTNAME>.cpp.elf > <PROJECTNAME>.asm
Pour désassembler tout le programme:
/usr/share/arduino/hardware/tools/avr/bin/avr-objdump -D /tmp/build3959672033620118453.tmp/test_disassembly.cpp.elf > ~/test_disassembly.cpp.asm
Pour désassembler le sketch:
/usr/share/arduino/hardware/tools/avr/bin/avr-objdump -D /tmp/build3959672033620118453.tmp/test_disassembly.cpp.o > ~/test_disassembly.cpp.asm
gedit ~/test_disassembly.cpp.asm
- test_disassembly.cpp.asm
/tmp/build3959672033620118453.tmp/test_disassembly.cpp.o: format de fichier elf32-avr Déassemblage de la section .text._Z13genere_value8t : 00000000 <_Z13genere_value8t>: 0: 91 70 andi r25, 0x01 ; 1 2: 89 2f mov r24, r25 4: 88 0f add r24, r24 6: 88 0f add r24, r24 8: 88 0f add r24, r24 a: 83 60 ori r24, 0x03 ; 3 c: 08 95 ret Déassemblage de la section .text._Z15genere_value8_2t : 00000000 <_Z15genere_value8_2t>: 0: 88 27 eor r24, r24 2: 91 70 andi r25, 0x01 ; 1 4: 25 e0 ldi r18, 0x05 ; 5 6: 96 95 lsr r25 8: 87 95 ror r24 a: 2a 95 dec r18 c: 01 f4 brne .+0 ; 0xe <_Z15genere_value8_2t+0xe> e: 83 60 ori r24, 0x03 ; 3 10: 08 95 ret Déassemblage de la section .text._Z14genere_value16t : 00000000 <_Z14genere_value16t>: 0: 9c 01 movw r18, r24 2: 95 e0 ldi r25, 0x05 ; 5 4: 36 95 lsr r19 6: 27 95 ror r18 8: 9a 95 dec r25 a: 01 f4 brne .+0 ; 0xc <_Z14genere_value16t+0xc> c: 28 70 andi r18, 0x08 ; 8 e: 33 27 eor r19, r19 10: 23 60 ori r18, 0x03 ; 3 12: 32 2f mov r19, r18 14: 22 27 eor r18, r18 16: a9 01 movw r20, r18 18: 48 2b or r20, r24 1a: ca 01 movw r24, r20 1c: 08 95 ret Déassemblage de la section .text._Z16genere_value16_2t : 00000000 <_Z16genere_value16_2t>: 0: 9c 01 movw r18, r24 2: 33 27 eor r19, r19 4: 23 60 ori r18, 0x03 ; 3 6: 88 27 eor r24, r24 8: 91 70 andi r25, 0x01 ; 1 a: 45 e0 ldi r20, 0x05 ; 5 c: 96 95 lsr r25 e: 87 95 ror r24 10: 4a 95 dec r20 12: 01 f4 brne .+0 ; 0x14 <_Z16genere_value16_2t+0x14> 14: 98 2f mov r25, r24 16: 88 27 eor r24, r24 18: 82 2b or r24, r18 1a: 93 2b or r25, r19 1c: 08 95 ret Déassemblage de la section .text.setup : 00000000 <setup>: 0: 08 95 ret Déassemblage de la section .text.loop : 00000000 <loop>: 0: 83 b1 in r24, 0x03 ; 3 2: 23 b1 in r18, 0x03 ; 3 4: 90 e0 ldi r25, 0x00 ; 0 6: 92 2b or r25, r18 8: 0e 94 00 00 call 0 ; 0x0 <loop> c: 15 b8 out 0x05, r1 ; 5 e: 85 b9 out 0x05, r24 ; 5 10: 83 b1 in r24, 0x03 ; 3 12: 23 b1 in r18, 0x03 ; 3 14: 90 e0 ldi r25, 0x00 ; 0 16: 92 2b or r25, r18 18: 0e 94 00 00 call 0 ; 0x0 <loop> 1c: 95 b9 out 0x05, r25 ; 5 1e: 85 b9 out 0x05, r24 ; 5 20: 83 b1 in r24, 0x03 ; 3 22: 23 b1 in r18, 0x03 ; 3 24: 90 e0 ldi r25, 0x00 ; 0 26: 92 2b or r25, r18 28: 0e 94 00 00 call 0 ; 0x0 <loop> 2c: 95 b9 out 0x05, r25 ; 5 2e: 85 b9 out 0x05, r24 ; 5 30: 08 95 ret
remarque concernant le décalage à gauche
L'opération de décalage a gauche (LSL page 120 de http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf ) se fait en pratique grace à Add Rd,Rd qui multiplie Rd par 2 (page 32) .