2017-09-23 84 views
0

我使用一个Arduino兆2560,其具有AVR Atmega2560芯片。我使用Windows上的库存Arduino IDE 1.8.4对其进行编程,该库随附avr-objdump 2.26和avr-g ++ 4.9.2。AVR-objdump的生产具有克不正确的输出++ -flto

我的程序或多或少有效,但是当试图检查生成的程序集时,看起来objdump没有生成正确的输出。

执行

avr-objdump -D -S -m avr:6 "arduino_build_948544\sketch\mysketch.ino.cpp.o" > mysketch.asm 

看似成功,但作为

void sleep_example() { 
    SMCR = 1; 
    __asm__("sleep"); 
} 

简单函数的反汇编似乎是基本上是随机的:

Disassembly of section .gnu.lto__Z13sleep_examplev.af7e500a: 

00000000 <.gnu.lto__Z13sleep_examplev.af7e500a>: 
    0: 78 9c   mul r7, r8 
    2: 63 66   ori r22, 0x63 ; 99 
    4: c0 04   cpc r12, r0 
    6: 52 40   sbci r21, 0x02 ; 2 
    8: fc 18   sub r15, r12 
    a: 88 3d   cpi r24, 0xD8 ; 216 
    c: 81 98   cbi 0x10, 1 ; 16 
    e: 91 99   sbic 0x12, 1 ; 18 
    10: 81 91   ld r24, Z+ 
    12: 69 c2   rjmp .+1234  ; 0x4e6 <__SREG__+0x4a7> 
    14: 39 06   cpc r3, r25 
    16: 86 46   sbci r24, 0x66 ; 102 
    18: 0e 26   eor r0, r30 
    1a: 46 46   sbci r20, 0x66 ; 102 
    1c: 10 83   st Z, r17 
    1e: 81 91   ld r24, Z+ 
    20: a1 9e   mul r10, r17 
    22: 89 b1   in r24, 0x09 ; 9 
    24: 9e f1   brts .+102  ; 0x8c <__SREG__+0x4d> 
    26: 25 d3   rcall .+1610  ; 0x672 <__SREG__+0x633> 
    28: 47 26   eor r4, r23 
    2a: c6 ef   ldi r28, 0xF6 ; 246 
    2c: 73 17   cp r23, r19 
    2e: 9c 60   ori r25, 0x0C ; 12 
    30: 52 57   subi r21, 0x72 ; 114 
    32: 9d fe   .word 0xfe9d ; ???? 
    34: ba 99   sbic 0x17, 2 ; 23 
    36: bb a1   ldd r27, Y+35 ; 0x23 
    38: cb e0   ldi r28, 0x0B ; 11 
    3a: 27 13   cpse r18, r23 
    3c: 03 c3   rjmp .+1542  ; 0x644 <__SREG__+0x605> 
    3e: 67 26   eor r6, r23 
    40: 88 21   and r24, r8 
    42: 8c cb   rjmp .-2280  ; 0xfffff75c <__SREG__+0xfffff71d> 
    44: 19 d5   rcall .+2610  ; 0xa78 <__SREG__+0xa39> 
    46: 19 80   ldd r1, Y+1 ; 0x01 
    48: 2a 3a   cpi r18, 0xAA ; 170 
    4a: 77 dc   rcall .-1810  ; 0xfffff93a <__SREG__+0xfffff8fb> 
    4c: ee e0   ldi r30, 0x0E ; 14 
    4e: 63 63   ori r22, 0x33 ; 51 
    50: 61 84   ldd r6, Z+9 ; 0x09 
    52: 48 30   cpi r20, 0x08 ; 8 
    54: ae 60   ori r26, 0x0E ; 14 
    56: 64 63   ori r22, 0x34 ; 52 
    58: 04 d2   rcall .+1032  ; 0x462 <__SREG__+0x423> 
    5a: eb 85   ldd r30, Y+11 ; 0x0b 
    5c: 0e 34   cpi r16, 0x4E ; 78 
    5e: fc ff   .word 0xfffc ; ???? 
    60: cf bc   out 0x2f, r12 ; 47 
    62: eb e1   ldi r30, 0x1B ; 27 
    64: 3b 65   ori r19, 0x5B ; 91 
    66: 66 06   cpc r6, r22 
    68: 86 27   eor r24, r22 
    6a: 40 29   or r20, r0 
    6c: 90 d1   rcall .+800  ; 0x38e <__SREG__+0x34f> 
    6e: 4f 99   sbic 0x09, 7 ; 9 
    70: 98 40   sbci r25, 0x08 ; 8 
    72: 34 f3   brlt .-52  ; 0x40 <__SREG__+0x1> 
    74: 2d c6   rjmp .+3162  ; 0xcd0 <__SREG__+0xc91> 
    76: 43 1f   adc r20, r19 
    78: 36 7c   andi r19, 0xC6 ; 198 
    7a: 63 94   inc r6 
    7c: 05 a9   ldd r16, Z+53 ; 0x35 
    7e: 06 1a   sub r0, r22 
    80: 31 67   ori r19, 0x71 ; 113 
    82: 75 fb   bst r23, 5 
    84: 19 de   rcall .-974  ; 0xfffffcb8 <__SREG__+0xfffffc79> 
    86: 17 4c   sbci r17, 0xC7 ; 199 
    88: 3f 99   sbic 0x07, 7 ; 7 
    8a: 18 83   st Y, r17 
    8c: 41 26   eor r4, r17 
    8e: ee ea   ldi r30, 0xAE ; 174 
    90: fb 7f   andi r31, 0xFB ; 251 
    92: 90 0b   sbc r25, r16 
    94: cc 65   ori r28, 0x5C ; 92 
    96: 00 71   andi r16, 0x10 ; 16 
    98: 37 ed   ldi r19, 0xD7 ; 215 
    9a: 5e 74   andi r21, 0x4E ; 78 
    9c: 9c 79   andi r25, 0x9C ; 156 
    9e: 2e e3   ldi r18, 0x3E ; 62 
    a0: ec c6   rjmp .+3544  ; 0xe7a <__SREG__+0xe3b> 
    a2: 16 46   sbci r17, 0x66 ; 102 
    a4: 86 9f   mul r24, r22 
    a6: 4c 4c   sbci r20, 0xCC ; 204 
    a8: 8c 2b   or r24, r28 
    aa: 19 a5   ldd r17, Y+41 ; 0x29 
    ac: 18 57   subi r17, 0x78 ; 120 
    ae: 31 02   muls r19, r17 
    b0: fd c0   rjmp .+506  ; 0x2ac <__SREG__+0x26d> 
    b2: b8 9a   sbi 0x17, 0 ; 23 
    b4: 71 2e   mov r7, r17 
    b6: 23 50   subi r18, 0x03 ; 3 
    b8: c1 a7   std Z+41, r28 ; 0x29 
    ba: 27 37   cpi r18, 0x77 ; 119 
    bc: 7f b2   in r7, 0x1f ; 31 
    be: 83 d4   rcall .+2310  ; 0x9c6 <__SREG__+0x987> 
    c0: 33 33   cpi r19, 0x33 ; 51 
    c2: 32 30   cpi r19, 0x02 ; 2 
    c4: ae 01   movw r20, r28 
    c6: ca dc   rcall .-1644  ; 0xfffffa5c <__SREG__+0xfffffa1d> 
    c8: 66 6c   ori r22, 0xC6 ; 198 
    ca: 38 7c   andi r19, 0xC8 ; 200 
    cc: fb 38   cpi r31, 0x8B ; 139 
    ce: 1b 13   cpse r17, r27 
    d0: c8 78   andi r28, 0x88 ; 136 
    d2: 90 53   subi r25, 0x30 ; 48 
    d4: 9d 19   sub r25, r13 
    d6: ee 31   cpi r30, 0x1E ; 30 
    d8: 36 1e   adc r3, r22 
    da: b8 eb   ldi r27, 0xB8 ; 184 
    dc: 0e e3   ldi r16, 0x3E ; 62 
    de: 3f 01   movw r6, r30 
    e0: 9a 0c   add r9, r10 
    e2: 74 06   cpc r7, r20 
    e4: d0 51   subi r29, 0x10 ; 16 
    e6: 0e ce   rjmp .-996  ; 0xfffffd04 <__SREG__+0xfffffcc5> 
    e8: 56 31   cpi r21, 0x16 ; 22 
    ea: a1 c5   rjmp .+2882  ; 0xc2e <__SREG__+0xbef> 
    ec: a9 45   sbci r26, 0x59 ; 89 
    ee: c5 31   cpi r28, 0x15 ; 21 
    f0: e9 25   eor r30, r9 
    f2: f9 f9   .word 0xf9f9 ; ???? 
    f4: b9 31   cpi r27, 0x19 ; 25 
    f6: fe 79   andi r31, 0x9E ; 158 
    f8: a9 2e   mov r10, r25 
    fa: 45 99   sbic 0x08, 5 ; 8 
    fc: 65 a9   ldd r22, Z+53 ; 0x35 
    fe: 31 2e   mov r3, r17 
