Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过阅读gcc输出学习汇编_C++_Gcc_Assembly_G++ - Fatal编程技术网

C++ 通过阅读gcc输出学习汇编

C++ 通过阅读gcc输出学习汇编,c++,gcc,assembly,g++,C++,Gcc,Assembly,G++,我试图通过读取GCC生成的输出来理解汇编。这是我用c++编写的代码: int main() { int x = 8; } 我使用以下方法编译它: g++-g-Wa,-alh=source.s-masm=intel-fverbose asm-O2-g-Wall-c-fmessage length=0-o source.o.。\\source.cpp“ 但是,即使有评论,我也完全不理解生成的所有内容: GAS LISTING C:\Users\Silkworm\AppData\Local\

我试图通过读取GCC生成的输出来理解汇编。这是我用c++编写的代码:

int main() {
    int x = 8;
}
我使用以下方法编译它:

g++-g-Wa,-alh=source.s-masm=intel-fverbose asm-O2-g-Wall-c-fmessage length=0-o source.o.。\\source.cpp“

但是,即使有评论,我也完全不理解生成的所有内容:

GAS LISTING C:\Users\Silkworm\AppData\Local\Temp\ccmDrbTs.s             page 1


   1                    .file   "source.cpp"
   2                    .intel_syntax noprefix
   3                 # GNU C++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) version 5.1.0 (x86_64-w64-mingw32)
   4                 #  compiled by GNU C version 5.1.0, GMP version 6.0.0, MPFR version 3.1.2-p11, MPC version 1.0.3
   5                 # GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
   6                 # options passed: 
   7                 # -iprefix C:/mingw-w64/x86_64-5.1.0-posix-seh-rt_v4-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw3
   8                 # -D_REENTRANT ..\source.cpp -masm=intel -mtune=core2 -march=nocona
   9                 # -auxbase-strip source.o -g -g -O2 -Wall -fverbose-asm
  10                 # -fmessage-length=0
  11                 # options enabled:  -faggressive-loop-optimizations -falign-labels
  12                 # -fasynchronous-unwind-tables -fauto-inc-dec -fbranch-count-reg
  13                 # -fcaller-saves -fchkp-check-incomplete-type -fchkp-check-read
  14                 # -fchkp-check-write -fchkp-instrument-calls -fchkp-narrow-bounds
  15                 # -fchkp-optimize -fchkp-store-bounds -fchkp-use-static-bounds
  16                 # -fchkp-use-static-const-bounds -fchkp-use-wrappers
  17                 # -fcombine-stack-adjustments -fcommon -fcompare-elim -fcprop-registers
  18                 # -fcrossjumping -fcse-follow-jumps -fdefer-pop
  19                 # -fdelete-null-pointer-checks -fdevirtualize -fdevirtualize-speculatively
  20                 # -fdwarf2-cfi-asm -fearly-inlining -feliminate-unused-debug-types
  21                 # -fexceptions -fexpensive-optimizations -fforward-propagate
  22                 # -ffunction-cse -fgcse -fgcse-lm -fgnu-runtime -fgnu-unique
  23                 # -fguess-branch-probability -fhoist-adjacent-loads -fident
  24                 # -fif-conversion -fif-conversion2 -findirect-inlining -finline
  25                 # -finline-atomics -finline-functions-called-once -finline-small-functions
  26                 # -fipa-cp -fipa-cp-alignment -fipa-icf -fipa-icf-functions
  27                 # -fipa-icf-variables -fipa-profile -fipa-pure-const -fipa-ra
  28                 # -fipa-reference -fipa-sra -fira-hoist-pressure -fira-share-save-slots
  29                 # -fira-share-spill-slots -fisolate-erroneous-paths-dereference -fivopts
  30                 # -fkeep-inline-dllexport -fkeep-static-consts -fleading-underscore
  31                 # -flifetime-dse -flra-remat -flto-odr-type-merging -fmath-errno
  32                 # -fmerge-constants -fmerge-debug-strings -fmove-loop-invariants
  33                 # -fomit-frame-pointer -foptimize-sibling-calls -foptimize-strlen
  34                 # -fpartial-inlining -fpeephole -fpeephole2 -fpic -fprefetch-loop-arrays
  35                 # -free -freg-struct-return -freorder-blocks -freorder-functions
  36                 # -frerun-cse-after-loop -fsched-critical-path-heuristic
  37                 # -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock
  38                 # -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
  39                 # -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fschedule-fusion
  40                 # -fschedule-insns2 -fsemantic-interposition -fset-stack-executable
  41                 # -fshow-column -fshrink-wrap -fsigned-zeros -fsplit-ivs-in-unroller
  42                 # -fsplit-wide-types -fssa-phiopt -fstdarg-opt -fstrict-aliasing
  43                 # -fstrict-overflow -fstrict-volatile-bitfields -fsync-libcalls
  44                 # -fthread-jumps -ftoplevel-reorder -ftrapping-math -ftree-bit-ccp
  45                 # -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-coalesce-vars
  46                 # -ftree-copy-prop -ftree-copyrename -ftree-cselim -ftree-dce
  47                 # -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre
  48                 # -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon
  49                 # -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pre
  50                 # -ftree-pta -ftree-reassoc -ftree-scev-cprop -ftree-sink -ftree-slsr
  51                 # -ftree-sra -ftree-switch-conversion -ftree-tail-merge -ftree-ter
  52                 # -ftree-vrp -funit-at-a-time -funwind-tables -fvar-tracking
  53                 # -fvar-tracking-assignments -fverbose-asm -fzero-initialized-in-bss
  54                 # -m128bit-long-double -m64 -m80387 -maccumulate-outgoing-args
  55                 # -malign-double -malign-stringops -mcx16 -mfancy-math-387 -mfentry
  56                 # -mfp-ret-in-387 -mfxsr -mieee-fp -mlong-double-80 -mmmx -mms-bitfields
  57                 # -mno-sse4 -mpush-args -mred-zone -msse -msse2 -msse3 -mstack-arg-probe
