【问题标题】:In x86 assembly how can you set the zero flag (ZF) without doing a compare operation?在 x86 汇编中,如何在不进行比较操作的情况下设置零标志 (ZF)?
【发布时间】:2011-12-06 16:48:06
【问题描述】:

我有一小段 (x86) 程序集,我正试图弄清楚它的作用。

...
 6:     81 ec 00 01 00 00       sub    $0x100, %esp
 c:     31 c9                   xor    %ecx  , %ecx
 e:     88 0c 0c                mov    %cl   , (%esp, %ecx, 1)
11:     fe c1                   inc    %cl
13:     75 f9                   jne    0xe
....

它看起来像是在循环,直到“JNE”评估为假,即零标志 = 0。(可能将数字 1、2、3 ...放入堆栈??)

根据我对装配的简短调查(我是新人),您可以通过执行比较操作 (CMP) 来设置零标志,但我没有看到比较操作。

那么,在什么情况下它会跳出这个循环呢?

【问题讨论】:

    标签: x86 assembly machine-code


    【解决方案1】:

    inc 如果cl 在增量后的值为零,则设置 ZF。您的循环正在这样做:

    sub    $0x100, %esp            // unsigned char array[256];
    xor    %ecx  , %ecx            // unsigned char cl = 0;
    mov    %cl   , (%esp, %ecx, 1) // e: array[cl] = cl;
    inc    %cl                     //    cl += 1;
    jne    0xe                     //    if (cl != 0) goto e;
    

    cl 从 255 递增并回绕到 0 时,循环终止,设置 ZF。

    【讨论】:

    • 好的,这是有道理的。谢谢!
    • 除了mov %cl, (%esp, %ecx, 1),我想我都遵循了。在英语中,我会说“将 CX (CL) 的低 8 位移动到位于 ESP+ECX 的地址的 RAM 中”,这是有道理的,但 1 操作数是什么?这真的是array[cl + 1] = cl(堆栈溢出?)还是array[cl] = cl + 1?可能我错过了 x86 程序集的一些细微差别,但我很好奇。
    • 1 实际上是缩放偏移量的大小。所以它真的是 array[cl * 1] = cl.
    • @Mike:请注意,在 Intel 语法中它只是 mov [esp+ecx], cl
    • @GreyCat,学究式的[esp+1*ecx](特别是没有位移,而不是 disp8=0 或 disp32=0),尽管在这种情况下它并不是真正模棱两可,因为 esp 不能用作索引寄存器。
    【解决方案2】:

    算术指令如add, sub, inc, dec, sar, sal,也可按位运算如test, shl, shr, or, and, xor, neg等,修改ZF。

    【讨论】:

    • 感谢您的完整列表,它将很有用。你是从某个特定的参考资料中得到的,还是你马上就知道的?
    • 这些说明我都知道,但是具体效果还是得在intel manuals/google上查。我不知道影响 ZF 的指令列表。
    【解决方案3】:

    inc、dec等数学运算也可以设置零标志。

    【讨论】:

      【解决方案4】:

      或者,对于初学者,保存 [push] 堆栈上的标志,[pop] 获取寄存器中的堆栈,使用算术或运算符在寄存器上具有所需位,压入寄存器并弹出标志。

      类似的东西。

      pushf
      pop ax
      or ax, 0x100 [this will set trap flag, you can get the value for any flag or flags you want]
      push ax
      popf
      

      【讨论】:

        猜你喜欢
        • 2015-04-18
        • 1970-01-01
        • 2011-12-07
        • 1970-01-01
        • 2011-12-23
        • 2019-06-27
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多