Str*_*rin 14 x86 assembly instruction-set cpu-architecture
在英特尔架构IA32中,诸如movl,movw之类的指令不允许作为内存位置的操作数.例如,不允许使用指令movl(%eax),(%edx).为什么?
Dou*_*gvj 15
答案包括更全面地了解RAM.简单地说,RAM只能处于两种状态,即读模式或写模式.如果您希望将ram中的一个字节复制到另一个位置,则在从读取切换到写入时,必须在RAM外部具有临时存储区域.
该架构当然有可能具有这样的RAM到RAM指令,但它将是一个高级指令,在微码中将转换为将数据从RAM复制到寄存器然后再复制到RAM.或者,可以扩展RAM控制器以使这样的临时寄存器仅用于这种数据复制,但是它不会为CPU /硬件交互的增加的复杂性提供很多好处.
编辑:值得注意的是,最近的进展,如混合存储器立方体和高带宽存储器是一种架构,其中RAM拓扑变得更像PCI-e和直接RAM到RAM传输现在是可能的,但这是由于支持逻辑对于技术,而不是RAM本身.在CPU架构中,这将是一次大块RAM的形式,如DMA,而不是单个指令的形式,加上CPU缓存的行为类似于传统RAM,因此架构必须将其抽象为根据我原来的解释
EDIT2: Per @PeterCordes评论,我原来的理解并不完全正确; 事实上,x86确实有一些内存到内存指令.它们不适用于大多数指令(例如movl和movw)的真正原因是保持指令编码复杂度低,但是他们可以实现它们.但是,我原来的答案中的基本思想是,在锁存器或寄存器形式的RAM之外存在临时存储位置是正确的,但是这就是为什么这些指令不存在的原因不是.即使是20世纪70年代的老式芯片,如6502和8086,也有内存到内存指令,您可以直接在RAM位置轻松执行INC等操作.这是通过将存储器提取直接锁存到ALU并再次返回存储器而不通过指令集使用的寄存器来实现的.
ia32是x86,x86是intel 8086(iAPX 86)的演进版.它是基于8位指令集的小而廉价的芯片,并且没有带有两个显式存储器操作数的"mov".
维基百科的作者给出了关于8086的指令编码的解释:
由于受8位处理器启发的紧凑编码,大多数指令是单地址或双地址操作,这意味着结果存储在其中一个操作数中.最多一个操作数可以在内存中,但是这个内存操作数也可以是目标,而另一个操作数,即源,可以是寄存器或立即数.单个存储器位置通常也可以用作源和目标,除其他因素外,还可以进一步提供与当时大多数8位机器相当(并且通常优于)的代码密度.
有一些具有存储器存储器指令的CISC(单个指令用于操作两个存储器操作数).讲座https://www.cis.upenn.edu/~milom/cis501-Fall05/lectures/02_isa.pdf说VAX可以编码内存内存指令:
DEC VAX(PDP-11的虚拟地址扩展):1977
- •可变长度指令:1-321字节!
- •14个GPR + PC +堆栈指针+条件代码
- •数据大小:8,16,32,64,128位,十进制,字符串
- • 所有数据大小的存储器存储器指令
- •特殊情节:crc,insque,polyf和数百人
这是VAX的OpenBSD memcpy源代码(指令集手册http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04623178):
movq 8(ap),r1 /* r1 = src, r2 = length */
movl 4(ap),r3 /* r3 = dst */
...
1: /* move forward */
cmpl r2,r0
bgtru 3f /* stupid movc3 limitation */
movc3 r2,(r1),(r3) /* move it all */
Run Code Online (Sandbox Code Playgroud)
这里的"movc3"指令有两个存储器操作数,这些地址存储在寄存器中.
x86有几个"字符串"指令,它将执行内存操作(*s,尤其是movs - http://x86.renejeschke.de/html/file_module_x86_id_203.html),但是该指令将使用预定义的寄存器SI和DI作为地址(隐式操作数),两个内存操作数仍然无法在x86中编码.
| 归档时间: |
|
| 查看次数: |
4830 次 |
| 最近记录: |