【问题标题】:Side-effects of x86 assembly right-shift operator SHR?x86汇编右移运算符SHR的副作用?
【发布时间】:2025-12-31 12:05:12
【问题描述】:

我正在使用 ASM 调试器 ollydbg 跟踪一个程序,我遇到了这段代码 sn-p,它是一个循环段:

CPU Disasm
Address   Hex dump          Command                                  Comments
007D05EC  |.  33C9          XOR ECX,ECX
007D05EE  |.  8BFF          MOV EDI,EDI
007D05F0  |>  8B54B4 10     /MOV EDX,DWORD PTR SS:[ESI*4+ESP+10]
007D05F4  |.  8BFA          |MOV EDI,EDX
007D05F6  |.  0FAFFE        |IMUL EDI,ESI
007D05F9  |.  8BDA          |MOV EBX,EDX
007D05FB  |.  D3EB          |SHR EBX,CL
007D05FD  |.  03F8          |ADD EDI,EAX
007D05FF  |.  83C1 10       |ADD ECX,10
007D0602  |.  83C6 01       |ADD ESI,1
007D0605  |.  03DF          |ADD EBX,EDI
007D0607  |.  33DA          |XOR EBX,EDX
007D0609  |.  81F9 B0000000 |CMP ECX,0B0
007D060F  |.  8BC3          |MOV EAX,EBX
007D0611  |.^ 7C DD         \JL SHORT 007D05F0

我可以跟踪并了解其他操作员所做的事情,当我跟踪它时,这很有意义。但是 SHR EBX, CL 对我来说没有意义。

//Shouldn't in asm
SHR EBX, CL
//be the same as doing this in c/c++?
//that's how it read when I checked the asm reference anyway
ebx >>= CL;

但是我在跟踪时看到的是,如果循环迭代是奇数,则丢弃 LSB 并将 MSB 移动到它的位置。如果是偶数,则 ebx 不变。每次循环迭代,ecx寄存器变化如下:

**ecx**
0x0000  -- loop 0
0x0010  -- loop 1
0x0020  -- loop 2
..
0x00A0  -- loop 10

我期望看到的是在第二个或第三个循环之后,ebx 总是会被清零,因为 0x20 你已经移动了 32 位。

我有点困惑,有人能解释一下吗?

谢谢

【问题讨论】:

    标签: assembly x86 bit-shift


    【解决方案1】:

    这是我从指令描述中读到的内容:

    在任何一种情况下,大于 31 的移位计数都以 32 为模执行。

    回答你的问题?

    【讨论】:

    • 谢谢,我认为这解释了我所看到的行为差异。 Mod 32 将导致 SHR 指令在 0x00 和 0x10 的移位之间振荡。