GAS LISTING C:\Users\Silkworm\AppData\Local\Temp\ccmDrbTs.s             page 2


  58                 # -mvzeroupper
  59                
  60                    .text
  61                .Ltext0:
  62                    .cfi_sections   .debug_frame
  63                    .def    __main; .scl    2;  .type   32; .endef
  64                    .section    .text.startup,"x"
  65                    .p2align 4,,15
  66                    .globl  main
  67                    .def    main;   .scl    2;  .type   32; .endef
  68                    .seh_proc   main
  69                main:
  70                .LFB0:
  71                    .file 1 "../source.cpp"
   1:../source.cpp **** 
   2:../source.cpp **** int main() {
  72                    .loc 1 2 0
  73                    .cfi_startproc
  74 0000 4883EC28      sub rsp, 40  #,
  75                    .seh_stackalloc 40
  76                    .cfi_def_cfa_offset 48
  77                    .seh_endprologue
  78                    .loc 1 2 0
  79 0004 E8000000      call    __main   #
  79      00
  80                .LVL0:
   3:../source.cpp **** int x = 8;
   4:../source.cpp **** }
  81                    .loc 1 4 0
  82 0009 31C0          xor eax, eax     #
  83 000b 4883C428      add rsp, 40  #,
  84                    .cfi_def_cfa_offset 8
  85 000f C3            ret
  86                    .cfi_endproc
  87                .LFE0:
  88                    .seh_endproc
  89                    .text
  90                .Letext0:
  91                    .section    .debug_info,"dr"
  92                .Ldebug_info0:
  93 0000 CF000000      .long   0xcf
  94 0004 0400          .word   0x4
  95 0006 00000000      .secrel32   .Ldebug_abbrev0
  96 000a 08            .byte   0x8
  97 000b 01            .uleb128 0x1
  98 000c 474E5520      .ascii "GNU C++ 5.1.0 -masm=intel -mtune=core2 -march=nocona -g -g -O2 -fmessage-length=0\0"
  98      432B2B20 
  98      352E312E 
  98      30202D6D 
  98      61736D3D 
  99 005e 04            .byte   0x4
 100 005f 2E2E5C68      .ascii "..\\source.cpp\0"
 100      656C6C6F 
 100      776F726C 
 100      642E6370 
 100      7000
 101 0071 433A5C63      .ascii "C:\\cpp_workspace\\disam\\Debug\0"
