我正在分析汇编中的嵌套数组访问代码,其中数组包含整数。机器代码计算访问特定子数组的行偏移量。这是我观察到的:
根据我的理解,因子 4 似乎与整数的大小(4 字节)有关。不过,我不确定这个解释是否正确。具体来说:
我想确认此类汇编计算中的 4 是否始终与数组元素的大小(在本例中为整数)相关。如果是这样,对于不同元素大小或子数组大小的数组,装配细分将如何变化?
例如,在大小为 6 的子数组中,我们可以有这样的东西:
# %rdi = index
movq %rdi, %rcx # Copy %rdi (index) to %rcx
salq $1, %rcx # Left shift %rcx by 1 to compute 2 * index
leaq (%rcx, %rdi, 4), %rax # Compute 6 * index using 2 * index + 4 * index
leaq pgh(,%rax,4), %rax # Compute pgh + (24 * index)
或
# %rdi = index
leaq (%rdi, %rdi, 2), %rax # Compute 3 * index
leaq pgh(,%rax,8), %rax # Compute pgh + (24 * index)
我的疑问是编译器在生成汇编代码时如何处理此偏移量......在计算这些内存偏移量时是否需要考虑元素大小(此处为整数)
是的,它需要考虑元素大小(这里 sizeof(integer)=4)。
或者只是找到最好的因素
是的,如果最佳因素包含每个元素的大小,那么这也有效。
我主要关心的是装配实现是否取决于找到最佳寻址模式(例如,1、2、4、8 等缩放因子)或明确考虑元素大小。我主要关心的是装配实现是否取决于找到最佳寻址模式(例如,1、2、4、8 等缩放因子)或明确考虑元素大小。
是的,在对数组进行索引的算术中必须考虑元素大小。
但是,最佳在某种程度上是主观的(即因处理器而异,有时因性能与空间、指令数/大小而异),但不,汇编不需要最佳 - 为什么会这样?
不求最好,只求准确。 任何能够准确完成索引背后的算术的方法都可以。 它只需要计算和访问正确的内存位置,但如何完成并不重要。
寻址和指针算术遵循与数学相同的属性,即交换性以及结合性和分布都适用。一般来说,编译器理解这一点。 当引用某些所需元素时,它只需要使用正确的数值(作为访问指令中的最终有效地址)即可。
此外,只要您为索引和中间体使用正确的数据类型,并且已知内存存在(即已正确分配为全局、本地或堆,并且访问位于边界)。