Solidus Code
How do you get assembler output from a C/C++ source file using gcc or g++?

To see the assembly equivalent of your current c or c++ source could follow these easy steps.

Lets you you have the following source could :

  • Source Code
  • Compiling
  • simple-io.c
    #include <stdlib.h> #include <stdio.h> void loop_message ( char *msg , int num_loops ) { for(int count =0; count < num_loops; count ++){ printf("%d ",(count+1)); printf(msg, num_loops); printf("\n"); } printf("\n");//Force new line } int main(int argc,char *argv[]){ // c programs are always called with at least 1 argument (the program name) printf("Input & Output: # Arguments = %d\n",argc) ; // program was invoked with at least 1 real parameter, out put it here if ( argc > 1) { int i=0; for(i=1; i < argc; i++) { printf("\t: arg[%d] = \"%s\" \n",i, argv[i]); } printf("\n"); }else { printf("\t: No input arguments supplies\n"); } int user_number=0; printf("\n\nHow many times should message loop: "); // Remember scanf must match is looking for exact pattern match scanf("%d", &user_number); char my_message[] = "Print this message %dx"; loop_message (my_message, user_number); return 0; }
    C
  • compiling
    gcc -o simple-io simple-io.c
    Command-Line

    If you do not have gcc or g++ on your linux system, do the following: assuming you are on ubuntu.

    sudo apt update      // updates repository
    sudo apt install build-essentials //install software building packages
    gcc --version       // test to installation
    
    //To compile:
    gcc -o [Executable_Program_Name] [file1.c file2.c  . . . fileN.c]
    
    //Compile with detailed error log
    gcc -Wall -o [error_log] [file1.c file2.c  . . . fileN.c]
    C

    Here are some frequently used flags with gcc and g++.

    FlagsDescription
    -oThis allow specify the output name of the executable file gcc/g++ is creating.
    -WallCompile and display any warnings or additional error messages the compiler found within your source code
    -Scompile the source code and produce the assembly file used for buidling the executable. We will use this later on in the blog.
    -CInstruct the assembly to ONLY produce the object (compiled code) without link them into the final executable file
    -save-tempsThis flag is very helpful if you want to to create the final executable file, produce the individual object files used in building the executable, and to get the assembly code of your source code.
    -lFor example "lSomelibrary". This flag is used to instruct gcc to link to a shared library file - "Somelibrary.so".
    -fPICUsed when needing to create shared library. This ensures the code's address is position indepent as it will be reference from other applications as needed. Add this flag when generating the object files. Then link the object files to the file output file using "gcc -shared -o libCfile.so Cfile.o"

This program output back to the user the set of input parameters used to invoke the program.  So if you invoked the program like below. 

./simple-io param1 parm2 etc
Command-Line

It will render out param1, param2, . . . and so forth.

Lastly, the program then prompts the user to enter a number which will then we used to loop the message "Print this message %dx".Finally the program exits.

Disassembling from source code

Now that you have a source code, to get an x86 disassembly of the file run the following:

gcc -Wall -S simple-io.c
Command-Line

In this example, the equivalent assembly for our sample c program is the following:

  • AT&T Syntax
  • Intel Syntax
  • gcc -Wall -S simple-io.c
    Command-Line
  • gcc -Wall -S -masm=intel simple-io.c
    Assembly

Here is an example of an intel disassembly of your source code:

	.file	"simple-io.c"
	.intel_syntax noprefix
	.text
	.section	.rodata
.LC0:
	.string	"%d "
	.text
	.globl	loop_message
	.type	loop_message, @function
loop_message:
.LFB6:
	.cfi_startproc
	endbr64
	push	rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	mov	rbp, rsp
	.cfi_def_cfa_register 6
	sub	rsp, 32
	mov	QWORD PTR -24[rbp], rdi
	mov	DWORD PTR -28[rbp], esi
	mov	DWORD PTR -4[rbp], 0
	jmp	.L2
