炸弹实验室组装说明

Bomb lab assembly explanation

我在做炸弹实验室,我猜对了这是斐波那契数列 (0 1 1 2 3 5)。我无法理解以下几行:8048d11-8048d1a

08048ce6 <phase_2>:
 8048ce6:       55                      push   %ebp
 8048ce7:       89 e5                   mov    %esp,%ebp
 8048ce9:       56                      push   %esi
 8048cea:       53                      push   %ebx
 8048ceb:       83 ec 30                sub    [=10=]x30,%esp
 8048cee:       8d 45 e0                lea    -0x20(%ebp),%eax
 8048cf1:       89 44 24 04             mov    %eax,0x4(%esp)
 8048cf5:       8b 45 08                mov    0x8(%ebp),%eax
 8048cf8:       89 04 24                mov    %eax,(%esp)
 8048cfb:       e8 ca 04 00 00          call   80491ca <read_six_numbers>
 8048d00:       83 7d e0 00             cmpl   [=10=]x0,-0x20(%ebp)
 8048d04:       75 06                   jne    8048d0c <phase_2+0x26>
 8048d06:       83 7d e4 01             cmpl   [=10=]x1,-0x1c(%ebp)
 8048d0a:       74 05                   je     8048d11 <phase_2+0x2b>
 8048d0c:       e8 77 04 00 00          call   8049188 <explode_bomb>
 8048d11:       8d 5d e8                lea    -0x18(%ebp),%ebx
 8048d14:       8d 75 f8                lea    -0x8(%ebp),%esi
 8048d17:       8b 43 fc                mov    -0x4(%ebx),%eax
 8048d1a:       03 43 f8                add    -0x8(%ebx),%eax
 8048d1d:       39 03                   cmp    %eax,(%ebx)
 8048d1f:       74 05                   je     8048d26 <phase_2+0x40>
 8048d21:       e8 62 04 00 00          call   8049188 <explode_bomb>
 8048d26:       83 c3 04                add    [=10=]x4,%ebx
 8048d29:       39 f3                   cmp    %esi,%ebx
 8048d2b:       75 ea                   jne    8048d17 <phase_2+0x31>
 8048d2d:       83 c4 30                add    [=10=]x30,%esp
 8048d30:       5b                      pop    %ebx
 8048d31:       5e                      pop    %esi
 8048d32:       5d                      pop    %ebp
 8048d33:       c3                      ret

我知道它保留了一个 tmp 变量来存储前一个元素,并将它加起来并与 8048d1d 的下一个进行比较。它是如何做到这一点的(通过 lea、mov 和 add)?

基本上就是这样:

int array[6];             // at ebp-0x20
int *ebx = &array[2];     // lea    -0x18(%ebp),%ebx
int *esi = &array[6];     // lea    -0x8(%ebp),%esi
do {
    int eax = *(ebx - 1); // mov    -0x4(%ebx),%eax
    eax += *(ebx - 2);    // add    -0x8(%ebx),%eax
    if (eax != *ebx)      // cmp    %eax,(%ebx)
        explode_bomb();
    ebx++;                // add    [=10=]x4,%ebx
} while (ebx != esi);

请记住,C 指针算法会自动按项目大小缩放,但程序集始终以字节为单位。 ebx 是指向当前元素的指针,代码将前两个相加并检查是否相等。 esi 是指向数组末尾的指针,用于退出循环。