【问题标题】:simple example of NOT instruction in x86 asmx86 asm 中 NOT 指令的简单示例
【发布时间】:2018-06-06 17:32:14
【问题描述】:

有人能解释一下 x86 汇编器中的 NOT 指令究竟是做什么的吗?

在我所知道的编程语言中,NOT 用于检查特定状态是否不正确(例如:if (!Isset($var)))

但是在Assembler中,操作符似乎做了别的事情,我不明白操作数到底是干什么用的。

谁能用一个简单的例子解释一下这个操作?

【问题讨论】:

  • 说明书的哪一部分你不明白?
  • 我对这个指令一无所知。我使用谷歌,但我不明白这个指令是做什么的。它是否简单地将每 0 更改为 1? 0xffff 怎么样? not 指令是否将 0xffff 更改为 0x0000?
  • 是的,它确实每隔 0 到 1 和 1 到 0 变化一次。如果 0xFFFF 在 16 位寄存器或 16 位内存操作数中,则结果为零。 (not eaxeax = FFFF 将产生eax = FFFF0000 时,操作数大小很重要,一如既往)。 felixcloutier.com/x86/NOT.html ... 不确定时,请使用调试器尝试一下,这是一种快速的方法,而且您可以练习调试。
  • 感谢您的回答。我有最后一个问题,是否可以将 not 指令与字符串一起使用?
  • @DR.Jones 没有。汇编中没有字符串。只有位,按字节、字、双字等分组......所以我不知道你在问什么。什么是高级语言中的“字符串”总是只是以位编码的值,所以是的,你当然可以not 这样的值,虽然我不确定你期望什么(在我看来,这种操作的使用主要是“不是有意义的”,除非它是某种琐碎的混淆方案)。

标签: assembly x86 nasm bitwise-operators logical-operators


【解决方案1】:

x86 NOT 是按位运算;它只是分别反转每个位,例如xor reg, -1,但不会影响 FLAGS。

NOT 实现了C's ~ operator,与! (logical not) 完全不同。

以下是 C 编译器如何实现这些运算符(x86-64 System V 调用约定的 gcc8.1 和 clang6.0,on the Godbolt compiler explorer)。两种编译器都生成相同的代码,正确地为现代 Intel/AMD CPU 选择最有效的实现。

int bitnot(int a) { return ~a; }

    mov     eax, edi
    not     eax
    ret

int logical_not(int a) { return !a; }

    xor     eax, eax
    test    edi, edi
    sete    al
    ret

int booleanize(int a) { return !!a; }

    xor     eax, eax
    test    edi, edi
    setne   al
    ret

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 2019-04-20
    • 2014-08-16
    • 1970-01-01
    • 2016-12-13
    • 2012-05-09
    • 1970-01-01
    • 2017-11-16
    相关资源
    最近更新 更多