GAS LISTING C:\Users\Silkworm\AppData\Local\Temp\ccmDrbTs.s             page 3


 101      70705F77 
 101      6F726B73 
 101      70616365 
 101      5C646973 
 102 008e 00000000      .secrel32   .Ldebug_ranges0+0
 103 0092 00000000      .quad   0
 103      00000000 
 104 009a 00000000      .secrel32   .Ldebug_line0
 105 009e 02            .uleb128 0x2
 106 009f 6D61696E      .ascii "main\0"
 106      00
 107 00a4 01            .byte   0x1
 108 00a5 02            .byte   0x2
 109 00a6 CB000000      .long   0xcb
 110 00aa 00000000      .quad   .LFB0
 110      00000000 
 111 00b2 10000000      .quad   .LFE0-.LFB0
 111      00000000 
 112 00ba 01            .uleb128 0x1
 113 00bb 9C            .byte   0x9c
 114 00bc CB000000      .long   0xcb
 115 00c0 03            .uleb128 0x3
 116 00c1 7800          .ascii "x\0"
 117 00c3 01            .byte   0x1
 118 00c4 03            .byte   0x3
 119 00c5 CB000000      .long   0xcb
 120 00c9 08            .byte   0x8
 121 00ca 00            .byte   0
 122 00cb 04            .uleb128 0x4
 123 00cc 04            .byte   0x4
 124 00cd 05            .byte   0x5
 125 00ce 696E7400      .ascii "int\0"
 126 00d2 00            .byte   0
 127                    .section    .debug_abbrev,"dr"
 128                .Ldebug_abbrev0:
 129 0000 01            .uleb128 0x1
 130 0001 11            .uleb128 0x11
 131 0002 01            .byte   0x1
 132 0003 25            .uleb128 0x25
 133 0004 08            .uleb128 0x8
 134 0005 13            .uleb128 0x13
 135 0006 0B            .uleb128 0xb
 136 0007 03            .uleb128 0x3
 137 0008 08            .uleb128 0x8
 138 0009 1B            .uleb128 0x1b
 139 000a 08            .uleb128 0x8
 140 000b 55            .uleb128 0x55
 141 000c 17            .uleb128 0x17
 142 000d 11            .uleb128 0x11
 143 000e 01            .uleb128 0x1
 144 000f 10            .uleb128 0x10
 145 0010 17            .uleb128 0x17
 146 0011 00            .byte   0
 147 0012 00            .byte   0
 148 0013 02            .uleb128 0x2
 149 0014 2E            .uleb128 0x2e
 150 0015 01            .byte   0x1
