【问题标题】:imul using DWORD PTR [reg+reg*n-n]imul 使用 DWORD PTR [reg+reg*n-n]
【发布时间】:2013-07-25 18:39:39
【问题描述】:

我显然不明白这个 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>

【问题讨论】:

    标签: assembly x86 gdb


    【解决方案1】:

    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
    

    并且会产生真正的比较。

    【讨论】:

    • 感谢您分解它,我对 uint32_t/uint8_t 不熟悉,但我有一个想法,我现在会阅读它们。
    • 我可以使用更好的类型吗?在这种情况下,我只是试图指示 32 位和 8 位整数类型。
    • 我确定你用的是对的,我在这里还只是一个初学者,对 C 的了解还不够。
    • 建议您在深入研究汇编之前尝试学习 C。
    【解决方案2】:

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

    【讨论】:

    • 我的意思是esi指向的地址是0x1,这不是imul用来计算的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多