I am searching for a compiler or better IDE for C which could generate completely linked program, including functions from CRT, in assembler form. Is there any? I tried Visual C Express 2008. It has a disassembler, but its somewhat strange. I mean for some reason it shows many "strange" lines of code, such as mov a,#3
in about 100 lines.... It for study purposes. Thanks for tips.
views:
117answers:
5Don't know if it is going to help you but for learning internals I use IDAPro and OllyDbg and disasm (on linux/unix) and those served me a lot.
The command line options to do this, especially in Visual C++ Express, using the C++ compiler, is /Fa
-OUTPUT FILES-
/Fa[file] name assembly listing file
/FA[scu] configure assembly listing /Fd[file] name .PDB file
/Fe name executable file /Fm[file] name map file
/Fo name object file /Fp name precompiled header file /Fr[file] name source browser file /FR[file] name extended .SBR file /doc[file] process XML documentation comments and optionally name the .xdc file
That is where you will see the assembler output, by combining the preprocessor flags in conjunction, you should be able to see all of the outputs mixed in with assembler.
-PREPROCESSOR-
/AI add to assembly search path
/FU forced using assembly/module /C don't strip comments
/D{=|#} define macro /E preprocess to stdout
/EP preprocess to stdout, no #line /P preprocess to file
/Fx merge injected code to file /FI name forced include file
/U remove predefined macro /u remove all predefined macros
/I add to include search path /X ignore "standard places"
Most, if not, ALL compilers are capable of doing it, its a matter of figuring out which switches to use.
gcc will generate ASM files. If you use gcc -Wa,-adhln -g [source.c]
gcc and as will interleave the C source lines with the generated assembly code.
clang with LLVM will generate high quality ASM files.
Example:
This C function:
long Fibonacci(long x) {
if (x == 0) return 0;
if (x == 1) return 1;
return Fibonacci(x - 1) + Fibonacci(x - 2);
}
Becomes this ASM file:
_Fibonacci:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
subq $32, %rsp
Ltmp2:
movq %rdi, -16(%rbp)
movq -16(%rbp), %rax
cmpq $0, %rax
jne LBB1_2
movq $0, -8(%rbp)
jmp LBB1_5
LBB1_2:
movq -16(%rbp), %rax
cmpq $1, %rax
jne LBB1_4
movq $1, -8(%rbp)
jmp LBB1_5
LBB1_4:
movq -16(%rbp), %rax
movabsq $1, %rcx
subq %rcx, %rax
movq %rax, %rdi
callq _Fibonacci
movq -16(%rbp), %rcx
movabsq $2, %rdx
subq %rdx, %rcx
movq %rcx, %rdi
movq %rax, -24(%rbp)
callq _Fibonacci
movq -24(%rbp), %rcx
addq %rax, %rcx
movq %rcx, -8(%rbp)
LBB1_5:
movq -8(%rbp), %rax
addq $32, %rsp
popq %rbp
ret
Leh_func_end1:
When you do this, you will want optimizations OFF.
It is also possible to interleave the generated ASM code with the higher level source, such as the writer has done HERE.
A normal compiler has nothing to do with the code after it's linked. The compiler can produce assembly output for a single file, but to get post-linking results you'll pretty much need to use a disassembler instead. As @dgarcia note, IDAPro is a very good one. Since you're apparently working on Windows you can also use dumpbin /disasm
. It isn't as nice as IDAPro, but it is free.