开发者

How can I see local variable symbol name in disassembly? (from C source)

开发者 https://www.devze.com 2023-02-16 04:30 出处:网络
If I compile a source like this, (with Clang, Mac OS X) int main() { int a = 4; int* b = &a; int c = *b;

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.


  1. 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
    
  2. 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
    
  3. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消