在x86中“test eax,eax”和“cmp eax,0”有什么区别

2024-02-20

Is test eax, eax比更有效率cmp eax, 0?是否存在以下情况:test eax, eax是必要的地方cmp eax, 0不满足要求?


正如臧明杰在评论中已经说过的,test eax, eax几乎与cmp eax, 0,除了它短于cmp,因为与cmp你必须提供0作为一个论点。请注意,节省的空间不是很大,因为第二个操作数经过符号扩展以匹配第一个操作数的大小,因此不一定需要整个 4 个字节来表示该零。

现在,您要问的是是否还有其他差异。这是一个合理的问题,因为cmp是算术运算(它执行减法并丢弃结果),而test是一个逻辑运算(它执行按位 AND 并丢弃结果),因此人们有理由怀疑他们可能会修改Flags注册方式不同。

事实证明,这两条指令都修改了Flags注册在almost相同的时尚。两条指令都会修改标志寄存器的 OF SF ZF AF PF 和 CF 位。这test指令总是清除 OF 和 CF,但这也是cmp反对零。唯一的其他区别是cmp指令将正确设置晦涩的AF flag https://en.wikipedia.org/wiki/Adjust_flag,而test指令使该标志的内容未定义。但在这种情况下cmp eax,0无论 AF 的值是多少,AF 总是会被清除eax,所以你无法从中学到任何东西cmp eax, 0你不会从test eax, eax.

因此,我的结论是,不存在以下情况:test eax, eax会给你一些东西cmp eax, 0不会,反之亦然。除了保存一两个字节的指令代码之外,这两条指令似乎可以完全互换用于任何实际甚至不那么实际的目的。

Using test eax, eax代替cmp eax, 0表明您了解您的装配。它还表明,与简单易懂的指令相比,您更喜欢稍微隐晦且性能稍微好一点的指令。这种东西往往会从其他极客那里获得奖励积分,但在过去几十年左右的时间里,它在现实世界中并没有任何实际用处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在x86中“test eax,eax”和“cmp eax,0”有什么区别 的相关文章

  • 有哪些 x86 指令会对 ESP 产生副作用?

    我知道call and ret将修改的值esp然后push and pop有很多变体 但是还有其他指令会影响堆栈指针吗 The following instructions modify the stack pointer as an im
  • LDR指令如何将常量加载到寄存器中?

    我刚刚读了一本ARM指令书 看到一条指令我无法解释 It says LDR将 32 位常量加载到r0登记 LDR r0 pc const number 8 pc const number DCD 0xff00ffff 我不明白什么 pc c
  • 如何找出英特尔处理器上的指令触及了哪条高速缓存线?

    我读了这篇文章关于 Meltdown Spectre 漏洞利用 http www theregister co uk 2018 01 04 intel amd arm cpu vulnerability 允许利用 CPU 中的硬件错误从内核
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 编译器在函数名称前添加下划线前缀的原因是什么?

    当我看到 C 应用程序的汇编代码时 如下所示 emacs hello c clang S O hello c o hello s cat hello s 函数名称以下划线作为前缀 例如callq printf 为什么这样做以及它有什么优点
  • 0 和双字 0 有什么区别?

    正如问题所述 有什么区别 例如 mov eax 0 and mov eax dword 0 我一直在使用 cmp 语句 但我无法理解其中的区别 一个是地址 另一个是数值 如前所述 MOV 指令没有区别 对于 CMP 您将有以下区别 qwor
  • 使用`esp*scale 时寻址内存时出错

    内存寻址一般形式 发现了here https stuff mit edu afs athena project rhel doc OldFiles 3 rhel as en 3 i386 memory html is base index
  • 本机代码、机器代码和汇编代码有什么区别?

    我对 NET 语言上下文中的机器代码和本机代码感到困惑 它们之间有什么区别 它们是一样的吗 这些术语确实有点令人困惑 因为它们有时使用不一致 机器代码 这是定义最明确的一种 它是使用字节码指令的代码 您的处理器 执行实际工作的物理金属部件
  • 使用 XCHG 解锁的自旋锁

    维基百科提供的使用 x86 XCHG 命令的自旋锁的示例实现是 Intel syntax locked The lock variable 1 locked 0 unlocked dd 0 spin lock mov eax 1 Set t
  • 如果我有一个 8 位值,那么使用 8 位寄存器而不是 16、32 或 64 位寄存器有什么优势吗?

    我读到的 x86 asm 介绍性文献似乎在所有实际场景中都坚持使用 32 位寄存器 eax ebx 等 除了证明 64 位寄存器也存在之外 如果确实提到 16 位寄存器 那也是作为历史注释来解释为什么 32 位寄存器的名称前面有一个 e 编
  • 用于计算三角函数、对数或类似函数的算法。仅限加减法

    我正在修复 Ascota 170 古董机械可编程计算机 它已经开始工作了 现在我正在寻找一种算法来展示其功能 例如计算三角或对数表 或类似的东西 不幸的是 从数学运算来看 计算机只能进行整数的加减法 从 1E12到1E12的55个寄存器 甚
  • 段错误...关于你好世界

    这段代码非常简单 但我在 x86 64 Linux 系统上遇到了段错误 这让我很烦恼 刚开始接触asm 请耐心等待 与 NASM 组装nasm f elf64 test asm 与连接ld o test test o SECTION tex
  • 在LPC2148 ARM处理器上创建中断向量的汇编代码

    我最近刚刚开始使用 LPC2148 ARM 处理器 我试图理解一些有关创建中断向量的汇编代码 这是代码 Runtime Interrupt Vectors Vectors b start reset start ldr pc undf un
  • 与 SSE 比较 16 字节字符串

    我有 16 字节的 字符串 它们可能更短 但您可能会假设它们在末尾用零填充 但您可能不会假设它们是 16 字节对齐的 至少不总是 如何编写一个例程将它们与 SSE 内在函数进行比较 是否相等 我发现这个代码片段可能会有帮助 但我不确定它是否
  • Mac OS X 上的 64 位程序集运行时错误:“dyld:无可写段”和“Trace/BPT trap”

    当尝试运行以下汇编程序时 globl start start pushq 0x0 movq 0x1 rax subq 0x8 rsp int 0x80 我收到以下错误 dyld no writable segment Trace BPT t
  • 简单内核无法在 GRUB 中启动

    我正在学习一些操作系统开发的知识OSDev org http osdev org 我有一个内核 我正在尝试使用 qemu 在 GRUB Legacy 0 97 中启动 但是 当我输入kernel 200 9 我收到消息 Multiboot
  • 段寄存器如何参与内存地址转换?

    到目前为止我所学到的有关细分的知识 虚拟地址包含段选择器和偏移量 段选择器与GDTR配合使用 查找段描述符的线性地址 段描述符保存有关所选段的信息 包括其线性地址 所以 我的问题是 根据我所读到的内容 虚拟地址被加载到段寄存器中 然后以某种
  • 如何在 MOS 6502 的 asm 中创建延迟

    我是 ASM 新手 我正在尝试研究如何为以下代码创建延迟 org 1000 loop inc d021 jmp loop 我想评论已经足够清楚了 每帧更改颜色的代码示例 1 50 秒 sei enable interrupts loop1
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • 该程序如何知道该字符串存储的确切位置?

    我用 Radare2 反汇编了一个 C 程序 在这个程序中有很多调用scanf像下面这样 0x000011fe 488d4594 lea rax var 6ch 0x00001202 4889c6 mov rsi rax 0x0000120

随机推荐