I'm writing some methods in C that must run very efficiently, so I'd like to manually edit some of the assembly code that is automatically generated.
I know how to read the assembly code using gdb or "objdump -d myfile.o", but can anyone tell me how to edit this code? (Will probably just be minor tweaks.)
gcc have -S switch, which stops compilation on after assembly generation phase. Then you cound edit resulting file and manually call assembly (with gas, for example)
Sure. It's called "inline assembly", and most compilers support it.
Here's an example using GCC:
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
There's no way you can do it.
Compiler generates code directly, there is no assembler involved; assembly listing is an aux product that can be generated, can be not.
You can take asm listing and assemble it yourself, however.
If you want to improve efficiency of your code, the best way to follow is, as stated before, inline asm; or write an assembly proc, make an object file and link it.
Related
I'm writing a proof-of-concept JIT compiler in C, which at the moment is generating strings of assembly code. The inline assembly functionality in C only deals with string literals that are known at compile time, so I can't use it to run my generated-at-runtime code.
I've read about using mmap() to execute generated machine code at runtime, but I'd like to avoid working with machine code if possible.
Does anyone know of any solutions? I've thought of writing it to a file and invoking the assembler & linker on said file, but that'd be messy and slow.
I think ultimately to be "JIT" you need to be time sensitive which means generate machine code. You might try putting in some debug code that generates both machine code to run and assembly code to verify, run the assembler compare the machine code from the assembly language to the machine code you generated directly and use that to debug/validate the machine code (if possible, sometimes assemblers want to do their own thing, not what you wanted them to do).
What I've done is generate C/C++/Fortran code, compile it on the fly, link it into a DLL, and dynamically load the DLL, all of which takes on the order of a few seconds at most.
You could do the same, except generate ASM.
It's a very effective technique when you need speed of the resulting code, plus the flexibility of the code (and run-time libraries) of the language you're generating.
I've been looking through questions on here and the internet for a while now and I cannot seem to find out whether or not it is possible to do inline assembly with GCC using something other than GAS. I am trying to find if I can avoid using not only GAS's AT&T syntax (though, I know how to use Intel syntax with GAS) but the extended asm format. While this is not for a project or anything other than my own curiosity, I would really appreciate any help I can get (this is actually my first question here because I could not find an answer about it)! Also, if this makes any difference, I'm currently using DevC++ (for C code, not C++) on Windows.
Thanks,
Tom
You can link the output from an assembler (a ".o" or ".obj" file) with your C or C++ program. Put your assembler code in a text file. Your IDE or makefile will assemble it just as it would any c source file. The only tricky bit is learning how to interface between the two different systems.
You cannot use another inline assembly syntax with GCC. inline assembly is implemented by GCC literally including the assembly you write inline with its own (textual) assembly output, which it then sends to gas to be assembled. Since GCC doesn't know how to change the format of its own output to feed to another assembler, you can't change the inline assembly, either.
I am looking at lots of assembly language code that is compiled along with c. They are using simple #define assembly without any headers in boot.s code. How does this work ?
Typically .s files are processed by an assembler. Without knowing any other details, there's nothing more to say. .s file goes in, .o file comes out.
Many assemblers provide some kind of include directive to allow use of headers, which would also be in assembly language.
Ah, the code you linked is for use by the GNU as assembler. If you're on Linux or Mac, do man as to learn about it. If you're on Windows, install MinGW or Cygwin.
Compilers can frequently include in-line assembly, but I believe it is compiler specific.
I don't remember the precise details, but I think its something like:
void myFunc(void)
{
int myNum; /* plain old C */
__asm /* Assembly */
{
mov ax,bx;
xor cx,cx;
}
myNum = 5; /* more C */
}
Research your specific compiler for details.
The link you post in your comment is an assembly language source file that is meant to be first run through a c-preprocessor. It's just a programming convenience, but lots of assembly language compilers support similar constructs anyway, so I'm not sure why they went the c-preprocessor route.
If you have "main proc" inside of your code, you are using x86 architecture and your file ends with .asm you con use for compilation:
tasm fileName.asm
In result you will get your fileName.obj file. After that you need to link it and for
that you can use tlink filename.obj
To run, just enter the filename.exe on the command line
If you need to link more than one file use tlink filename1.obj filename2.obj and so on
during the compilation and linking is not necessary to specify the file extension like .obj or .asm. Using just filename should be fine.
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.
I'm trying to test a rather threading-sensitive area in my program and was wondering if there's a way to force gcc to insert a call after every instruction it emits so that I can manually yield to a different thread?
Thanks,
Robert
No, GCC does not has such an option.
However, you may be able hack together a script that does that job. You can compile your code to assembler using the -S option. Compiler generated assembler is relative easy to parse.
Don't forget to save the flags and all registers inside your debugging code though.