为什么不能执行 mov [eax], [ebx] [重复]

2024-05-05

我可以做这个:

mov eax, ebx

和这个:

mov [eax], ebx

甚至这个:

mov eax, [ebx]

但不是这个(错误C2415):

mov [eax], [ebx]

只是wtf...为什么? 它与 *ptr1 = *ptr2 相同,为什么我能够将一个寄存器复制到另一个寄存器,将寄存器中的地址复制值到另一个寄存器,或者将寄存器的值复制到存储在另一个寄存器中的地址...

但它不能将一个地址上的值复制到另一个地址。为什么?


您不能执行 mov [eax], [ebx],因为这意味着机器指令将允许您指定两个内存操作数。 x86 指令集主要是围绕机器指令设计的,这些指令允许您指定一个寄存器和一个内存操作数,因为这非常有用,并且它不会影响提取寄存器然后分步放入内存的操作的性能。

与所有复杂的指令集架构一样,有一些原则(例如上述),并且也有一些用于其他目的的规则例外。

您可能对 MOVB/MOVW/MOVD 指令感兴趣,它们分别有效:

 MOV byte[edi], byte[esi]; add edi,1; add esi,1
 MOV word[edi], word[esi]; add edi,2; add esi,2
 MOV dword[edi], dword[esi]; add edi,4, add esi,4

(不,您无法选择寄存器;这些寄存器已硬连线以使用 ESI 和 EDI)。就其本身而言,这并不是很有趣(除了完全按照您想要的方式做之外:),但可以使用 REP 前缀重复它来构建块移动。而且芯片设计者非常努力地让这种块移动运行得极快。

[对于 64 位 x86,有一个在 qword 上运行的 MOVQ]。

如果您要编写汇编代码,那么在编写大量代码之前仔细阅读指令集描述是非常值得的。

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

为什么不能执行 mov [eax], [ebx] [重复] 的相关文章

  • 为什么 Linux perf 使用事件 l1d.replacement 来处理 x86 上的“L1 dcache misses”?

    在英特尔 x86 上 Linux用途 https stackoverflow com a 52172985 149138事件l1d replacements来实施其L1 dcache load misses event 该事件定义如下 计数
  • 从类模板参数为 asm 生成唯一的字符串文字

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

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 避免 gcc 函数序言开销?

    我最近遇到了很多 gcc 在 x86 上生成非常糟糕的代码的函数 它们都符合以下模式 if some condition do something really simple and return else something comple
  • 何时可以重用avx指令中的源寄存器

    在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用 例如 我想使用vgatherdps该指令消耗两个 ymm 寄存器 其中之一是位移索引 我意识到vgatherdps由于数据的局部性较差 因此需要花费大量时间来收集 位移索引寄存器
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw
  • 将字段中的位扩展到掩码中所有(重叠+相邻)集位的最快方法?

    假设我有 2 个名为 IN 和 MASK 的二进制输入 实际字段大小可能是 32 到 256 位 具体取决于用于完成任务的指令集 每次调用时两个输入都会改变 Inputs IN 1100010010010100 MASK 000111101
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • Intel:序列化指令和分支预测

    英特尔架构开发人员手册 http www intel com content www us en architecture and technology 64 ia 32 architectures software developer v
  • 使用 Gas 生成与位置无关的代码 (-fPIC)

    我尝试在 x86 64 上创建共享库但失败 问题归结为以下代码 请不要介意 它没有多大意义 section data newline ascii n section text globl write newline type write n
  • _mm_max_ss 在 clang 和 gcc 之间有不同的行为

    我正在尝试使用 clang 和 gcc 交叉编译一个项目 但在使用时发现一些奇怪的差异 mm max ss e g m128 a mm set ss std numeric limits
  • 各种中断的区别:SCI、SMI、NMI、普通中断

    我正在学习英特尔架构 到目前为止我遇到过几种类型的中断 SCI 系统控制中断 硬件使用的系统中断 用于向操作系统通知 ACPI 事件 SCI 是一个有效 低电平 可共享的电平中断 SMI 系统管理中断 由遗留系统上的中断事件生成的操作系统透
  • 在 Intel x86 架构上使用非 AVX 指令移动 xmm 整数寄存器值

    我有以下问题 需要使用 AVX2 以外的任何工具来解决 我有 3 个值存储在 m128i 变量中 不需要第四个值 需要将这些值移动 4 3 5 我需要两个功能 一个用于按这些值进行右逻辑移位 另一个用于左逻辑移位 有谁知道使用 SSE AV
  • long double(GCC 特定)和 __float128

    我正在寻找有关的详细信息long double and float128在 GCC x86 中 更多是出于好奇而不是因为实际问题 可能很少有人需要这些 我只是有史以来第一次 truly需要一个double 但我想知道你的工具箱里有什么以及它
  • 从c调用汇编函数

    我试图从 c 调用汇编函数 但我不断收到错误 text globl integrate type integrate function integrate push ebp mov esp ebp mov 0 edi start loop
  • 64 位 Windows 汇编器

    我想对 64 位 Windows 程序集进行编程 最好使用 NASM 我在 google 上查了一下 但似乎找不到 64 位 Windows 编译器 有些网站提到了ml64 但它似乎不再包含在VC 中 我尝试过 32 位程序集 但显然它在我
  • 比“add esp, 4”更小的指令

    又是我 我的程序中有很多 add esp 4 我正在尝试减小它的大小 是否有任何更小的指令可以替代 add esp 4 pop edx 或者您不介意破坏的任何其他整数寄存器 这就是现代编译器实际上所做的 https stackoverflo
  • x86 asm 图形设置的分辨率高于 640x480?

    我刚刚开始使用汇编语言 感觉像学习新东西 并且遇到了一些问题 到目前为止 我一直在浏览的所有教程都没有回答 或者太旧而无法知道 1 我尝试了一些搜索 也许我只是不知道正确的关键字 但我找不到用于更改屏幕分辨率等的图形模式的更新列表 我发现的
  • 汇编语言程序中连续两次相乘

    我正在使用 8086 模拟器以及 DOSBOX 和 MASM 我知道当我们将 8 位与 8 位相乘时 答案将是 16 位 al 8 bit ax 当我们将 16 位与 16 位相乘时 答案将是 32 位 ax 16 bit dx ax 但如
  • 将十进制转换为十六进制

    首先 这是家庭作业 我正在尝试将 5 位数字读入寄存器 bx 假定该数字不大于 65535 16 位 以下是我尝试这样做的方法 但是 当我尝试打印该号码时 我仅打印输入的最后一位数字 这让我猜测 当我向 bx 添加另一个数字时 它会覆盖以前

随机推荐