【发布时间】:2016-02-24 22:13:21
【问题描述】:
我是组装新手,真的不知道发生了什么。
我正在尝试完成一项家庭作业,其中我们必须通过找出程序五个阶段的正确输入来拆除炸弹。
我尝试在网上寻找我的问题的答案,但我真的不知道要搜索什么才能找到我正在寻找的答案。
我相信我理解下面代码中从<+0> 到<+35> 的所有内容。在<+40> 调用 cmp 运算符来比较$0x2 和%eax 寄存器中存储的内容。在进行比较时,我相信 %eax 仍在存储对 scanf 的函数调用(如果我错了,请纠正我)。
通过使用 gdb,我知道 scanf 函数的调用如下:
scanf("%d %d", &x, &y);
那么在这种情况下,$0x2 到底指的是什么(只是值 2?)以及比较这两个项目时发生了什么?
我相信这是 GAS 语法。
0x0804870a <+0>: sub $0x2c,%esp
0x0804870d <+3>: lea 0x1c(%esp),%eax
0x08048711 <+7>: mov %eax,0xc(%esp)
0x08048715 <+11>: lea 0x18(%esp),%eax
0x08048719 <+15>: mov %eax,0x8(%esp)
0x0804871d <+19>: movl $0x8048baa,0x4(%esp)
0x08048725 <+27>: mov 0x804b040,%eax
0x0804872a <+32>: mov %eax,(%esp)
0x0804872d <+35>: call 0x8048480 <__isoc99_fscanf@plt>
0x08048732 <+40>: cmp $0x2,%eax
0x08048735 <+43>: je 0x8048743 <phase_1_of_5+57>
0x08048737 <+45>: movl $0x1,(%esp)
0x0804873e <+52>: call 0x80486ef <explode>
0x08048743 <+57>: mov 0x18(%esp),%eax
0x08048747 <+61>: mov %eax,%edx
0x08048749 <+63>: shl $0x5,%edx
0x0804874c <+66>: add %edx,%eax
0x0804874e <+68>: cmp 0x1c(%esp),%eax
0x08048752 <+72>: je 0x8048760 <phase_1_of_5+86>
0x08048754 <+74>: movl $0x1,(%esp)
0x0804875b <+81>: call 0x80486ef <explode>
0x08048760 <+86>: add $0x2c,%esp
0x08048763 <+89>: ret
【问题讨论】:
-
cmp从%eax的值中减去0x2(十六进制 2 == 十进制 2),相应地设置标志,并保持%eax不变。 -
是的,
$2就是2。它在比较fscanf的返回值,这意味着它正在检查您是否输入了 2 个数字。不要误会我的意思,但是如果您甚至无法解决此问题,您以后会遇到更多麻烦,并且询问 SO 可能不是正确的方法。 -
谢谢大家。感谢您的关注,小丑。我也很确定我会遇到更多麻烦。我只是很难在互联网上找到像样的组装教程。我在一次重要的讲座中失去了注意力(诅咒你加),现在我有点迷失了。我刚刚和我的教授谈过了,但我忘了问那条线,不想再打扰他了。
-
我认为这是学习 ASM 的一个非常有效且很好的问题。不知道为什么投反对票。它涵盖了使用堆栈、调用 api 和操作码。