我找到了答案,解释说在x86平台上无法直接进行内存到内存复制,而不会将值存储在介于两者之间。

mov rax,[RSI]
mov [RDI],rax

我使用pop大量使用64位写入内存,它似乎直接从内存复制值到内存,没有任何明显的“中间人”。

写入之前的值在哪里,但在读完之后?

#1楼 票数:4

临时位置是CPU内部的缓冲区,不属于架构状态。

在像Skylake这样的现代x86上, pop [mem]解码为2 uop,所以推测第一个uop是内部寄存器的pop ,第二个是商店。

我们知道现代的x86 CPU确实有一些额外的逻辑寄存器可供微码和像这样的多uop指令使用。 它们以与架构寄存器相同的方式重命名为物理寄存器文件。 例如http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/提到“一些额外的架构寄存器供内部使用”。 亨利称他们为“建筑”寄存器,但这可能令人困惑的术语。 他只是意味着逻辑而不是物理, 就像建筑寄存器一样。 这些临时寄存器不是(AFAIK)跨指令边界使用,仅在一条x86指令中使用。

原始8086是非流水线的(除了指令预取),因此实现pop [mem]的内部微码或逻辑可能只是加载然后从某个专用缓冲区存储。 就像add [mem], reg但是负载与存储的地址不同而没有通过ALU提供它。

在x86上无法直接进行内存到内存复制。

你可能指的是为什么IA32不允许内存到内存mov的接受答案 不幸的是,对原因的解释是完全错误的,而且非常误导。

这是一个指令编码限制,使mov [mem], [mem]不可能,而不是CPU内部的限制。 请参阅哪些x86指令需要两个(或更多)内存操作数?
pop [mem]是其中之一,因为其中一个内存操作数是隐式的 即使是原版8086也可以做到这一点。


我使用pop大量使用64位写入内存

如果前端uop吞吐量或端口2/3压力是瓶颈,请考虑使用堆栈中的128位SSE负载,然后使用movlpsmovhps存储64位半部分。 在当前的Intel CPU(如Skylake)上, movhps [mem], xmm0是单指令。 (实际上是微融合的;所有商店都是商店地址+商店数据。但无论如何,没有端口5改变需要像无用的内存目的地形式的pextrq )。

或者,如果目标是连续的,请执行128位或256位副本。

pop [mem]有一些用例,但它并不精彩,主流英特尔通常不会比pop reg / mov [mem], reg更快mov [mem], reg因为它仍然是2 uops。 它确实安全的代码大小,并且不需要tmp reg。

请参阅https://agner.org/optimize/

#2楼 票数:3 已采纳

pop [rax]是执行内存到内存操作的方法之一。 弹出的值可能存储在介于两者之间的某个位置,但这是一个实现细节。 这些答案的含义是,对其操作数使用modr / m字节的指令最多只能有一个内存操作数。 这些是大多数指令,但不是像movsb [rdi], [rsi]这样的指令,它们的操作数内置在指令中。

  ask by z0rberg's translate from so

未解决问题?本站智能推荐:

2回复

汇编:为什么某些 x86 操作码在 x64 中无效?

为什么在 x64 中一些操作码无效(例如06 、 07 ),而在 x86 中用于相当基本的指令( 06和07是push和pop )? 我认为那些最简单的指令在两种架构中都能很好地运行。 为什么他们在 x64 中禁用了一些简单的指令? 他们为什么不工作? 为什么他们禁用了一些操作码,在操作码列表中创
1回复

为什么使用 push/pop 而不是 sub 和 mov?

当我在https://godbolt.org上使用不同的编译器时,我注意到编译器生成这样的代码是很常见的: 我知道每次push或pop做两件事: 将操作数移入/移出堆栈空间 递增/递减堆栈指针 (rsp) 所以在我们上面的例子中,我假设 CPU 实际上在做 12 次操作(6 次移动,
1回复

在x86-64 Assembly中,“。align”指令是什么意思?

我注意到有一些指令与.align前缀一起使用,后跟数值。 我不确定这是什么,也不确定是否需要使用,但是我已经编写了x86 Assembly,并且之前从未使用过“ .align”。 它的基本目的是什么,为什么或为什么不是强制性的?
2回复

x86 32位操作码,x86-x64不同或完全删除

我在x86-x64中查找了维基百科的x86向后兼容性,它说: x86-64完全向后兼容16位和32位x86代码。因为完整的x86 16位和32位指令集仍然在硬件中实现而没有任何干预仿真,现有的x86可执行文件运行时没有兼容性或性能损失而重新编码以利用处理器设计的新功能的现有应用程序可以
2回复

R代表RAX,RBX,RCX,RDX,RSI,RDI,RBP,RSP? [重复]

这个问题在这里已有答案: 英特尔32位和64位寄存器的名称中E和R前缀代表什么? 1个答案 x86汇编语言不得不改变,因为x86处理器架构已经从8位变为16位变为32位,现在变为64位。 我知道在32位汇编程序寄存器名称(EAX,EBX等)中,每个名称的E前
1回复

clwb 是否负责存储缓冲区中的写入?

英特尔软件手册说clwb “将包含用内存操作数指定的线性地址的缓存行(如果修改)写回内存,该线性地址来自缓存一致性域中缓存层次结构的任何级别。该行可以保留在缓存层次结构中未修改的状态。 clwb 是根据较旧的写入缓存线被回写的顺序排序的“ 我的问题是,在下面的伪代码中 clwb 是否负责存储
1回复

RSP中的R代表什么?

根据其位架构相应地调用寄存器:16位:SP =堆栈指针32位:ESP =扩展堆栈指针64位:RSP = R? 堆栈指针 有人知道R代表什么吗? 我在stackoverflow上找到了一个答案,暗示R代表寄存器,但是没有任何证据,这只是用户的猜测。
3回复

为什么 GCC 不使用部分寄存器?

在 linux 上反汇编write(1,"hi",3) ,使用gcc -s -nostdlib -nostartfiles -O3 : 我不参与编译器开发,但由于移动到这些寄存器中的每个值都是常量并且在编译时已知,我很好奇为什么 gcc 不使用dl 、 dil和al来代替。 也许有人会说,此功能