[英]What is the minimum number of addressing modes necessary for computation?
在x86汇编程序中,假设你有
为什么需要索引和基指针寻址模式 ? 据我所知,每个都可以用循环代替。
间接模式似乎也没有太大用处,因为您可以简单地使用直接模式来引用内存地址。 首先访问寄存器的目的是什么,然后包含指向存储器地址的指针?
简而言之,哪些寻址方式确实是必要的?
虽然理论上“寻址模式”可用于指代操作数类型,但由于它不涉及地址,因此有点令人困惑。 英特尔手册使用“寻址模式”来指代内存寻址,我将使用此定义。
在汇编中,操作数可以是:
在x86架构中,“寻址模式”仅适用于最后一种类型的操作数:存储器操作数(地址),并且指的是可用于计算地址的方法。 寻址模式可以在单个可配置寻址模式中汇总:
address = REG_base + REG_index*n + offset
REG_base
, REG_index
, n
和offset
都是可配置的,并且都可以省略(但显然至少需要一个)。
address = offset
称为立即,直接或绝对寻址。
address = REG_base
称为寄存器间接寻址。
address = REG_base + REG_index
称为base plus index寻址。
同样,您可以添加偏移量( offset
)和比例( n
)。
严格来说,您只需要一种模式即可完成所有操作:注册间接寻址( address = REG
)。 这样,如果需要访问内存,可以在寄存器中计算所需的任何地址,并使用它来进行访问。 它也可以通过使用内存替换直接寄存器操作数,并通过使用算术构造值来立即操作数。 但是,对于实际的指令集,您仍然可以立即有效地加载地址操作数,如果您不想要仅指针寄存器,则需要注册操作数。
除了间接寄存器之外的所有其他寻址模式都是为了方便起见,它们确实非常方便:
int
)数组,而无需额外的寄存器或计算。 这些寻址模式不需要CPU的大量计算:只需要添加和移位。 考虑到x86可以在每个周期进行乘法,这些操作很简单,但仍然非常方便。
没有寄存器,x86不能做太多,所以我认为你不能摆脱寄存器“寻址模式”。 一些非常不同的架构可能不使用寄存器,只有堆栈或内存,内存指令。 IDK如何实现指针; 也许这样的架构可以做memory[memory]
(C数组表示法)。
是不是需要立即进行计算成为可能 。 您可以使用多个寄存器构造任何值。 以零(开始xor eax, eax
), inc
就拿到1,左移它给你想要的任何位置, inc
要设置低位,左移等,所以它需要在最糟糕的2*popcount(N)
指令将N
放入寄存器。 请注意,即时移位计数将不可用,因此重复移位一个显而易见的方法( shl eax
,是的,有一个单独的编码,一个一个,或只是使用add eax, eax
)将取决于在最高设置位的位置。 所以log2(N) + popcount(N)
表示明显的shift和inc。
绝对(你所谓的直接)内存寻址不是最有用的寻址模式。 我们可以通过使用一系列指令构造地址(见上文)和使用[register]
来模拟它。 如果我们试图削减,我们想放弃它。 正如杰斯特所指出的那样,保持绝对地址作为我们唯一的形式将是非常不方便(或者可能不可能?)使用。
索引显然可用于性能,而不是必需:您可以使用单独的指令进行移位和添加。
位移也仅用于性能,因此我们可以摆脱它们并强制代码手动添加任何位移。 请参阅立即段落了解具体方法。
我相信86仍然被任意编程, 只需 register
和[register]
寻址模式。
使用register
, [register]
和immediate
,性能应该比完整的x86差很多。
如果对内存的隐式访问不算作寻址模式,您当然可以使用lodsd
和stosd
模拟[register]
,但是您将无法进行原子读 - 修改 - 写操作。 但这感觉就像是作弊。
还有堆栈( push/pop
):我不知道堆栈+寄存器机器是否是Turing-complete,但它通常不是通常意义上的可编程。 当然,如果你修改e/rsp
,你可以再次模拟[register]
,但操作数大小的选择少于lodsb/w/d/q
/ stosb/w/d/q
。
如果包含16个ymm寄存器,x86有足够的空间存储寄存器。 虽然我想不出一种在整数寄存器和ymm的高128b之间移动数据的方法,而不使用任何内存或立即操作数(对于vextractf128
),所以在实践中你有更多像16个16B向量寄存器槽用于存储本地堆栈以外的状态。 尽管如此,它的大小有限,这可能意味着32位386 ISA中的8个GP寄存器与64位AVX2 ISA中的所有整数/ mmx / ymm寄存器无关,这与机器是否只有推/弹的图像完全无关,寄存器,除了通过push / pop之外没有修改堆栈指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.