lox*_*xxy 4 microcontroller microprocessors x86-16
为什么我们不能将数据直接从内存位置移动到另一个内存位置.
请原谅我,如果我问一个愚蠢的问题,但我认为这是一个真实的情况,至少对于我遇到的问题(8085,8086 n 80386)
我并不是在寻找一种移动数据的解决方案(例如,使用movs n all),但实际上是这种异常的原因.
基本原因是大多数指令集允许一个寄存器操作数和一个内存操作数,坚持这种格式使设计指令解码器更容易。它还使 CPU 内的执行引擎更容易,因为该指令通常可以仅对一个内存位置发出内存操作,并且最多可以读取或写入一个寄存器块。
直接执行内存到内存指令需要指定两个内存位置。考虑到寄存器/内存指令格式,这很尴尬。鉴于机器的性能,几乎没有理由为此修改指令格式。
更现代的 CPU 使用的一种技巧是提供某种类型的块移动指令,其中源位置和目标位置位于寄存器中(对于 X86,分别是 ESI 和 EDI)。然后一条指令可以只指定两个寄存器(或者在 x86 的情况下,指令只知道哪些寄存器)。这解决了指令解码问题。
指令执行问题有点难,但人们有很多晶体管。组织从一个寄存器间接读取,并通过另一个寄存器间接写入,并递增两者在硅中很尴尬,但这只会消耗一些晶体管。现在您可以按照您的要求从内存移动到内存的指令。为 X86 注意到的其他海报之一有说明(MOVB、MOVW、MOVS,...)正是这样做的,一次一个内存字节/字/...。
移动内存块将是理想的,因为 CPU 可以生成高带宽读取和写入。x86 使用 MOV- 上的 REP(重复)前缀来移动更大的块。
但是,如果单个指令可以做到这一点,您就会遇到执行可能需要很长时间(移动 1Gb 需要多长时间?--> 数百万个时钟周期!)的问题,这会破坏 CPU 的中断响应率。
x86 通过允许 REP MOV- 被中断来解决这个问题,PC 被设置回指令的开头。通过在移动期间适当地更新寄存器,您可以中断并重新启动具有快速块移动和高中断响应率的 REP MOV- 指令。管子里有更多的晶体管。
RISC 人员发现块移动指令的所有这些复杂性大多不值得。您可以编写一个愚蠢的循环(甚至是 x86):
copy: MOV EAX,[ESI]
ADD ESI,4
MOV [EDI],EAX
ADD EDI,4
DEC ECX
JNE copy
Run Code Online (Sandbox Code Playgroud)
它的基本功能与 REP MOV- 相同。几乎现代 CPU(x86,其他)执行此操作如此之快(超标量等),以至于总线就像自定义移动指令一样被利用,但现在您不需要所有那些浪费的晶体管(或相应的热量)。
| 归档时间: |
|
| 查看次数: |
4615 次 |
| 最近记录: |