How to convert gcc -S output to C code? - c

I have a program written in C which does a lot of processing on a 2d array and i would like to optimize it regarding function calls and cache line misses.
gcc -O3 performs really good but I would like to see what it really does or at least get an idea of it to help me do the same in the C code.
Now, the gcc -O3 -S outputs assembly and I was wondering if any of you guys know a way to get it back to C.
Or is there a way to get the output of O3 back to C code and see how it looks after optimization? Or at least a glimpse of it?

Related

Trying to grasp C bytecode... does/can GNU/gcc produce C bytecode like Clang/LLVM?

Recently I was told to look at how C functions are compiled into LLVM bytecode, and then how the LLVM bytecode is translated into x86 ASM. As a regular GNU/gcc user, I have some questions about this. To put it mildly.
Does GNU/gcc compile to bytecode, too? Can it? I was under the impression that gcc compiles directly into ASM. If not, is there a way to view the bytecode intermediary as there is with the clang command?
~$ clang ~/prog_name.c -S -emit-llvm -o - <== will show bytecode for prog_name.c.
Also, I find bytecode to be rather byzantine. By contrast, it makes assembly language seem like light reading. In other words: I have little idea what it is saying.
Does anyone have any advice or references for vaguely deciphering the information that the bytecode gives? Currently I compare and contrast with actual ASM, so to say it is slow going is a compliment.
Perhaps this is all comically naive, but I find it quite challenging to break through the surface of this.
Perhaps try taking a look at the language reference.
As far as I know, GCC does have an IR as well known as GIMPLE (another reference here).
If you mean that you would rather analyze the assembly output instead of the IR, you can take a look at this question which describes how to output an assembly file.

compiling a C file with gcc to get x86 assembly code

I have a C file heapsort.c which Im trying to compile on a 64 bit linux machine to output the corresponding assembly code. Im using the following command:
gcc -02 -S heapsort.c
when I type this Im getting this error message
gcc:error: unrecognized option '-02'
I tried googling this error but nothing helpful came up. Any suggestions on how to navigate this error and get the x86 output?
The flag is -O2, not -02. That's a letter O for "optimization", not a number 0. You might want to look into using a font that makes the difference more obvious.
I suggest even (as every pointed out is is the letter O not the digit 0)
gcc -O2 -fverbose-asm -S heapsort.c
The -fverbose-asm will give you more generated comments in the assembly file heapsort.s
BTW, passing -Wall to GCC is always a good habit.
if you are really curious and want to understand a bit more the internal representations inside GCC try even
gcc -fdump-tree-all -O2 -S heapsort.c
but be prepared to get a lot of files.
You'll get hundreds of them, matching heapsort.c.*!
If you want some crude GUI interface to query the Gimple internal representation at some arbitrary source code position, consider using MELT. MELT is mostly a high-level domain specific language (with a Lisp-like syntax, powerful pattern matching, object oriented, functional, dynamically typed, ....) to extend GCC, but you can also use its (crude) probe to query interactively some of the GCC internal representations.
It should be -O2 with 'O' not "zero"
Try -O2 instead of -02. It's a letter 'O' and shorthand for "optimization level 2".

Side by side C, x86 programs

Is there anywhere I can find side-by-side examples of dead simple C and x86 programs? The examples I've found so far on the Internet seem to jump straight from "here's Hello World in x86" to "write your own operating system!" I'm having trouble internalizing what has to happen when you do things like call a function.
I would recommend a look at GCC's intermediate assembly output, for example call
gcc -S a.c
then look at a.s
Most of the time, smaller and easier to understand assembly is generated by optimizing, so you would rather use
gcc -O -S a.c
If you mean x86 assembly language, use objdump --disassemble myprog (on any GNU system) to show the assembly language generated by your C program. If your system doesn't have objdump, you can use ndisasm.
Assuming you mean x86 assembler then with gcc you can use gcc -S yourhelloworldprogram.c to get assembler output. For Visual Studio you can get assembler output by following this: How do I get the assembler output from a C file in VS2005
I reccommend ddd. You can have the both C sources (if you built with debug symbols) and the machine code showing. You can also step over the code interactively probing register and memory values. A great learning tool.
On gcc you can use the -save-temps -fverbose-asm options which is better than the -S option because it still generates the object file and you get also the preprocessor file. The verbose-asm is also important because it adds comments to the assembly output that make the link between the function and variable names of your program and the generated assembly code. Especially when generating with optimization it often is difficult to make the link between the source C and the assembly.

