x86 asm 中 NOT 指令的简单示例

2024-02-28

有人能解释一下 x86 汇编器中 NOT 指令的具体作用吗?

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

但在汇编器中,运算符似乎做了其他事情,我不明白操作数到底是做什么用的。

有人可以用一个简单的例子解释一下操作吗?


x86 NOT http://felixcloutier.com/x86/NOT.html是按位运算;它只是分别反转每个位,就像xor reg, -1但不影响标志。

NOT实施C's ~操作员 http://en.cppreference.com/w/c/language/operator_arithmetic,并且完全不同于! (逻辑非 http://en.cppreference.com/w/c/language/operator_logical).

以下是 C 编译器如何实现这些运算符(用于 x86-64 System V 调用约定的 gcc8.1 和 clang6.0,在 Godbolt 编译器资源管理器上 https://gcc.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:'int+bitnot(int+a)+%7B+return+~a%3B+%7D%0D%0Aint+logical_not(int+a)+%7B+return+!!a%3B+%7D%0D%0Aint+booleanize(int+a)+%7B+return+!!!!a%3B+%7D%0D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:37.18061674008811,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:g81,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'1'),lang:c%2B%2B,libs:!(),options:'-xc+-O3+-std%3Dgnu11+-Wall+-march%3Dskylake',source:1),l:'5',n:'0',o:'x86-64+gcc+8.1+(Editor+%231,+Compiler+%231)+C%2B%2B',t:'0')),k:32.64490422214522,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang600,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'1'),lang:c%2B%2B,libs:!(),options:'-xc+-O2+-std%3Dgnu11+-Wall+-march%3Dhaswell+-mno-avx512f+-mno-avx',source:1),l:'5',n:'0',o:'x86-64+clang+6.0.0+(Editor+%231,+Compiler+%232)+C%2B%2B',t:'0')),k:30.174479037766666,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)。两个编译器生成相同的代码,正确地选择现代 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

x86 asm 中 NOT 指令的简单示例 的相关文章

  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 为什么 GCC 不将 a*a*a*a*a*a 优化为 (a*a*a)*(a*a*a)?

    我正在对科学应用程序进行一些数值优化 我注意到的一件事是 GCC 会优化调用pow a 2 通过将其编译成a a 但是调用pow a 6 没有优化 实际会调用库函数pow 这大大降低了性能 相比之下 英特尔 C 编译器 http en wi
  • 在 x86 ASM 中测试零通常哪个更快:“TEST EAX, EAX”与“TEST AL, AL”?

    测试 AL 中的字节是否为零 非零通常哪个更快 TEST EAX EAX TEST AL AL 假设之前有一个 MOVZX EAX BYTE PTR ESP 4 指令加载了一个带有零扩展的字节参数到 EAX 的其余部分 防止了我已经知道的组
  • 用于预乘 ARGB 的 SSE alpha 混合

    我正在尝试编写一个支持 SSE 的 alpha 合成器 这就是我想出的 首先 混合两个 4 像素向量的代码 alpha blend two 128 bit 16 byte SSE vectors containing 4 pre multi
  • 从 NASM 调用 C 函数 _printf 会导致分段错误

    我一直在尝试使用 NASM 在 Mac OS 和 Windows 上学习 64 位汇编 我的代码是 extern printf section data msg db Hello World 10 0 section text global
  • AVX-512CD(冲突检测)与原子变量访问有何不同?

    所以我在看他们展示了如何 void Histogram const float age int const hist const int n const float group width const int m const float o
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • 从 exe 文件中获取汇编级代码?

    我当时正在做linux汇编编程 在过去的几天里我已经转而学习windows汇编编程 我在用ml作为我的汇编器和golink作为我的链接器 我有我的汇编代码并已获得我的exe从中 现在我需要取回它的十六进制 xff xab x55等等 在li
  • CPU寄存器和多任务处理

    我目前正在学习汇编 我很困惑 CPU 寄存器如何与多任务一起工作 所以在多任务系统中 CPU可以随时暂停某个程序的执行并运行另一个程序 那么在这一步中寄存器值是如何保存的呢 寄存器是压入堆栈还是以其他方式 CPU 寄存器如何与多任务一起工作
  • 如何使用movntdqa避免缓存污染?

    我正在尝试编写一个 memcpy 函数 该函数不会将源内存加载到 CPU 缓存中 目的是避免缓存污染 下面的 memcpy 函数可以工作 但会像标准 memcpy 一样污染缓存 我正在使用带有 Visual C 2008 Express 的
  • MikeOS 引导加载程序中的堆栈段

    我不明白这段代码 mov ax 07C0h Set up 4K of stack space above buffer add ax 544 8k buffer 512 paragraphs 32 paragraphs loader cli
  • 设置 IRQ 映射

    我正在遵循一些教程和参考文献来尝试设置我的内核 我在教程中遇到了一些不熟悉的代码 但根本没有解释它 这是我被告知映射的代码16 IRQs 0 15 到 ISR 地点32 47 void irq remap void outportb 0x2
  • Visual Studio 2012 本机 C++ DLL x86 编译

    我最近将我的工具集从 Win 7 x86 Visual Studio 2010 升级到 Win 8 x64 Visual Studio 2012 但是 现在我的本机 C dll 编译为 x64 而不是 x86 除了将代码移至新操作系统并将其
  • GCC的sqrt()编译后如何工作?使用哪种root方法?牛顿-拉夫森?

    只是对标准感到好奇sqrt 来自 GCC 上的 math h 我自己编码的sqrt 使用牛顿拉夫森来做到这一点 是的 我知道 fsqrt 但CPU是如何做到这一点的呢 我无法调试硬件 现代 CPU 中的典型 div sqrt 硬件使用 2
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 为什么我的代码显示垃圾?

    当我也想打印列表中的每个数字时 我的代码显示垃圾 有什么问题吗 输出应如下所示 给定的数组是 2G 4 PT为什么这是垃圾总数是 7 Code ASSUME CS CODE DS DATA SS STK ORG 0000H DATA SEG
  • LC3 LEA指令和存储的值

    我对这个问题感到困惑 指令后寄存器0中存储的值是多少 LEA R0 A 被处决了吗 为什么答案是x370C 我认为应该将A的地址加载到R0中 如果是这样我们怎么知道地址 有人可以帮忙吗 非常感谢 ORIG X3700 LEA R0 A LD
  • 两个布尔列表之间的逻辑运算

    我得到了一个奇怪的结果 我尝试应用and or the orpython 中 2 个布尔列表的运算符 事实上 我得到的结果与我的预期完全相反 True False False and True True False gt True True
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12

随机推荐