Понимание разборки - Увидеть два main () - PullRequest
1 голос
/ 15 ноября 2010

Дамп следующей 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<2 или i<10, я вижу два main() с такой же структурой.Может кто-нибудь сказать мне, почему это происходит?

Ответы [ 2 ]

2 голосов
/ 15 ноября 2010

дизассемблер покорно чередует исходный код в точности так, как говорится в выходной отладочной информации компилятора.В 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
…

Мой компилятор, очевидно, немного отличается от вашего, так как адреса разные, но вы видите, как это работает: отображение между адресами в выводесборка и строки во входном исходном файле неточные.

2 голосов
/ 15 ноября 2010

Вы не видите двух main() с. Вы видите дизассемблер, совершенно сбитый с толку циклом for. Фактическая сборка, если вы прочитали ее полностью, представляет ровно одну функцию, main(), и логический путь идентичен коду C.

Вкратце: C, чередующийся в сборке, является неправильным .

...