When debugging and optimizing programs, developers sometimes need to generate and investigate into the assembly generated by the compiler. Generating a mixed source and assembly list will help a lot for debugging and optimization. gcc can achieve this by working with the assembler.

Generate assembly list mixed with the source code

Just add these gcc compile options:

-Wa,-adhln -g

The command:

$ gcc -Wa,-adhln -g source_code.c > assembly_list.s

The options:

-g: Produce debugging information
-Wa,option: Pass option as an option to the assembler
-adhln:
a: turn on listings
d: omit debugging directives; n: omit forms processing
h: include high-level source
l: include assembly

One example

The source code:

helloworld.c:

#include <stdio.h>
int main()
{
  printf("Hello world!\n");
  return 0;
}

The command:

$ gcc -Wa,-adhln -g helloworld.c > helloworld.s

helloworld.s:

    ...
    
    0:helloworld.c  **** #include <stdio.h>
    1:helloworld.c  ****
    2:helloworld.c  **** int main()
    3:helloworld.c  **** {
    19                            .loc 1 4 0
    20                            .cfi_startproc
    21 0000 55                    pushq   %rbp
    22                    .LCFI0:
    23                            .cfi_def_cfa_offset 16
    24 0001 4889E5                movq    %rsp, %rbp
    25                            .cfi_offset 6, -16
    26                    .LCFI1:
    27                            .cfi_def_cfa_register 6
    4:helloworld.c  ****   printf("Hello world!\n");
    28                            .loc 1 5 0
    29 0004 BF000000              movl    $.LC0, %edi
    29      00
    30 0009 E8000000              call    puts
    30      00
    5:helloworld.c  ****   return 0;
    31                            .loc 1 6 0
    32 000e B8000000              movl    $0, %eax
    32      00
    6:helloworld.c  **** }
    
    ...

Another example with more than 1 source files

You may also use the method here for compiling programs from more than 1 C source files. For example, a project contains 2 source files as follows.

fun1.c:

#include <stdio.h>

void fun1()
{
    printf("Hello world!\n");
}

main.c:

#include <stdio.h>
void fun1();
int main()
{
    fun1();
    return 0;
}

You can generate the source-assembly list by

$ gcc -Wa,-adhln -g fun1.c main.c -o a > helloworld.s

For your reference, the helloworld.s file is as follows.

   1              		.file	"fun1.c"
   2              		.text
   3              	.Ltext0:
   4              		.section	.rodata
   5              	.LC0:
   6 0000 48656C6C 		.string	"Hello world!"
   6      6F20776F 
   6      726C6421 
   6      00
   7              		.text
   8              		.globl	fun1
  10              	fun1:
  11              	.LFB0:
  12              		.file 1 "fun1.c"
   1:fun1.c        **** #include <stdio.h>
   2:fun1.c        **** 
   3:fun1.c        **** void fun1()
   4:fun1.c        **** {
  13              		.loc 1 4 0
  14              		.cfi_startproc
  15 0000 55       		pushq	%rbp
  16              		.cfi_def_cfa_offset 16
  17              		.cfi_offset 6, -16
  18 0001 4889E5   		movq	%rsp, %rbp
  19              		.cfi_def_cfa_register 6
   5:fun1.c        ****     printf("Hello world!\n");
  20              		.loc 1 5 0
  21 0004 BF000000 		movl	$.LC0, %edi
  21      00
  22 0009 E8000000 		call	puts
  22      00
   6:fun1.c        **** }
  23              		.loc 1 6 0
  24 000e 5D       		popq	%rbp
  25              		.cfi_def_cfa 7, 8
  26 000f C3       		ret
  27              		.cfi_endproc
  28              	.LFE0:
  30              	.Letext0:
   1              		.file	"main.c"
   2              		.text
   3              	.Ltext0:
   4              		.globl	main
   6              	main:
   7              	.LFB0:
   8              		.file 1 "main.c"
   1:main.c        **** #include <stdio.h>
   2:main.c        **** void fun1();
   3:main.c        **** int main()
   4:main.c        **** {
   9              		.loc 1 4 0
  10              		.cfi_startproc
  11 0000 55       		pushq	%rbp
  12              		.cfi_def_cfa_offset 16
  13              		.cfi_offset 6, -16
  14 0001 4889E5   		movq	%rsp, %rbp
  15              		.cfi_def_cfa_register 6
   5:main.c        ****     fun1();
  16              		.loc 1 5 0
  17 0004 B8000000 		movl	$0, %eax
  17      00
  18 0009 E8000000 		call	fun1
  18      00
   6:main.c        ****     return 0;
  19              		.loc 1 6 0
  20 000e B8000000 		movl	$0, %eax
  20      00
   7:main.c        **** }
  21              		.loc 1 7 0
  22 0013 5D       		popq	%rbp
  23              		.cfi_def_cfa 7, 8
  24 0014 C3       		ret
  25              		.cfi_endproc
  26              	.LFE0:
  28              	.Letext0:

About Eric Zhiqiang Ma

Eric Zhiqiang Ma is interested in operating systems and distributed computing and processing systems. Find Eric on Facebook, Twitter, LinkedIn and Google+. The views or opinions expressed here are solely Eric's own and do not necessarily represent those of any third parties.

7 comments:

  1. Hi,
    I have found the above commands you have suggested quite useful but i would like to know how can i use this command when there are mutiple files of code to be executed and I am interested in the assembly code of only one of those files ?

    1. You can use the same method to generate the source-assembly list from several source files. Note that the line numbers are followed with source file names like “1:fun1.c”. You may only check the parts that you are interested in.

  2. Hi Sir,

    Thank you very much for your explanation.
    I have one query, So from the above option we can get the list of source file but is it possible that “Can we get to know what and particular source file is going to be used for particular executable file (In case when source code generate two or more executable’s)” ..?
    Lets say:
    We have 5 source file, and 3 source files are used for “a.out” and rest 2 source files are used for “b.out” then “How can we get to know it that which source files is used for which “executable file”..?

    Thanks in advance

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>