我必须阅读一些随机生成的程序集并输入一些正确的输入,以便在不调用explode_bomb函数的情况下到达目的地。问题是有两条线似乎直接相互矛盾,我担心由于随机生成,我的任务实际上可能是不可能的。
以下是完整代码:
08048d1b <phase_2>:
8048d1b: 55 push %ebp
8048d1c: 89 e5 mov %esp,%ebp
8048d1e: 56 push %esi
8048d1f: 53 push %ebx
8048d20: 83 ec 30 sub $0x30,%esp
8048d23: 8d 45 e0 lea 0xffffffe0(%ebp),%eax
8048d26: 89 44 24 04 mov %eax,0x4(%esp)
8048d2a: 8b 45 08 mov 0x8(%ebp),%eax
8048d2d: 89 04 24 mov %eax,(%esp)
8048d30: e8 42 04 00 00 call 8049177 <read_six_numbers>
8048d35: 83 7d e0 00 cmpl $0x0,0xffffffe0(%ebp)
8048d39: 79 05 jns 8048d40 <phase_2+0x25>
8048d3b: e8 f5 03 00 00 call 8049135 <explode_bomb>
8048d40: bb 01 00 00 00 mov $0x1,%ebx
8048d45: 8d 75 e0 lea 0xffffffe0(%ebp),%esi
8048d48: 89 d8 mov %ebx,%eax
8048d4a: 03 44 9e fc add 0xfffffffc(%esi,%ebx,4),%eax
8048d4e: 39 04 9e cmp %eax,(%esi,%ebx,4)
8048d51: 74 05 je 8048d58 <phase_2+0x3d>
8048d53: e8 dd 03 00 00 call 8049135 <explode_bomb>
8048d58: 83 c3 01 add $0x1,%ebx
8048d5b: 83 fb 06 cmp $0x6,%ebx
8048d5e: 75 e8 jne 8048d48 <phase_2+0x2d>
8048d60: 83 c4 30 add $0x30,%esp
8048d63: 5b pop %ebx
8048d64: 5e pop %esi
8048d65: 5d pop %ebp
8048d66: c3 ret
有问题的行是8048d4a和8048d4e。因为这是2的恭维,第一个数字是-4,第二个数字是我的第一个输入(这是否甚至改变到我的第二个和第三个?),第三个将是循环的任何迭代我们是和第四个一样。
现在直接顺序比较这些值基本上意味着我将数字与自身进行比较 - 4,对吗?我怎么能够通过那个测试呢?
感谢您的协助。
答案 0 :(得分:3)
我的AT&amp; T语法并不是最好的,但它似乎在做:
ADD EAX,[ESI + EBX * 4 - 4]
CMP EAX,[ESI + EBX * 4]
aka,它将前一个和一些计数器的总和与当前条目进行比较。请参阅this以供参考,具体为:
Example:
Intel Syntax
instr foo,segreg:[base+index*scale+disp]
mov eax,[ebx+20h]
add eax,[ebx+ecx*2h
lea eax,[ebx+ecx]
sub eax,[ebx+ecx*4h-20h]
AT&T Syntax
instr %segreg:disp(base,index,scale),foo
movl 0x20(%ebx),%eax
addl (%ebx,%ecx,0x2),%eax
leal (%ebx,%ecx),%eax
subl -0x20(%ebx,%ecx,0x4),%eax
至于为什么它这样做,好像它是一个优化,以避免寄存器溢出或减少数组索引然后递增它的替代。
答案 1 :(得分:0)
mov $0x1,%ebx ; i = 1
lea 0xffffffe0(%ebp),%esi ; ESI = address of array of 6 numbers
mov %ebx,%eax
add 0xfffffffc(%esi,%ebx,4),%eax ; add to element
cmp %eax,(%esi,%ebx,4)
add 0xfffffffc(%esi,%ebx,4),%eax
上述指令正在访问数组的元素。对于Scale,Index,Base,这在x86中称为 SIB 寻址。还有一个Offset组件。该阵列基于由基址寄存器(此处为EBX
)加上偏移量(此处为-4)确定的地址。元素编号位于索引寄存器(此处为ESI
)。每个元素的大小由比例(这里为4)确定。
lea 0xffffffe0(%ebp),%esi ; ESI = address of array of 6 numbers
如果你进一步了解,你会看到数组的地址如何移动到%ESI
。该数组是一个局部变量,位于帧指针下方32个字节处(当使用帧指针时,局部变量,包括数组,被视为与帧指针的偏移量)
add 0xfffffffc(%esi,%ebx,4),%eax
因此该指令访问在真实数组之前开始4个字节的“虚拟”数组。这是因为循环索引从1开始,但访问的元素是0,因此使用“虚拟阵列”一切都会到位。
mov $0x1,%ebx ; i = 1
lea 0xffffffe0(%ebp),%esi ; ESI = address of array of 6 numbers
mov %ebx,%eax
add 0xfffffffc(%esi,%ebx,4),%eax ; add to element i-1
cmp %eax,(%esi,%ebx,4) ; compare against element i