【发布时间】:2017-05-15 05:44:22
【问题描述】:
我对这个程序集中发生的事情有点困惑。我可以看到,如果不输入六个数字,炸弹就会爆炸并结束程序。逐行检查输入,如果六个数字非负则进入循环。我在这里迷路了0x0000000000400f29 <+29>: add -0x4(%rbp),%eax。
看起来很简单,但我真的不明白这里添加了什么。它是添加-4然后将其与0进行比较吗?然后如果相等就跳?
我基本上是在寻找关于循环的具体说明,以及预期在循环中继续的输入模式。
转储
0x0000000000400f0c <+0>: push %rbp
0x0000000000400f0d <+1>: push %rbx
0x0000000000400f0e <+2>: sub $0x28,%rsp
0x0000000000400f12 <+6>: mov %rsp,%rsi
0x0000000000400f15 <+9>: callq 0x40165a <read_six_numbers>
0x0000000000400f1a <+14>: cmpl $0x0,(%rsp)
0x0000000000400f1e <+18>: jns 0x400f44 <phase_2+56>
0x0000000000400f20 <+20>: callq 0x401624 <explode_bomb>
0x0000000000400f25 <+25>: jmp 0x400f44 <phase_2+56>
0x0000000000400f27 <+27>: mov %ebx,%eax
=> 0x0000000000400f29 <+29>: add -0x4(%rbp),%eax
0x0000000000400f2c <+32>: cmp %eax,0x0(%rbp)
0x0000000000400f2f <+35>: je 0x400f36 <phase_2+42>
0x0000000000400f31 <+37>: callq 0x401624 <explode_bomb>
0x0000000000400f36 <+42>: add $0x1,%ebx
0x0000000000400f39 <+45>: add $0x4,%rbp
0x0000000000400f3d <+49>: cmp $0x6,%ebx
0x0000000000400f40 <+52>: jne 0x400f27 <phase_2+27>
0x0000000000400f42 <+54>: jmp 0x400f50 <phase_2+68>
0x0000000000400f44 <+56>: lea 0x4(%rsp),%rbp
0x0000000000400f49 <+61>: mov $0x1,%ebx
0x0000000000400f4e <+66>: jmp 0x400f27 <phase_2+27>
0x0000000000400f50 <+68>: add $0x28,%rsp
0x0000000000400f54 <+72>: pop %rbx
0x0000000000400f55 <+73>: pop %rbp
0x0000000000400f56 <+74>: retq
End of assembler dump.
read_six_numbers
Dump of assembler code for function read_six_numbers:
=> 0x000000000040165a <+0>: sub $0x18,%rsp
0x000000000040165e <+4>: mov %rsi,%rdx
0x0000000000401661 <+7>: lea 0x4(%rsi),%rcx
0x0000000000401665 <+11>: lea 0x14(%rsi),%rax
0x0000000000401669 <+15>: mov %rax,0x8(%rsp)
0x000000000040166e <+20>: lea 0x10(%rsi),%rax
0x0000000000401672 <+24>: mov %rax,(%rsp)
0x0000000000401676 <+28>: lea 0xc(%rsi),%r9
0x000000000040167a <+32>: lea 0x8(%rsi),%r8
0x000000000040167e <+36>: mov $0x402871,%esi
0x0000000000401683 <+41>: mov $0x0,%eax
0x0000000000401688 <+46>: callq 0x400c30 <__isoc99_sscanf@plt>
0x000000000040168d <+51>: cmp $0x5,%eax
0x0000000000401690 <+54>: jg 0x401697 <read_six_numbers+61>
0x0000000000401692 <+56>: callq 0x401624 <explode_bomb>
0x0000000000401697 <+61>: add $0x18,%rsp
0x000000000040169b <+65>: retq
End of assembler dump.
【问题讨论】:
-
哪一部分是
C? -
它将
rbp-4指向的内存位置的值添加到eax,然后将eax与内存位置rbp的值进行比较 -
如果说这是响应
C代码而生成的程序集,难道不正确吗? -
我在问题中没有看到 C 语言的语法中的任何内容,也没有提到 C。为什么 C 标记在那里?您想显示作为该程序集源的 C 代码吗?如果是这样的话。
-
愚蠢的 AT&T 语法一如既往地令人困惑。
add -0x4(%rbp),%eax在 Intel 语法中是add eax, [rbp-4],这意味着“将存储在 rbp-4 中的值添加到 eax”(在伪 C 中,它类似于eax+=*((uint32_t *)rbp-1)- -1 而不是 -4,因为指针算术是如何工作的在 C)。长话短说,它只是添加一个局部变量的值(记住:根据经验,rbp+something 是堆栈上的参数,rbp-something 是本地变量)。