解决装配循环问题

时间:2018-10-19 05:44:18

标签: assembly x86-64

有人可以帮助我解密第49-72行吗?我知道这是一个从1到6的循环,但是我的答案似乎随着输出的变化而不同。例如,如果我输入0 1 2 3 4 5,则不会在0炸弹。但是,如果我输入0 2 4 6 8 10,则炸弹在0炸弹?我对为什么感到困惑。

   0x0000000000400f49 <+0>:     push   %rbp
   0x0000000000400f4a <+1>:     push   %rbx
   0x0000000000400f4b <+2>:     sub    $0x28,%rsp
   0x0000000000400f4f <+6>:     mov    %fs:0x28,%rax
   0x0000000000400f58 <+15>:    mov    %rax,0x18(%rsp)
   0x0000000000400f5d <+20>:    xor    %eax,%eax
   0x0000000000400f5f <+22>:    mov    %rsp,%rsi
   0x0000000000400f62 <+25>:    callq  0x4016c6 <read_six_numbers>
   0x0000000000400f67 <+30>:    cmpl   $0x0,(%rsp)
   0x0000000000400f6b <+34>:    jns    0x400f72 <phase_2+41>
   0x0000000000400f6d <+36>:    callq  0x401690 <explode_bomb>
   0x0000000000400f72 <+41>:    mov    %rsp,%rbp
   0x0000000000400f75 <+44>:    mov    $0x1,%ebx
   0x0000000000400f7a <+49>:    mov    %ebx,%eax
   0x0000000000400f7c <+51>:    add    0x0(%rbp),%eax
   0x0000000000400f7f <+54>:    cmp    %eax,0x4(%rbp)
   0x0000000000400f82 <+57>:    je     0x400f89 <phase_2+64>
   0x0000000000400f84 <+59>:    callq  0x401690 <explode_bomb>
   0x0000000000400f89 <+64>:    add    $0x1,%ebx
   0x0000000000400f8c <+67>:    add    $0x4,%rbp
   0x0000000000400f90 <+71>:    cmp    $0x6,%ebx
   0x0000000000400f93 <+74>:    jne    0x400f7a <phase_2+49>
   0x0000000000400f95 <+76>:    mov    0x18(%rsp),%rax
   0x0000000000400f9a <+81>:    xor    %fs:0x28,%rax
   0x0000000000400fa3 <+90>:    je     0x400faa <phase_2+97>
   0x0000000000400fa5 <+92>:    callq  0x400b90 <__stack_chk_fail@plt>
   0x0000000000400faa <+97>:    add    $0x28,%rsp
   0x0000000000400fae <+101>:   pop    %rbx
   0x0000000000400faf <+102>:   pop    %rbp
   0x0000000000400fb0 <+103>:   retq

1 个答案:

答案 0 :(得分:0)

  

但是,如果我输入0 2 4 6 8 10,炸弹将在0爆炸?我对为什么感到困惑。

因为如果input[ebx] != input[ebx-1] + ebx

,该循环会炸弹爆炸。

这是第一次迭代的样子:

mov    %rsp,%rbp           ; rbp = &input[0]
mov    $0x1,%ebx           ; ebx = 1
repeat:
    mov    %ebx,%eax       ; eax = 1
    add    0x0(%rbp),%eax  ; eax = input[0] + 1
    cmp    %eax,0x4(%rbp)  ; flags = input[1] - (input[0] + 1)
    je     no_explode      ; if (flags.z) goto no_explode
    callq  explode_bomb
    no_explode:
    add    $0x1,%ebx       ; ebx++
    ...

因此,如果输入为0 1 2 3 4 5,则在第一个迭代中,该比较的左侧为1,右侧为1(0 + 1),如下所示:好。因此,没有爆炸。

相反,如果输入是0 2 4 6 8 10,那么您会在左侧看到2,在右侧看到1 =>炸弹熄灭。