GAS LISTING C:\Users\Silkworm\AppData\Local\Temp\ccmDrbTs.s             page 4


 151 0016 3F            .uleb128 0x3f
 152 0017 19            .uleb128 0x19
 153 0018 03            .uleb128 0x3
 154 0019 08            .uleb128 0x8
 155 001a 3A            .uleb128 0x3a
 156 001b 0B            .uleb128 0xb
 157 001c 3B            .uleb128 0x3b
 158 001d 0B            .uleb128 0xb
 159 001e 49            .uleb128 0x49
 160 001f 13            .uleb128 0x13
 161 0020 11            .uleb128 0x11
 162 0021 01            .uleb128 0x1
 163 0022 12            .uleb128 0x12
 164 0023 07            .uleb128 0x7
 165 0024 40            .uleb128 0x40
 166 0025 18            .uleb128 0x18
 167 0026 9642          .uleb128 0x2116
 168 0028 19            .uleb128 0x19
 169 0029 01            .uleb128 0x1
 170 002a 13            .uleb128 0x13
 171 002b 00            .byte   0
 172 002c 00            .byte   0
 173 002d 03            .uleb128 0x3
 174 002e 34            .uleb128 0x34
 175 002f 00            .byte   0
 176 0030 03            .uleb128 0x3
 177 0031 08            .uleb128 0x8
 178 0032 3A            .uleb128 0x3a
 179 0033 0B            .uleb128 0xb
 180 0034 3B            .uleb128 0x3b
 181 0035 0B            .uleb128 0xb
 182 0036 49            .uleb128 0x49
 183 0037 13            .uleb128 0x13
 184 0038 1C            .uleb128 0x1c
 185 0039 0B            .uleb128 0xb
 186 003a 00            .byte   0
 187 003b 00            .byte   0
 188 003c 04            .uleb128 0x4
 189 003d 24            .uleb128 0x24
 190 003e 00            .byte   0
 191 003f 0B            .uleb128 0xb
 192 0040 0B            .uleb128 0xb
 193 0041 3E            .uleb128 0x3e
 194 0042 0B            .uleb128 0xb
 195 0043 03            .uleb128 0x3
 196 0044 08            .uleb128 0x8
 197 0045 00            .byte   0
 198 0046 00            .byte   0
 199 0047 00            .byte   0
 200                    .section    .debug_aranges,"dr"
 201 0000 2C000000      .long   0x2c
 202 0004 0200          .word   0x2
 203 0006 00000000      .secrel32   .Ldebug_info0
 204 000a 08            .byte   0x8
 205 000b 00            .byte   0
 206 000c 0000          .word   0
 207 000e 0000          .word   0
GAS LISTING C:\Users\Silkworm\AppData\Local\Temp\ccmDrbTs.s             page 5


 208 0010 00000000      .quad   .LFB0
 208      00000000 
 209 0018 10000000      .quad   .LFE0-.LFB0
 209      00000000 
 210 0020 00000000      .quad   0
 210      00000000 
 211 0028 00000000      .quad   0
 211      00000000 
 212                    .section    .debug_ranges,"dr"
 213                .Ldebug_ranges0:
 214 0000 00000000      .quad   .LFB0
 214      00000000 
 215 0008 10000000      .quad   .LFE0
 215      00000000 
 216 0010 00000000      .quad   0
 216      00000000 
 217 0018 00000000      .quad   0
 217      00000000 
 218                    .section    .debug_line,"dr"
 219                .Ldebug_line0:
 220 0000 41000000      .section    .debug_str,"dr"
 220      02002800 
 220      00000101 
 220      FB0E0D00 
 220      01010101 
 221                    .ident  "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 5.1.0"

这里没有一条我学过的指令像movl,pop,没有像%eax之类的寄存器。这与我在网上遇到的例子完全不同。我怎么能理解这一点。

您的程序实际上什么都不做;局部变量x未使用,已被编译器删除。大部分汇编代码都是调试信息,其余部分与调用主函数所需的操作有关

您应该能够识别这一行:

xor eax, eax

主函数隐式返回零。该值在eax寄存器中返回,因此此行将在eax中置零

正如@user2864740所提到的,这不是学习汇编的最佳方式,但是您可以学习并理解不同的编译器如何将C/C++转换为汇编,以及它们如何优化代码

