简体   繁体   中英

Running an external compiler (godbolt) assembly

Let's say I have the following C program:

int main() {
    int a = 1;
    int b = 2;
    return a + b;
}

Compiling this on Compiler Explorer gives me:

main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $1, -4(%rbp)
        movl    $2, -8(%rbp)
        movl    -4(%rbp), %edx
        movl    -8(%rbp), %eax
        addl    %edx, %eax
        popq    %rbp
        ret

This is (somewhat) similar to what compiling via gcc gives me, at least for the main part. However, this will not compile as a "stand-alone", for example if I copy-paste the asm into a file gb.s and run $ gcc gb.s I get an error:

/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol...
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

-- unless I also include the .globl at the top, for example:

.globl  main

From this, I have two questions:

  • Why doesn't the godbolt compiler contain that at the top, or something else to make it self-contained?
  • Is there a way to run gcc and tell it that main is the main/global section without putting .globl main at the top?

A good man Matt Godbolt has put a lots of effort to filter all the noise form the generated assembly

.file   "example.c"
        .text
.Ltext0:
        .globl  main
        .type   main, @function
main:
.LFB0:
        .file 1 "./example.c"
        .loc 1 1 12
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        .loc 1 2 9
        movl    $1, -4(%rbp)
        .loc 1 3 9
        movl    $2, -8(%rbp)
        .loc 1 4 14
        movl    -4(%rbp), %edx
        movl    -8(%rbp), %eax
        addl    %edx, %eax
        .loc 1 5 1
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
.Letext0:
        .section        .debug_info,"",@progbits
.Ldebug_info0:
        .long   0x6e
        .value  0x4
        .long   .Ldebug_abbrev0
        .byte   0x8
        .uleb128 0x1
        .long   .LASF0
        .byte   0xc
        .long   .LASF1
        .long   .LASF2
        .quad   .Ltext0
        .quad   .Letext0-.Ltext0
        .long   .Ldebug_line0
        .uleb128 0x2
        .long   .LASF3
        .byte   0x1
        .byte   0x1
        .byte   0x5
        .long   0x6a
        .quad   .LFB0
        .quad   .LFE0-.LFB0
        .uleb128 0x1
        .byte   0x9c
        .long   0x6a
        .uleb128 0x3
        .string "a"
        .byte   0x1
        .byte   0x2
        .byte   0x9
        .long   0x6a
        .uleb128 0x2
        .byte   0x91
        .sleb128 -20
        .uleb128 0x3
        .string "b"
        .byte   0x1
        .byte   0x3
        .byte   0x9
        .long   0x6a
        .uleb128 0x2
        .byte   0x91
        .sleb128 -24
        .byte   0
        .uleb128 0x4
        .byte   0x4
        .byte   0x5
        .string "int"
        .byte   0
        .section        .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
        .uleb128 0x1
        .uleb128 0x11
        .byte   0x1
        .uleb128 0x25
        .uleb128 0xe
        .uleb128 0x13
        .uleb128 0xb
        .uleb128 0x3
        .uleb128 0xe
        .uleb128 0x1b
        .uleb128 0xe
        .uleb128 0x11
        .uleb128 0x1
        .uleb128 0x12
        .uleb128 0x7
        .uleb128 0x10
        .uleb128 0x17
        .byte   0
        .byte   0
        .uleb128 0x2
        .uleb128 0x2e
        .byte   0x1
        .uleb128 0x3f
        .uleb128 0x19
        .uleb128 0x3
        .uleb128 0xe
        .uleb128 0x3a
        .uleb128 0xb
        .uleb128 0x3b
        .uleb128 0xb
        .uleb128 0x39
        .uleb128 0xb
        .uleb128 0x49
        .uleb128 0x13
        .uleb128 0x11
        .uleb128 0x1
        .uleb128 0x12
        .uleb128 0x7
        .uleb128 0x40
        .uleb128 0x18
        .uleb128 0x2117
        .uleb128 0x19
        .uleb128 0x1
        .uleb128 0x13
        .byte   0
        .byte   0
        .uleb128 0x3
        .uleb128 0x34
        .byte   0
        .uleb128 0x3
        .uleb128 0x8
        .uleb128 0x3a
        .uleb128 0xb
        .uleb128 0x3b
        .uleb128 0xb
        .uleb128 0x39
        .uleb128 0xb
        .uleb128 0x49
        .uleb128 0x13
        .uleb128 0x2
        .uleb128 0x18
        .byte   0
        .byte   0
        .uleb128 0x4
        .uleb128 0x24
        .byte   0
        .uleb128 0xb
        .uleb128 0xb
        .uleb128 0x3e
        .uleb128 0xb
        .uleb128 0x3
        .uleb128 0x8
        .byte   0
        .byte   0
        .byte   0
        .section        .debug_aranges,"",@progbits
        .long   0x2c
        .value  0x2
        .long   .Ldebug_info0
        .byte   0x8
        .byte   0
        .value  0
        .value  0
        .quad   .Ltext0
        .quad   .Letext0-.Ltext0
        .quad   0
        .quad   0
        .section        .debug_line,"",@progbits
.Ldebug_line0:
        .section        .debug_str,"MS",@progbits,1
.LASF2:
        .string "/home/ce"
.LASF3:
        .string "main"
.LASF0:
        .string "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g"
.LASF1:
        .string "./example.c"
        .ident  "GCC: (Compiler-Explorer-Build) 9.3.0"
        .section        .note.GNU-stack,"",@progbits

Simple untick the "Directives" 在此处输入图像描述

Why doesn't the godbolt compiler contain that at the top, or something else to make it self-contained?

Godbolt (Compiler Explorer) is not a compiler, but a web interface to study the output of many compilers for many languages. Since it is intended mostly to study optimizations and code generation, its output is filtered by default to show you what is relevant.

Is there a way to run gcc and tell it that main is the main/global section without putting.globl main at the top?

I think this is an instance of the XY problem. Assuming that what you want is to see what your local GCC generates, you should use the -S option which will give you the unfiltered output. You can then pass that into GCC again to link it.

In other words, you don't need Compiler Explorer if what you want is to compile actual programs into assembly and then link them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM