If I compile a source like this, (with Clang, Mac OS X)
int main()
{
int a = 4;
int* b = &a;
int c = *b;
return 6;
}
compiled object file will be disassembled like this. (with otool
, Mac OS X)
main.o:
(__TEXT,__text) section
_main:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp,%rbp
0000000000000004 movl $0x00000006,%eax
0000000000000009 leaq 0xf8(%rbp),%rcx
000000000000000d movl $_main,0xfc(%rbp)
0000000000000014 movl $0x0000开发者_Go百科0004,0xf8(%rbp)
000000000000001b movq %rcx,0xf0(%rbp)
000000000000001f movq 0xf0(%rbp),%rcx
0000000000000023 movl (%rcx),%edx
0000000000000025 movl %edx,0xec(%rbp)
0000000000000028 popq %rbp
0000000000000029 ret
Is it possible to see local variable symbol name in disassembly? Just like debugger does. If possible, how can I do that?
There are no symbols other than _main
in your program. You have to do both of these: make a program that actually uses symbols (define a (non-inlined) function) and use your compiler's command-line-arguments to make it dump debug information.
Compile with -fverbose-asm
. Here's the description:
Put extra commentary information in the generated assembly code to make it more readable. This option is generally only of use to those who actually need to read the generated assembly code (perhaps while debugging the compiler itself).
-fno-verbose-asm
, the default, causes the extra information to be omitted and is useful when comparing two assembler files.
- Use a compiler/options which actually includes local symbols into debuginfo.
For example with VS 2005 a compiler asm listing (similar to gcc -S) looks like this:
; Line 3 push ebp mov ebp, esp sub esp, 12 ; 0000000cH ; Line 4 mov DWORD PTR _a$[ebp], 4 ; Line 5 lea eax, DWORD PTR _a$[ebp] mov DWORD PTR _b$[ebp], eax ; Line 6 mov ecx, DWORD PTR _b$[ebp] mov edx, DWORD PTR [ecx] mov DWORD PTR _c$[ebp], edx ; Line 7 mov eax, 6 ; Line 8 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
- Use a disassembler that supports debug info.
For example (with Ida;
btw there're free/eval versions of Ida - like there http://www.hex-rays.com/idapro/idadown.htm)
.text:00401010 ; int __cdecl main() .text:00401010 _main proc near ; CODE XREF: _main_0j .text:00401010 .text:00401010 c = dword ptr -0Ch .text:00401010 b = dword ptr -8 .text:00401010 a = dword ptr -4 .text:00401010 .text:00401010 push ebp .text:00401011 mov ebp, esp .text:00401013 sub esp, 0Ch .text:00401016 mov [ebp+a], 4 .text:0040101D lea eax, [ebp+a] .text:00401020 mov [ebp+b], eax .text:00401023 mov ecx, [ebp+b] .text:00401026 mov edx, [ecx] .text:00401028 mov [ebp+c], edx .text:0040102B mov eax, 6 .text:00401030 mov esp, ebp .text:00401032 pop ebp .text:00401033 retn .text:00401033 _main endp
- I'd suggest making a sample with unique local var names (not 'a' which can be found in random places) and finding compiler/options for which that name would be present in debuginfo.
Unless you've compiled your code with debugging information and you're using a disassembler that can read that debugging information you're out of luck. Local variables have no name outside of your source code. They're just convenient labels used in your source to refer to a memory location (or, if optimized, a register).
The only symbolic names you're going to see in the object code are those which have to be available for linking to by external modules, so things like non-static global variables and non-static functions and the like.
If you're doing this to learn how your compiler generates code, your best bet is to tell your compiler to generate assembly language source and read that. Most compilers will generate assembler with annotations to tell you what line(s) of code are associated with which blocks of assembly language.
You may find -save-temps
to be useful. It saves intermediate files during compilation, this includes the preprocessor output, and the compiler assembly output.
See also Useful GCC flags for C.
精彩评论