1

我显然不明白这个 imul 到底发生了什么,因为当我自己进行计算时,它不会出现 2。如果有人能解释 r/m 形式以及为什么 imul 得到 2,我将不胜感激。

esi 和 ebx = 0x1。*4 是指字长,对吗?(我认为 4 是 DWORD)?最后一部分,-0x4,是位移吗?只是为了增加或减少价值?

顺便说一句,当我自己进行计算时,如果你还没有猜到,我会得到 -2。

9: x/32xw $esp
0xffffd300: 0xffffd3f4  0x00000000  0xffffd338  0x08049226
0xffffd310: 0x00000001  0x00000002  0x00000006  0x00000001
0xffffd320: 0x00000002  0x00000006  0xffffd358  0x08048a83
0xffffd330: 0x0804b6d0  0x08049620  0xffffd358  0x08048a7a
8: /x $ebp = 0xffffd328
7: /x $ebx = 0x1
6: /x $ecx = 0x0
5: /x $edx = 0x0
4: /x $edi = 0x0
3: /x $esi = 0xffffd310
2: /x $eax = 0x2
1: x/10i $eip
=> 0x8048b79 <phase_2+49>:  imul   eax,DWORD PTR [esi+ebx*4-0x4]
   0x8048b7e <phase_2+54>:  cmp    DWORD PTR [esi+ebx*4],eax

(gdb) 
0x08048b7e in phase_2 ()
9: x/32xw $esp
0xffffd300: 0xffffd3f4  0x00000000  0xffffd338  0x08049226
0xffffd310: 0x00000001  0x00000002  0x00000006  0x00000001
0xffffd320: 0x00000002  0x00000006  0xffffd358  0x08048a83
0xffffd330: 0x0804b6d0  0x08049620  0xffffd358  0x08048a7a
8: /x $ebp = 0xffffd328
7: /x $ebx = 0x1
6: /x $ecx = 0x0
5: /x $edx = 0x0
4: /x $edi = 0x0
3: /x $esi = 0xffffd310
2: /x $eax = 0x2
1: x/10i $eip
=> 0x8048b7e <phase_2+54>:  cmp    DWORD PTR [esi+ebx*4],eax
   0x8048b81 <phase_2+57>:  je     0x8048b88 <phase_2+64>
4

2 回答 2

2

imul eax,DWORD PTR [esi+ebx*4-0x4]相当于 C 类伪代码中的这个表达式:

eax = eax * *(uint32_t *)((uint8_t *)esi + ebx*4 - 4)

替换您的值:

eax = 2 * *(uint32_t *)((uint8_t *)0xffffd310 + 1*4 - 4)
eax = 2 * *(uint32_t *)0xffffd310
eax = 2 * 1
eax = 2

同样,该cmp指令正在与 进行比较eaxDWORD PTR [esi+ebx*4]例如:

eax == *(uint32_t *)((uint8_t *)esi + ebx * 4)
2 == *(uint32_t *)((uint8_t *)0xffffd310 + 1*4)
2 == *(uint32_t *)0xffffd314
2 == 2

并且会产生真实的比较。

于 2013-07-25T18:44:39.007 回答
0

$esi 不是 0x1——它是 0xffffd310,它是堆栈上的一个地址。DWORD PTR 正在读取堆栈内存位置的内容,[] 中的表达式是地址计算。

于 2013-07-25T18:44:58.233 回答