2010-11-15 21 views
1

以下C程序的转储():了解拆卸 - 眼看着两个主要的

int main() { 
    int i,j; 
    for(i=0; i<2; i++) { 
     j++; 
    } 
    return 0; 
} 

是生产:

08048394 <main>: 
int main() { 
8048394: 8d 4c 24 04    lea 0x4(%esp),%ecx 
8048398: 83 e4 f0    and $0xfffffff0,%esp 
804839b: ff 71 fc    pushl -0x4(%ecx) 
804839e: 55      push %ebp 
804839f: 89 e5     mov %esp,%ebp 
80483a1: 51      push %ecx 
80483a2: 83 ec 10    sub $0x10,%esp 
    int i,j; 
    for(i=0; i<2; i++) { 
80483a5: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) 
80483ac: eb 08     jmp 80483b6 <main+0x22> 
     j++; 
80483ae: 83 45 f4 01    addl $0x1,-0xc(%ebp) 
int main() { 
    int i,j; 
    for(i=0; i<2; i++) { 
80483b2: 83 45 f8 01    addl $0x1,-0x8(%ebp) 
80483b6: 83 7d f8 01    cmpl $0x1,-0x8(%ebp) 
80483ba: 7e f2     jle 80483ae <main+0x1a> 
     j++; 
    } 
    return 0; 
80483bc: b8 00 00 00 00   mov $0x0,%eax 
} 

不管我是否把i<2i<10,我看到两个main()的结构相同。有人能告诉我为什么会发生这种情况吗?

回答

2

你没有看到两个main() s。一个for循环让你看到一个反汇编者完全混淆了它。实际装配,如果你一直读完,代表的只是一个功能,main(),而逻辑路径与C代码完全相同。

总之:C交错组装为错误

+0

哦!那么你能否告诉我这是干什么的:'jmp 80483b6 '和'jle 80483ae '?最后,有没有办法改善这种拆卸? – Legend 2010-11-15 04:15:45

+3

我不会错过反汇编,拆卸看起来不错;它只是将目标文件中的调试信息派生出来,该文件包含从源文件:行到输出的映射,但并不总是准确的。 – ephemient 2010-11-15 04:55:17

+0

@Legend:'jmp'从for循环的初始化代码('i = 0')跳转到test('i <2')。 'jle'是一个跳跃式if-less-than-or-to-to,它将'i'与'1'进行比较(编译器将'i <2'优化为'i <= 1')。如果它小于或等于1,则将控制权转移给for循环的主体。 – cdhowie 2010-11-15 18:42:56

2

反汇编器完全按照编译器的输出调试信息所说的完全交错源代码。在Linux上,你可以用objdump -W看到:

 
… 
Line Number Statements: 
    Extended opcode 2: set Address to 0x80483e4 
    Copy 
    Special opcode 91: advance Address by 6 to 0x80483ea and Line by 2 to 3 
    Special opcode 132: advance Address by 9 to 0x80483f3 and Line by 1 to 4 
    Special opcode 60: advance Address by 4 to 0x80483f7 and Line by -1 to 3 
    Special opcode 148: advance Address by 10 to 0x8048401 and Line by 3 to 6 
    Special opcode 76: advance Address by 5 to 0x8048406 and Line by 1 to 7 
    Advance PC by 2 to 0x8048408 
    Extended opcode 1: End of Sequence 
… 

我的编译器显然有些不同,从你们的,地址是不同的,但你看它是如何工作:在输出组件和行地址之间的映射输入源文件不准确。