AVR: desensamblador con soporte de registro llamado

3

¿Hay un desensamblador AVR que produce una salida legible para el ser humano, por ejemplo, escribe

OUT       SREG,R0 

en lugar de

OUT       0x3F,R0

(Me gustaría comprender mejor lo que está haciendo el compilador)

    
pregunta Mike L.

3 respuestas

2

Lamento revivir este hilo, pero me he preguntado algunas veces cómo podría tener avr-objdump de salida de nombres de registro adecuados. Descubrí que es inútil. ¿O es eso? ¡No para un amante de los pitones, por supuesto!

Esa es la razón de este script, que básicamente es un contenedor / post-procesador para avr-objdump . Actualmente está limitado a unas pocas arquitecturas, a saber, avr35 y avr5 esencialmente porque usé esos 3 procesadores: ATmega64M1 , ATmega328 (Arduino) y ATtiny1634 . Hay espacio para mejorar, como hacer que la lista de registro esté disponible en módulos, pero esto abre el camino.

La invocación de la línea de comandos es tan simple como esto:

adump.py <MCUNAME> <avr-objdump arguments>

Ejemplos:

adump.py atmega328 -S main.flash.hex

Si tiene la imagen flash binaria sin procesar que ha descargado de una pizarra:

adump.py atmega328 -D -b binary main.flash.bin

Aquí está la salida para una imagen flash recuperada de un programa simple de parpadeo escrito para el ATmega64M1:

$ adump.py atmega64m1 -D -b binary blink-m64m1.bin

...
00000000 <.data>:
   0:   0c 94 3e 00     jmp 0x7c    ;  0x7c
   4:   0c 94 48 00     jmp 0x90    ;  0x90
   8:   0c 94 48 00     jmp 0x90    ;  0x90
   c:   0c 94 48 00     jmp 0x90    ;  0x90
  10:   0c 94 48 00     jmp 0x90    ;  0x90
  14:   0c 94 48 00     jmp 0x90    ;  0x90
  18:   0c 94 48 00     jmp 0x90    ;  0x90
  1c:   0c 94 48 00     jmp 0x90    ;  0x90
  20:   0c 94 48 00     jmp 0x90    ;  0x90
  24:   0c 94 48 00     jmp 0x90    ;  0x90
  28:   0c 94 48 00     jmp 0x90    ;  0x90
  2c:   0c 94 48 00     jmp 0x90    ;  0x90
  30:   0c 94 48 00     jmp 0x90    ;  0x90
  34:   0c 94 48 00     jmp 0x90    ;  0x90
  38:   0c 94 48 00     jmp 0x90    ;  0x90
  3c:   0c 94 48 00     jmp 0x90    ;  0x90
  40:   0c 94 48 00     jmp 0x90    ;  0x90
  44:   0c 94 48 00     jmp 0x90    ;  0x90
  48:   0c 94 48 00     jmp 0x90    ;  0x90
  4c:   0c 94 48 00     jmp 0x90    ;  0x90
  50:   0c 94 48 00     jmp 0x90    ;  0x90
  54:   0c 94 48 00     jmp 0x90    ;  0x90
  58:   0c 94 48 00     jmp 0x90    ;  0x90
  5c:   0c 94 48 00     jmp 0x90    ;  0x90
  60:   0c 94 48 00     jmp 0x90    ;  0x90
  64:   0c 94 48 00     jmp 0x90    ;  0x90
  68:   0c 94 48 00     jmp 0x90    ;  0x90
  6c:   0c 94 48 00     jmp 0x90    ;  0x90
  70:   0c 94 48 00     jmp 0x90    ;  0x90
  74:   0c 94 48 00     jmp 0x90    ;  0x90
  78:   0c 94 48 00     jmp 0x90    ;  0x90
  7c:   11 24           eor r1, r1
  7e:   1f be           out SREG, r1    ; 63
  80:   cf ef           ldi r28, 0xFF   ; 255
  82:   d0 e1           ldi r29, 0x10   ; 16
  84:   de bf           out SPH, r29    ; 62
  86:   cd bf           out SPL, r28    ; 61
  88:   0e 94 4a 00     call    0x94    ;  0x94
  8c:   0c 94 5a 00     jmp 0xb4    ;  0xb4
  90:   0c 94 00 00     jmp 0   ;  0x0
  94:   82 e0           ldi r24, 0x02   ; 2
  96:   8a b9           out DDRD, r24   ; 10
  98:   92 e0           ldi r25, 0x02   ; 2
  9a:   8b b1           in  r24, PORTD  ; 11
  9c:   89 27           eor r24, r25
  9e:   8b b9           out PORTD, r24  ; 11
  a0:   2f e3           ldi r18, 0x3F   ; 63
  a2:   3d e0           ldi r19, 0x0D   ; 13
  a4:   83 e0           ldi r24, 0x03   ; 3
  a6:   21 50           subi    r18, 0x01   ; 1
  a8:   30 40           sbci    r19, 0x00   ; 0
  aa:   80 40           sbci    r24, 0x00   ; 0
  ac:   e1 f7           brne    .-8         ;  0xa6
  ae:   00 c0           rjmp    .+0         ;  0xb0
  b0:   00 00           nop
  b2:   f3 cf           rjmp    .-26        ;  0x9a
  b4:   f8 94           cli
  b6:   ff cf           rjmp    .-2         ;  0xb6