Easy way to convert c code to x86 assembly?

Is there an easy way (like a free program) that can covert c/c++ code to x86 assembly?
I know that any c compiler does something very similar and that I can just compile the c code and then disassemble the complied executable, but that's kind of an overkill, all I want is to convert a few lines of code.
Does anyone know of some program that can do that?
EDIT: I know that GCC compiler does that but it's AT&T syntax and I'm looking for the Intel syntax (not sure if it's called intel syntax or not). The AT&T syntax looks a bit like gibberish to me and some commands use operands in reverse order and not how I'm used to and it can get really confusing.
GCC can output Intel syntax assembly using the following command line:
gcc -S input.c -o output.asm -masm=intel
Gcc can do it with the -S switch, but it will be disgustingly ugly at&t syntax.
gcc will generate assembly if you pass it the -S option on the command line.
Microsoft Visual C++ will do the same with the /FAs option.
The lcc compiler is a multiplatform cross-compiler. You can get it to produce Intel syntax assembly code by
lcc -S -Wf-target=x86/win32 foo.c
I find assembly code from lcc significantly easier to read than what gcc spits out nowawadays.
Your compiler is already doing that as you've stated, and most likely will have an option to stop before assembling.
For GCC, add the -S flag.
gcc -S x.c
cat x.s
Edit: If your program is pretty short, you could use the online service at https://gcc.godbolt.org/.
if you are using gcc as a compiler, you can compile with the -S option to produce assembly code. see http://www.delorie.com/djgpp/v2faq/faq8_20.html
As many people point out most compilers will do that. If you don't like the syntax,a bit of work with awk or sed should be able to translate. Or I'd be surprised if there wasn't a program that did that bit for you already written somewhere.
In VC++ the following command can be used to list the assembly code.
cl /FAs a.c
notice
every architecture has its own unique names and even build differently
now when you know the stacks involved using asm volatile
would b the perfect solution

how to see the optimized code in c

I can examine the optimization using profiler, size of the executable file and time to take for the execution.
I can get the result of the optimization.
But I have these questions,
How to get the optimized C code.
Which algorithm or method used by C to optimize a code.
Thanks in advance.
you can get an idea of optimization using the option -fdump-tree-optimized with gcc .
and you'll get an optimised file. you cannot run the code but using that you can get an idea of optimization . dont forget to include -O2 or -O3 or some other level.
Usually the code isn't optimized as C. Usually optimization passes are done long after the C has been converted into some form of intermediate representation that is easier for a compiler to work with in memory. Therefore, a direct answer to your question is that the optimized C code never exists.
A C compiler does not usually produce optimized C at any stage. Rather, the compiler turns C into a simplified internal representation, and most compiler optimizations will be done on one or more of those intermediate representations. Then the compiler generates assembly or a binary from that.
The closest you can get is probably to compile a file to assembly with no optimization and again with highest optimization, and then compare the assembly output. You will have to have a good grasp of assembly language to do that. If you are using gcc, read about the -S and -O switches for how to do (or not do) this.
If your goal is to write faster code, then, your best bet is to write better C by using better algorithms and data structures at the C level by carefully using the profiler.
If your goal is just to understand optimization, try Program Optimization and Compiler Optimization on Wikipedia for some general information.
If you're using GCC, use an argument to optimize the code and use --save-temps as an argument. Everyone saying C code isn't optimized as C when compiling with GCC is wrong to an extent. Write a recursive Fibonacci sequence generator in C, and read through the preprocessed code. The aforementioned argument also saves the generated assembly in the directory GCC is called from. If you're more comfortable with Intel-syntax assembly, use -masm=intel as an argument as well.
if you understand assembler, you can inspect the assembler generated code by compiler.

Resources