Assembly 在x64中,使用;pop[RAX]“是的;,值临时存储在哪里?

Assembly 在x64中,使用;pop[RAX]“是的;,值临时存储在哪里?,assembly,x86,x86-64,cpu-architecture,Assembly,X86,X86 64,Cpu Architecture,我找到了一些答案,解释了在x86平台上,如果不将值存储在两者之间,直接内存到内存的复制是不可能的 mov rax,[RSI] mov [RDI],rax 我使用pop大量使用64位写入内存,它似乎直接将值从内存复制到内存,而没有任何明显的“中间人” 其中是写入前的值,但读取后的值?pop[rax]是执行内存对内存操作的方法之一。弹出的值可能存储在两者之间的某个位置,但这是一个实现细节。这些答案的意思是,使用modr/m字节作为操作数的指令最多只能有一个内存操作数。这些是大多数指令,但不是像mo

我找到了一些答案,解释了在x86平台上,如果不将值存储在两者之间,直接内存到内存的复制是不可能的

mov rax,[RSI]
mov [RDI],rax
我使用pop大量使用64位写入内存,它似乎直接将值从内存复制到内存,而没有任何明显的“中间人”


其中是写入前的值,但读取后的值?

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

临时位置是CPU内部某个不属于体系结构状态的缓冲区

在像Skylake这样的现代x86上,
pop[mem]
解码为2个uop,因此第一个uop可能是一个
pop
,进入内部寄存器,第二个uop是一个存储

我们知道,现代x86 CPU确实保留了一些额外的逻辑寄存器,供微码和多uop指令使用。它们以与体系结构寄存器相同的方式重命名到物理寄存器文件中。e、 g.提到“一些内部使用的额外架构寄存器”。Henry称之为“架构”寄存器,但这可能会混淆术语。他只是指逻辑,而不是物理,就像架构寄存器一样。这些临时寄存器(AFAIK)不会跨指令边界使用,只能在一条x86指令中使用

最初的8086是非流水线的(除了指令预取),因此实现
pop[mem]
的内部微码或逻辑可能只是从某个专用缓冲区加载然后存储。与添加[mem]类似,reg但是加载和存储的地址不同,并且没有通过ALU提供

x86上不可能进行直接内存到内存的复制

你可能指的是关于原因解释的公认答案,不幸的是,这完全是错误的,而且非常误导

这是一种指令编码限制,使得
mov[mem],[mem]
不可能,而不是CPU内部的限制。见
pop[mem]
是其中之一,因为其中一个内存操作数是隐式的。即使是最初的8086也能做到这一点


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

如果前端UOP吞吐量或端口2/3压力是瓶颈,考虑从堆栈中使用128位SSE负载,然后用“代码> MOVLPS 和<代码> MOVHPS存储64位半部。在当前的英特尔CPU(如Skylake)上,

movhps[mem],xmm0
是一条uop指令。(实际上是微融合的;所有存储都是存储地址+存储数据。但无论如何,对于无用的内存目标形式
pextrq
,不需要端口5洗牌uop)

或者,如果目标是连续的,则执行128位或256位复制

pop[mem]
有一些使用案例,但这并不美妙,而且在主流英特尔上通常不会比
pop-reg
/
mov[mem],reg
更快,因为它仍然是2个UOP。它的代码大小是安全的,并且不需要tmp注册表


哇,我忘了movsb/等等。我想说,如果你删除“可能”,那么我可以接受它作为一个答案。这个“可能”让我很困扰,因为它必须存储在一些公众一无所知的实现细节后面,对吗?对于可能出现的吹毛求疵或“语义”,我深表歉意。@z0rberg的观点是,可能有人以这样的方式实现了x86,即数据从一个内存位置直接传输到另一个内存位置(例如,通过连接两个内存的数据总线),但这不太可能。由于没有规范要求中间寄存器,我只能说“可能”。我也可以说“一般”;这能让你满意吗?你的回答让我笑了。“连接两个存储器的数据总线。”很好。感谢您抽出时间撰写回复。我会接受这个答案。遗憾的是,显然没有更多的东西需要了解。@zorberg恰恰相反,有!让我看看是否能找到一些更深入的阅读资料来帮助您深入了解这一点。@zorberg很抱歉,我没有找到真正的x86处理器中到底发生了什么。如果我有什么特别的发现,我会给你回电话的。