gpt4 book ai didi

assembly - 在 x64 中,使用 "pop [RAX]",值临时存储在哪里?

转载 作者:行者123 更新时间:2023-12-01 22:50:47 24 4
gpt4 key购买 nike

我找到了解释直接内存到内存复制在 x86 平台上是不可能的,除非值存储在两者之间的某个地方。

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

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

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

最佳答案

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

在像 Skylake 这样的现代 x86 上,pop [mem] 解码为 2 微指令,所以大概第一个微指令是 pop 进入内部寄存器,第二个是一家商店。

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

原始 8086 是非流水线的(指令预取除外),因此实现 pop [mem] 的内部微代码或逻辑大概只是从某个特殊用途的缓冲区加载然后存储。与 add [mem], reg 相似,但加载地址与存储地址不同,并且不通过 ALU 馈送。

direct memory-to-memory copy is not possible on x86.

您可能指的是关于 Why IA32 does not allow memory to memory mov? 的公认答案之类的事情不幸的是,这种对原因的解释是完全错误的,而且极具误导性。

这是一个指令编码的限制使得mov [mem], [mem]不可能,而不是CPU内部的限制。参见 What x86 instructions take two (or more) memory operands?
pop [mem] 就是其中之一,因为内存操作数之一是隐式。即使是原始的 8086 也可以做到这一点。


I make heavy use of 64bit writes to memory using pop

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

或者,如果您的目的地是连续的,则执行 128 位或 256 位副本。

pop [mem] 有一些用例,但它并不好,而且在主流 Intel 上通常不会比 pop reg/mov [mem] 快, reg 因为它仍然是 2 微指令。它的代码大小安全,但不需要 tmp reg。

参见 https://agner.org/optimize/

关于assembly - 在 x64 中,使用 "pop [RAX]",值临时存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58001187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com