I wrote a simple C program test.c:
#include <stdio.h>
#include <stdlib.h>
int add(int a, int b);
int main()
{
int i=5,j=10;
int result;
result = add(i, j);
printf("result is %d\n", result);
}
int add(int a, int b)
{
return (a + b);
}
and I compiled it:
gcc -S -Os -o test.s test.c
and I get the build file test.s:
.file "test3.c"
.section .rodata
.LC0:
.string "result is %d\n"
.text
.globl main
.type main, @function
main:
.LFB5:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $16, %rsp
.LCFI2:
movl $5, -12(%rbp)
movl $10, -8(%rbp)
movl -8(%rbp), %esi
movl -12(%rbp), %edi
call add
movl %eax, -4(%rbp)
movl -4(%rbp), %esi
movl $.LC0, %edi
movl $0, %eax
call printf
leave
ret
.LFE5:
.size main, .-main
.globl add
.type add, @function
add:
.LFB6:
pushq %rbp
.LCFI3:
movq %rsp, %rbp
.LCFI4:
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -8(%rbp), %eax
addl -4(%rbp), %eax
leave
ret
.LFE6:
.size add, .-add
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x1
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB5
.long .LFE5-.LFB5
.uleb128 0x0
.byte 0x4
.long .LCFI0-.LFB5
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE1:
.LSFDE3:
.long .LEFDE3-.LASFDE3
.LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB6
.long .LFE6-.LFB6
.uleb128 0x0
.byte 0x4
.long .LCFI3-.LFB6
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI4-.LCFI3
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE3:
.ident "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-48)"
.section .note.GNU-stack,"",@progbits
I understand all of these instructions, but I really don't understand what these labels mean. .LC0, .LFB5, .LCFI0, .LCFI1, .LCFI2, .LFE5, ... These tags are automatically generated gcc. Why are these shortcuts needed? Some tags seem to be redundant.
- gcc version: 4.1.2
- machine: x86_64