.L3:
	mov	eax, DWORD PTR -4[rbp]
	add	eax, 1
	mov	esi, eax
	lea	rdi, .LC0[rip]
	mov	eax, 0
	call	printf@PLT
	mov	edx, DWORD PTR -28[rbp]
	mov	rax, QWORD PTR -24[rbp]
	mov	esi, edx
	mov	rdi, rax
	mov	eax, 0
	call	printf@PLT
	mov	edi, 10
	call	putchar@PLT
	add	DWORD PTR -4[rbp], 1
.L2:
	mov	eax, DWORD PTR -4[rbp]
	cmp	eax, DWORD PTR -28[rbp]
	jl	.L3
	mov	edi, 10
	call	putchar@PLT
	nop
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE6:
	.size	loop_message, .-loop_message
	.section	.rodata
	.align 8
.LC1:
	.string	"Input & Output: # Arguments = %d\n"
.LC2:
	.string	"\t: arg[%d] = \"%s\" \n"
	.align 8
.LC3:
	.string	"\t: No input arguments supplies"
	.align 8
.LC4:
	.string	"\n\nHow many times should message loop: "
.LC5:
	.string	"%d"
	.text
	.globl	main
	.type	main, @function
main:
.LFB7:
	.cfi_startproc
	endbr64
	push	rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	mov	rbp, rsp
	.cfi_def_cfa_register 6
	sub	rsp, 64
	mov	DWORD PTR -52[rbp], edi
	mov	QWORD PTR -64[rbp], rsi
	mov	rax, QWORD PTR fs:40
	mov	QWORD PTR -8[rbp], rax
	xor	eax, eax
	mov	eax, DWORD PTR -52[rbp]
	mov	esi, eax
	lea	rdi, .LC1[rip]
	mov	eax, 0
	call	printf@PLT
	cmp	DWORD PTR -52[rbp], 1
	jle	.L5
	mov	DWORD PTR -36[rbp], 0
	mov	DWORD PTR -36[rbp], 1
	jmp	.L6
.L7:
	mov	eax, DWORD PTR -36[rbp]
	cdqe
	lea	rdx, 0[0+rax*8]
	mov	rax, QWORD PTR -64[rbp]
	add	rax, rdx
	mov	rdx, QWORD PTR [rax]
	mov	eax, DWORD PTR -36[rbp]
	mov	esi, eax
	lea	rdi, .LC2[rip]
	mov	eax, 0
	call	printf@PLT
	add	DWORD PTR -36[rbp], 1
.L6:
	mov	eax, DWORD PTR -36[rbp]
	cmp	eax, DWORD PTR -52[rbp]
	jl	.L7
	mov	edi, 10
	call	putchar@PLT
	jmp	.L8
.L5:
	lea	rdi, .LC3[rip]
	call	puts@PLT
.L8:
	mov	DWORD PTR -40[rbp], 0
	lea	rdi, .LC4[rip]
	mov	eax, 0
	call	printf@PLT
	lea	rax, -40[rbp]
	mov	rsi, rax
	lea	rdi, .LC5[rip]
	mov	eax, 0
	call	__isoc99_scanf@PLT
	movabs	rax, 7526676561683640912
	movabs	rdx, 7022083123460469609
	mov	QWORD PTR -32[rbp], rax
	mov	QWORD PTR -24[rbp], rdx
	mov	DWORD PTR -16[rbp], 622880103
	mov	WORD PTR -12[rbp], 30820
	mov	BYTE PTR -10[rbp], 0
	mov	edx, DWORD PTR -40[rbp]
	lea	rax, -32[rbp]
	mov	esi, edx
	mov	rdi, rax
	call	loop_message
	mov	eax, 0
	mov	rcx, QWORD PTR -8[rbp]
	xor	rcx, QWORD PTR fs:40
	je	.L10
	call	__stack_chk_fail@PLT
.L10:
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE7:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	 1f - 0f
	.long	 4f - 1f
	.long	 5
0:
	.string	 "GNU"
1:
	.align 8
	.long	 0xc0000002
	.long	 3f - 2f
2:
	.long	 0x3
3:
	.align 8
4:
Assembly

Soliduscode

Thank you for visiting.  Please check back regularly for updated content.

©SolidusCode 2024

Proudly powered by JxtPress