Ahora aquí está el script, con la esperanza de que aún sea útil:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  adump.py
#
#  Copyright 2017 Nasha
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.

from __future__ import print_function
import sys

def report(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

arches = {
    # List of supported architectures.
    # See http://www.atmel.com/webdoc/AVRLibcReferenceManual/using_tools_1using_avr_gcc_mach_opt.html
    # for updates
    "at90s1200": "avr1",
    "attiny11": "avr1",
    "attiny12": "avr1",
    "attiny15": "avr1",
    "attiny28": "avr1",
    "at90s2313": "avr2",
    "at90s2323": "avr2",
    "at90s2333": "avr2",
    "at90s2343": "avr2",
    "attiny22": "avr2",
    "attiny26": "avr2",
    "at90s4414": "avr2",
    "at90s4433": "avr2",
    "at90s4434": "avr2",
    "at90s8515": "avr2",
    "at90c8534": "avr2",
    "at90s8535": "avr2",
    "at86rf401": "avr25",
    "ata6289": "avr25",
    "ata5272": "avr25",
    "ata6616c": "avr25",
    "attiny13": "avr25",
    "attiny13a": "avr25",
    "attiny2313": "avr25",
    "attiny2313a": "avr25",
    "attiny24": "avr25",
    "attiny24a": "avr25",
    "attiny25": "avr25",
    "attiny261": "avr25",
    "attiny261a": "avr25",
    "attiny4313": "avr25",
    "attiny43u": "avr25",
    "attiny44": "avr25",
    "attiny44a": "avr25",
    "attiny441": "avr25",
    "attiny45": "avr25",
    "attiny461": "avr25",
    "attiny461a": "avr25",
    "attiny48": "avr25",
    "attiny828": "avr25",
    "attiny84": "avr25",
    "attiny84a": "avr25",
    "attiny841": "avr25",
    "attiny85": "avr25",
    "attiny861": "avr25",
    "attiny861a": "avr25",
    "attiny87": "avr25",
    "attiny88": "avr25",
    "atmega603": "avr3",
    "at43usb355": "avr3",
    "atmega103": "avr31",
    "at43usb320": "avr31",
    "at90usb82": "avr35",
    "at90usb162": "avr35",
    "ata5505": "avr35",
    "ata6617c": "avr35",
    "ata664251": "avr35",
    "atmega8u2": "avr35",
    "atmega16u2": "avr35",
    "atmega32u2": "avr35",
    "attiny167": "avr35",
    "attiny1634": "avr35",
    "at76c711": "avr3",
    "ata6285": "avr4",
    "ata6286": "avr4",
    "ata6612c": "avr4",
    "atmega48": "avr4",
    "atmega48a": "avr4",
    "atmega48pa": "avr4",
    "atmega48p": "avr4",
    "atmega8": "avr4",
    "atmega8a": "avr4",
    "atmega8515": "avr4",
    "atmega8535": "avr4",
    "atmega88": "avr4",
    "atmega88a": "avr4",
    "atmega88p": "avr4",
    "atmega88pa": "avr4",
    "atmega8hva": "avr4",
    "at90pwm1": "avr4",
    "at90pwm2": "avr4",
    "at90pwm2b": "avr4",
    "at90pwm3": "avr4",
    "at90pwm3b": "avr4",
    "at90pwm81": "avr4",
    "at90can32": "avr5",
    "at90can64": "avr5",
    "at90pwm161": "avr5",
    "at90pwm216": "avr5",
    "at90pwm316": "avr5",
    "at90scr100": "avr5",
    "at90usb646": "avr5",
    "at90usb647": "avr5",
    "at94k": "avr5",
    "atmega16": "avr5",
    "ata5790": "avr5",
    "ata5702m322": "avr5",
    "ata5782": "avr5",
    "ata6613c": "avr5",
    "ata6614q": "avr5",
    "ata5790n": "avr5",
    "ata5795": "avr5",
    "ata5831": "avr5",
    "atmega161": "avr5",
    "atmega162": "avr5",
    "atmega163": "avr5",
    "atmega164a": "avr5",
    "atmega164p": "avr5",
    "atmega164pa": "avr5",
    "atmega165": "avr5",
    "atmega165a": "avr5",
    "atmega165p": "avr5",
    "atmega165pa": "avr5",
    "atmega168": "avr5",
    "atmega168a": "avr5",
    "atmega168p": "avr5",
    "atmega168pa": "avr5",
    "atmega169": "avr5",
    "atmega169a": "avr5",
    "atmega169p": "avr5",
    "atmega169pa": "avr5",
    "atmega16a": "avr5",
    "atmega16hva": "avr5",
    "atmega16hva2": "avr5",
    "atmega16hvb": "avr5",
    "atmega16hvbrevb": "avr5",
    "atmega16m1": "avr5",
    "atmega16u4": "avr5",
    "atmega32": "avr5",
    "atmega32a": "avr5",
    "atmega323": "avr5",
    "atmega324a": "avr5",
    "atmega324p": "avr5",
    "atmega324pa": "avr5",
    "atmega325": "avr5",
    "atmega325a": "avr5",
    "atmega325p": "avr5",
    "atmega325pa": "avr5",
    "atmega3250": "avr5",
    "atmega3250a": "avr5",
    "atmega3250p": "avr5",
    "atmega3250pa": "avr5",
    "atmega328": "avr5",
    "atmega328p": "avr5",
    "atmega329": "avr5",
    "atmega329a": "avr5",
    "atmega329p": "avr5",
    "atmega329pa": "avr5",
    "atmega3290": "avr5",
    "atmega3290a": "avr5",
    "atmega3290p": "avr5",
    "atmega3290pa": "avr5",
    "atmega32c1": "avr5",
    "atmega32hvb": "avr5",
    "atmega32hvbrevb": "avr5",
    "atmega32m1": "avr5",
    "atmega32u4": "avr5",
    "atmega32u6": "avr5",
    "atmega406": "avr5",
    "atmega64rfr2": "avr5",
    "atmega644rfr2": "avr5",
    "atmega64": "avr5",
    "atmega64a": "avr5",
    "atmega640": "avr5",
    "atmega644": "avr5",
    "atmega644a": "avr5",
    "atmega644p": "avr5",
    "atmega644pa": "avr5",
    "atmega645": "avr5",
    "atmega645a": "avr5",
    "atmega645p": "avr5",
    "atmega6450": "avr5",
    "atmega6450a": "avr5",
    "atmega6450p": "avr5",
    "atmega649": "avr5",
    "atmega649a": "avr5",
    "atmega6490": "avr5",
    "atmega6490a": "avr5",
    "atmega6490p": "avr5",
    "atmega649p": "avr5",
    "atmega64c1": "avr5",
    "atmega64hve": "avr5",
    "atmega64hve2": "avr5",
    "atmega64m1": "avr5",
    "m3000": "avr5",
    "at90can128": "avr51",
    "at90usb1286": "avr51",
    "at90usb1287": "avr51",
    "atmega128": "avr51",
    "atmega128a": "avr51",
    "atmega1280": "avr51",
    "atmega1281": "avr51",
    "atmega1284": "avr51",
    "atmega1284p": "avr51",
    "atmega128rfr2": "avr51",
    "atmega1284rfr2": "avr51",
    "atmega2560": "avr6",
    "atmega2561": "avr6",
    "atmega256rfr2": "avr6",
    "atmega2564rfr2": "avr6",
    "atxmega16a4": "avrxmega2",
    "atxmega16a4u": "avrxmega2",
    "atxmega16c4": "avrxmega2",
    "atxmega16d4": "avrxmega2",
    "atxmega32a4": "avrxmega2",
    "atxmega32a4u": "avrxmega2",
    "atxmega32c3": "avrxmega2",
    "atxmega32c4": "avrxmega2",
    "atxmega32d3": "avrxmega2",
    "atxmega32d4": "avrxmega2",
    "atxmega8e5": "avrxmega2",
    "atxmega16e5": "avrxmega2",
    "atxmega32e5": "avrxmega2",
    "atxmega64a3": "avrxmega4",
    "atxmega64a3u": "avrxmega4",
    "atxmega64a4u": "avrxmega4",
    "atxmega64b1": "avrxmega4",
    "atxmega64b3": "avrxmega4",
    "atxmega64c3": "avrxmega4",
    "atxmega64d3": "avrxmega4",
    "atxmega64d4": "avrxmega4",
    "atxmega64a1": "avrxmega5",
    "atxmega64a1u": "avrxmega5",
    "atxmega128a3": "avrxmega6",
    "atxmega128a3u": "avrxmega6",
    "atxmega128b1": "avrxmega6",
    "atxmega128b3": "avrxmega6",
    "atxmega128c3": "avrxmega6",
    "atxmega128d3": "avrxmega6",
    "atxmega128d4": "avrxmega6",
    "atxmega192a3": "avrxmega6",
    "atxmega192a3u": "avrxmega6",
    "atxmega192c3": "avrxmega6",
    "atxmega192d3": "avrxmega6",
    "atxmega256a3": "avrxmega6",
    "atxmega256a3u": "avrxmega6",
    "atxmega256a3b": "avrxmega6",
    "atxmega256a3bu": "avrxmega6",
    "atxmega256c3": "avrxmega6",
    "atxmega256d3": "avrxmega6",
    "atxmega384c3": "avrxmega6",
    "atxmega384d3": "avrxmega6",
    "atxmega128a1": "avrxmega7",
    "atxmega128a1u": "avrxmega7",
    "atxmega128a4u": "avrxmega7",
    "attiny4": "avrtiny10",
    "attiny5": "avrtiny10",
    "attiny9": "avrtiny10",
    "attiny10": "avrtiny10",
    "attiny20": "avrtiny10",
    "attiny40": "avrtiny10",
}

regs = {
    # Register dictionary for supported architectures
    "avr35": {
        0x7F : "TWSCRA",
        0x7E : "TWSCRB",
        0x7D : "TWSSRA",
        0x7C : "TWSA",
        0x7B : "TWSAM",
        0x7A : "TWSD",
        0x79 : "UCSR1A",
        0x78 : "UCSR1B",
        0x77 : "UCSR1C",
        0x76 : "UCSR1D",
        0x75 : "UBRR1H",
        0x74 : "UBRR1L",
        0x73 : "UDR1",
        0x72 : "TCCR1A",
        0x71 : "TCCR1B",
        0x70 : "TCCR1C",
        0x6F : "TCNT1H",
        0x6E : "TCNT1L",
        0x6D : "OCR1AH",
        0x6C : "OCR1AL",
        0x6B : "OCR1BH",
        0x6A : "OCR1BL",
        0x69 : "ICR1H",
        0x68 : "ICR1L",
        0x67 : "GTCCR",
        0x66 : "OSCCAL1",
        0x65 : "OSCTCAL0B",
        0x64 : "OSCTCAL0A",
        0x63 : "OSCCAL0",
        0x62 : "DIDR2",
        0x61 : "DIDR1",
        0x60 : "DIDR0",
        0x3F : "SREG",
        0x3E : "SPH",
        0x3D : "SPL",
        0x3C : "GIMSK",
        0x3B : "GIFR",
        0x3A : "TIMSK",
        0x39 : "TIFR",
        0x38 : "QTCSR",
        0x37 : "SPMCSR",
        0x36 : "MCUCR",
        0x35 : "MCUSR",
        0x34 : "PRR",
        0x33 : "CLKPR",
        0x32 : "CLKSR",
        0x30 : "WDTCSR",
        0x2F : "CCP",
        0x2E : "DWDR",
        0x2D : "USIBR",
        0x2C : "USIDR",
        0x2B : "USISR",
        0x2A : "USICR",
        0x29 : "PCMSK2",
        0x28 : "PCMSK1",
        0x27 : "PCMSK0",
        0x26 : "UCSR0A",
        0x25 : "UCSR0B",
        0x24 : "UCSR0C",
        0x23 : "UCSR0D",
        0x22 : "UBRR0H",
        0x21 : "UBRR0L",
        0x20 : "UDR0",
        0x1F : "EEARH",
        0x1E : "EEARL",
        0x1D : "EEDR",
        0x1C : "EECR",
        0x1B : "TCCR0A",
        0x1A : "TCCR0B",
        0x19 : "TCNT0",
        0x18 : "OCR0A",
        0x17 : "OCR0B",
        0x16 : "GPIOR2",
        0x15 : "GPIOR1",
        0x14 : "GPIOR0",
        0x13 : "PORTCR",
        0x12 : "PUEA",
        0x11 : "PORTA",
        0x10 : "DDRA",
        0x0F : "PINA",
        0x0E : "PUEB",
        0x0D : "PORTB",
        0x0C : "DDRB",
        0x0B : "PINB",
        0x0A : "PUEC",
        0x09 : "PORTC",
        0x08 : "DDRC",
        0x07 : "PINC",
        0x06 : "ACSRA",
        0x05 : "ACSRB",
        0x04 : "ADMUX",
        0x03 : "ADCSRA",
        0x02 : "ADCSRB",
        0x01 : "ADCH",
        0x00 : "ADCL",
    },
    "avr5": {
        0xFA : "CANMSG",
        0xF9 : "CANSTMPH",
        0xF8 : "CANSTMPL",
        0xF7 : "CANIDM1",
        0xF6 : "CANIDM2",
        0xF5 : "CANIDM3",
        0xF4 : "CANIDM4",
        0xF3 : "CANIDT1",
        0xF2 : "CANIDT2",
        0xF1 : "CANIDT3",
        0xF0 : "CANIDT4",
        0xEF : "CANCDMOB",
        0xEE : "CANSTMOB",
        0xED : "CANPAGE",
        0xEC : "CANHPMOB",
        0xEB : "CANREC",
        0xEA : "CANTEC",
        0xE9 : "CANTTCH",
        0xE8 : "CANTTCL",
        0xE7 : "CANTIMH",
        0xE6 : "CANTIML",
        0xE5 : "CANTCON",
        0xE4 : "CANBT3",
        0xE3 : "CANBT2",
        0xE2 : "CANBT1",
        0xE1 : "CANSIT1",
        0xE0 : "CANSIT2",
        0xDF : "CANIE1",
        0xDE : "CANIE2",
        0xDD : "CANEN1",
        0xDC : "CANEN2",
        0xDB : "CANGIE",
        0xDA : "CANGIT",
        0xD9 : "CANGSTA",
        0xD8 : "CANGCON",
        0xD2 : "LINDAT",
        0xD1 : "LINSEL",
        0xD0 : "LINIDR",
        0xCF : "LINDLR",
        0xCE : "LINBRRH",
        0xCD : "LINBRRL",
        0xCC : "LINBTR",
        0xCB : "LINERR",
        0xCA : "LINENIR",
        0xC9 : "LINSIR",
        0xC8 : "LINCR",
        0xBC : "PIFR",
        0xBB : "PIM",
        0xBA : "PMIC2",
        0xB9 : "PMIC1",
        0xB8 : "PMIC0",
        0xB7 : "PCTL",
        0xB6 : "POC",
        0xB5 : "PCNF",
        0xB4 : "PSYNC",
        0xB3 : "POCR_RBH",
        0xB2 : "POCR_RBL",
        0xB1 : "POCR2SBH",
        0xB0 : "POCR2SBL",
        0xAF : "POCR2RAH",
        0xAE : "POCR2RAL",
        0xAD : "POCR2SAH",
        0xAC : "POCR2SAL",
        0xAB : "POCR1SBH",
        0xAA : "POCR1SBL",
        0xA9 : "POCR1RAH",
        0xA8 : "POCR1RAL",
        0xA7 : "POCR1SAH",
        0xA6 : "POCR1SAL",
        0xA5 : "POCR0SBH",
        0xA4 : "POCR0SBL",
        0xA3 : "POCR0RAH",
        0xA2 : "POCR0RAL",
        0xA1 : "POCR0SAH",
        0xA0 : "POCR0SAL",
        0x97 : "AC3CON",
        0x96 : "AC2CON",
        0x95 : "AC1CON",
        0x94 : "AC0CON",
        0x92 : "DACH",
        0x91 : "DACL",
        0x90 : "DACON",
        0x8B : "OCR1BH",
        0x8A : "OCR1BL",
        0x89 : "OCR1AH",
        0x88 : "OCR1AL",
        0x87 : "ICR1H",
        0x86 : "ICR1L",
        0x85 : "TCNT1H",
        0x84 : "TCNT1L",
        0x82 : "TCCR1C",
        0x81 : "TCCR1B",
        0x80 : "TCCR1A",
        0x7F : "DIDR1",
        0x7E : "DIDR0",
        0x7C : "ADMUX",
        0x7B : "ADCSRB",
        0x7A : "ADCSRA",
        0x79 : "ADCH",
        0x78 : "ADCL",
        0x77 : "AMP2CSR",
        0x76 : "AMP1CSR",
        0x75 : "AMP0CSR",
        0x6F : "TIMSK1",
        0x6E : "TIMSK0",
        0x6D : "PCMSK3",
        0x6C : "PCMSK2",
        0x6B : "PCMSK1",
        0x6A : "PCMSK0",
        0x69 : "EICRA",
        0x68 : "PCICR",
        0x66 : "OSCCAL",
        0x64 : "PRR",
        0x61 : "CLKPR",
        0x60 : "WDTCSR",
        0x3F : "SREG",
        0x3E : "SPH",
        0x3D : "SPL",
        0x37 : "SPMCSR",
        0x35 : "MCUCR",
        0x34 : "MCUSR",
        0x33 : "SMCR",
        0x30 : "ACSR",
        0x2E : "SPDR",
        0x2D : "SPSR",
        0x2C : "SPCR",
        0x29 : "PLLCSR",
        0x28 : "OCR0B",
        0x27 : "OCR0A",
        0x26 : "TCNT0",
        0x25 : "TCCR0B",
        0x24 : "TCCR0A",
        0x23 : "GTCCR",
        0x22 : "EEARH",
        0x21 : "EEARL",
        0x20 : "EEDR",
        0x1F : "EECR",
        0x1E : "GPIOR0",
        0x1D : "EIMSK",
        0x1C : "EIFR",
        0x1B : "PCIFR",
        0x1A : "GPIOR2",
        0x19 : "GPIOR1",
        0x16 : "TIFR1",
        0x15 : "TIFR0",
        0x0E : "PORTE",
        0x0D : "DDRE",
        0x0C : "PINE",
        0x0B : "PORTD",
        0x0A : "DDRD",
        0x09 : "PIND",
        0x08 : "PORTC",
        0x07 : "DDRC",
        0x06 : "PINC",
        0x05 : "PORTB",
        0x04 : "DDRB",
        0x03 : "PINB",
    }
}

import io
import os
import re
from subprocess import Popen, PIPE

decode = [
    re.compile(r'\b(?P<op>in|lds)\s+\w+,\s+(?P<reg>\w+)'),
    re.compile(r'\b(?P<op>out|[cs]bi|sts)\s+(?P<reg>\w+),\s+\w+'),
]

def main(args):
    """ Arguments: mcu_name dump_file """
    # Find MCU name hence architecture name & registers from first argument
    try:
        mcu = args[1]
        arch = arches[mcu]
        cmd = ['avr-objdump', '-m', arch] + args[2:]
        reg_dict = regs[arch]

    except IndexError:
        report("""{0}: Not enough arguments

Syntax: {0} <MCU> <avr-objdump argument list>

Examples:
  {0} atmega328 -S main.flash.hex
  {0} atmega328 -D -b binary main.flash.bin
""".format(args[0]))
        return 1

    # Architecture not found or wrong MCU name. Use a blank register list
    except KeyError:
        reg_dict = []
        try:
            report("Register dictionary for '{}' not available yet...".format(arch))
        except UnboundLocalError:
            cmd = ['avr-objdump'] + args[1:]
            report("Unknown MCU name: '{}'".format(mcu))

    # Architecture & reg dictionary are ready, run disassembler, analyze output
    # Examples:
    #   avr-objdump -D -m avr5 -b binary <file.flash.bin>
    #   avr-objdump -D -m avr5 <file.flash.hex>
    p = Popen(cmd, stdout=PIPE, universal_newlines=True)
    try:

        # Parse each line from objdump standard output
        for line in iter(p.stdout.readline, ''):
            matches = decode[0].search(line) or decode[1].search(line)
            try:
                # If there's a match, replace the special register index (in hex)
                # with the matched register name from the register dictionary.
                if matches:
                    # As per the datasheet, registers 0-0x3F are accessed with a
                    # 0x20 offset only with their memory-mapped version (LDS & STS)
                    regid = int(matches['reg'], 0)
                    if matches['op'] in [ 'sts', 'lds' ] and regid < 0x60:
                        regid -= 0x20

                    line = ''.join( [
                        line[:matches.start(0)],
                        re.sub(matches['reg'], reg_dict[regid], matches[0]),
                        line[matches.end(0):]
                    ] )

            # Instruction matches but operand does not, ignore (maybe no reg list)
            except IndexError:
                pass

            # Don't care if register index is nowhere to be found
            except KeyError:
                pass

            sys.stdout.write(line)

        p.stdout.close()
        return p.wait()

    # We were piped and the pager exited... bail out!
    except BrokenPipeError:
        return 0


if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))
    