100: f9 c9   rjmp .-3086  ; 0xfffff4f4 <__SREG__+0xfffff4b5> 
102: a5 b9   out 0x05, r26 ; 5 
104: a9 79   andi r26, 0x99 ; 153 
106: 25 c5   rjmp .+2634  ; 0xb52 <__SREG__+0xb13> 
108: 31 8e   std Z+25, r3 ; 0x19 
10a: 45 29   or r20, r5 
10c: a5 99   sbic 0x14, 5 ; 20 
10e: 79 f9   .word 0xf979 ; ???? 
110: 31 c9   rjmp .-3486  ; 0xfffff374 <__SREG__+0xfffff335> 
112: 89 05   cpc r24, r9 
114: b9 a9   ldd r27, Y+49 ; 0x31 
116: 25 a9   ldd r18, Z+53 ; 0x35 
118: 45 70   andi r20, 0x05 ; 5 
11a: 86 1e   adc r8, r22 
11c: 50 94   com r5 
11e: 81 ad   ldd r24, Z+57 ; 0x39 
120: 38 27   eor r19, r24 
122: 35 b5   in r19, 0x25 ; 37 
124: 80 01   movw r16, r0 
126: 00 1d   adc r16, r0 
128: 9f 69   ori r25, 0x9F ; 159 
12a: 9f f5   Address 0x0000012a is out of bounds. 
.word 0xffff ; ???? 