在您的示例中,您将看不到任何有趣的学习内容,因为您的代码不包含任何函数,而且您使用优化(-O2)编译它

  • 如果您想看到一些以易于理解的方式反映您编写内容的汇编代码,请不要使用优化(-O0)
  • 请注意,您选择了“英特尔”汇编代码语法,还有AT&T代码语法()。如果要查看AT&T样式,请从编译行中删除
    -masm=intel
  • 例如,尝试构建以下代码:

    int main()
    {
     int x = 8;
     int y = 18;
     int z = x + y;
    
     return z;
    }
    
    在没有优化的情况下,您会得到如下结果:

      35                main:
      36                .LFB2:
      37                    .file 1 "assm.cpp"
       1:assm.cpp      **** int main()
      38                    .loc 1 1 0
      39 0000 55            push    %rbp    #
      40                .LCFI0:
      41 0001 4889E5        mov %rbp, %rsp  #,
      42                .LCFI1:
      43                .LBB2:
       2:assm.cpp      ****     {
       3:assm.cpp      ****      int x = 8;
      44                    .loc 1 3 0
      45 0004 C745F408      mov DWORD PTR [%rbp-12], 8  # x,
      45      000000
       4:assm.cpp      ****      int y = 18;
      46                    .loc 1 4 0
      47 000b C745F812      mov DWORD PTR [%rbp-8], 18  # y,
      47      000000
    GAS LISTING /tmp/ccHUnQdo.s            page 2
    
    
       5:assm.cpp      ****      int z = x + y;
      48                    .loc 1 5 0
      49 0012 8B45F8        mov %eax, DWORD PTR [%rbp-8]    # y, y
      50 0015 0345F4        add %eax, DWORD PTR [%rbp-12]   # tmp60, x
      51 0018 8945FC        mov DWORD PTR [%rbp-4], %eax    # z, tmp60
       6:assm.cpp      ****     
       7:assm.cpp      ****      return z;
      52                    .loc 1 7 0
      53 001b 8B45FC        mov %eax, DWORD PTR [%rbp-4]    # D.2339, z
      54                .LBE2:
       8:assm.cpp      ****     }
      55                    .loc 1 8 0
      56 001e C9            leave
      57 001f C3            ret
    
    您可以看到局部变量在堆栈上(RBP用于访问它们),编译器在我的机器上为它们分配12个字节(x,y,z)=>的
    sizeof(int)
    是4个字节。RBP指向堆栈的末尾,x首先在堆栈上分配,因此为了访问它,编译器使用“RBP-12”(y是堆栈上的第二个,因此由“RBP-8”访问,依此类推)。方括号表示内存访问,方括号中的值表示地址。“DWORD PTR”表示内存访问大小为“双字”,即4字节(字=16位=2字节)

    使用-O2优化,编译器将优化所有代码并立即返回26(如果32位足以保持该值而不丢失数据,则返回值通常放在EAX中):

    48主:
    49.LFB2:
    50.文件1“assm.cpp”
    1:assm.cpp****int main()
    51.loc 1 10
    2:助理cpp****{
    气体清单/tmp/CCZVIDN.s第2页
    3:assm.cpp****int x=8;
    4:assm.cpp****int y=18;
    5:assm.cpp****int z=x+y;
    6:助理cpp****
    7:助理cpp****返回z;
    8:assm.cpp****}
    52.loc 18 0
    53 0000 B81A0000 mov%eax,26#,
    53      00
    54 0005 C3 ret
    
    总之:这可能不是学习汇编的方法:}您的变量没有被使用。总的来说,编译器生成的汇编代码与手工编写的汇编代码相比可能不那么简单——有几个因素(比如代码优化)起作用。要使push、pop指令可见,请尝试添加一个简单函数并从main调用它。不执行任何操作的程序不能期望有任何明确实现“不执行任何操作”的汇编指令。真正地查看编译器输出的想法并不坏,但您需要以一种更明智的方式进行。例如,从
    main
    中的一个简单函数调用开始。请记住,编译器通常会添加大量样板代码,对于最小的小程序来说,这是没有意义的。我个人将使用编译C代码的结果而不是C++。
      48                main:
      49                .LFB2:
      50                    .file 1 "assm.cpp"
       1:assm.cpp      **** int main()
      51                    .loc 1 1 0
       2:assm.cpp      ****     {
    GAS LISTING /tmp/ccZvidrN.s            page 2
    
    
       3:assm.cpp      ****      int x = 8;
       4:assm.cpp      ****      int y = 18;
       5:assm.cpp      ****      int z = x + y;
       6:assm.cpp      ****     
       7:assm.cpp      ****      return z;
       8:assm.cpp      ****     }
      52                    .loc 1 8 0
      53 0000 B81A0000      mov %eax, 26    # <result>,
      53      00
      54 0005 C3            ret