respondido por el user59864
1

El mejor desensamblador que he visto es IDA. También es compatible con AVR. Pero solo lo he usado para x86. Creo que la característica que está preguntando es una de sus características principales. Puede ser por eso que este desensamblador se llama Interactivo. enlace

    
respondido por el user924
1

Si tiene una cadena de herramientas de código abierto, y esto realmente no está disponible como una opción, me parece que debería ser bastante fácil de proporcionar.

De lo contrario, no debería ser demasiado difícil de hacer en algo que post-procesa la salida. Básicamente, debe expresar una regla para hacer coincidir un patrón en el que una dirección se debe convertir en un nombre de registro, y proporcionar una tabla de búsqueda de direcciones bajas a nombres. Esto podría hacerse de manera ineficiente con un comando sed por registro y formato de instrucciones. realizado en un solo tramo muy complicado de magia por formato, o puede realizarse en casi cualquier lenguaje de programación en el que sepa leer y escribir cadenas en secuencias o archivos.

Uno de los trucos coincidiría con el contexto suficiente para determinar que el número, como 0x3F, es una dirección y no un argumento inmediato.

En un extremo, escribir su propio desensamblador no es necesariamente una empresa tan grande, y puede ser informativo. Puede comenzar haciendo grupos de códigos de operación que usen el mismo formato. Por lo general, la codificación binaria de un determinado estilo de instrucción tiene unos pocos bits para la operación ALU, quizás unos pocos bits de opción, y luego una cantidad de bits que codifican los números de registro del operando.

    
respondido por el Chris Stratton

Lea otras preguntas en las etiquetas