我不知道为什么这是。这可能是我对avr-objdump的调用,但我不知道要改变什么才能显示正确的反汇编。

+0

不要打开链接时优化(LTO),否则代码不会被编译到链接时。 –

+0

@RossRidge我可以确认在编译和链接阶段都会传递'-flto'。虽然我无法控制IDE的功能,但我可以在没有它的情况下自定义编译,然后尝试objdump。但为什么它很重要?为什么这个输出如此混乱? – Reinderien

+2

因为,正如我所说,它尚未编译。它不是从C翻译成机器码,而是从C翻译成GCC使用的一些内部中间格式。它不会被翻译成机器代码,你可以反汇编,直到链接阶段。如果你想看到GCC的汇编输出,我建议使用'-S'选项(不带'-flto'选项),GCC将生成一个汇编文件而不是一个目标文件。 –

回答

4

-flto将GCC的内部表示置于.o中,用于在链接时进行跨文件优化。 https://gcc.gnu.org/wiki/LinkTimeOptimization

它不在代码部分,但是您使用-D反汇编非代码段,就好像它们是代码一样。所以你得到了你所要求的。

如果您还没有使用过LTO,那么.o中会有实际的AVR机器代码。

有可能会包括机器代码并在.o海合会内部表示一种选择,但不会是最终的机器代码,如果你使用-flto同时链接,将进入二进制文件。但更好的方法是看gcc -O3 -S(另请参阅How to remove "noise" from GCC/clang assembly output?)。 (无-flto,否则你会看到gcc馈送到gas的ASM产生.o.gnu.lto__Z13sleep...部分,而不是.text部分。)

只有这样,才能看到最终的二进制代码拆解。优化发生在创建它的同一步骤中,所以以前的步骤都不会保证是相同的。但是,查看编译器的asm输出可能很有用,因为它可以保留一些符号信息,尤其是-fverbose-asm

+0

事实上:我发现最后的'elf'上的objdump产生了最好的结果。不幸的是,'gcc -S'没有用。而不是将反汇编显示为说明,它将十六进制的重新版本显示为不透明文本段的块。 – Reinderien

+2

@Reinderien:你使用过'gcc -O3 -S -flto'吗?像罗斯告诉你不要? asm输出是它如何创建一个'.o',它包含'.gnu.lto__Z13sleep _...'节而不是'.text'节。 –

+0

嗯,是的......我曾尝试删除LTO,并添加了-S,但不在一起。那样做了。 – Reinderien