多维数组索引是否调用函数来计算c中的元素地址?

Does multidimentional array indices calls a function to calculate the element adress in c?

假设我正在使用 ARM Cortex M7。现在看看:

int a[4][4];
a[i][j]=5;

在汇编语言中,函数是否会计算 a[j][j] 地址,或者它使用查找表(具有相同大小的指针数组)或一些神奇的方法将 5 放在正确的位置?

这是反汇编程序的输出:

136               array1[i][i+1]=i;
08000da6:   ldr     r3, [r7, #36]   ; 0x24
08000da8:   adds    r3, #1
08000daa:   ldr     r2, [r7, #36]   ; 0x24
08000dac:   uxtb    r1, r2
08000dae:   ldr     r2, [r7, #36]   ; 0x24
08000db0:   lsls    r2, r2, #2
08000db2:   add.w   r0, r7, #40     ; 0x28
08000db6:   add     r2, r0
08000db8:   add     r3, r2
08000dba:   subs    r3, #36 ; 0x24
08000dbc:   mov     r2, r1
08000dbe:   strb    r2, [r3, #0]

如果您像示例中那样编写索引,编译器将在编译时计算所需的确切内存地址。

如果索引是变量,那么地址将在运行时计算。

这里是comparison of assembly output for both cases.

在不考虑优化的情况下,编译器实现对数组元素的引用的标准方式,比如 x[k]:

  • x的内存地址开始。
  • x 的一个元素的字节数乘以 k
  • 将其添加到 x 的内存地址。

假设 int 有四个字节。

int a[4][4]a[i][j],有两个内存引用,所以地址计算:

  • a的内存地址开始。
  • a的元素是4个int的数组,所以a的一个元素的大小是4乘以4字节,即16字节。
  • 将 16 个字节乘以 i
  • 将其添加到 a 的地址。现在我们已经计算出了a[i].
  • 的地址
  • 我们使用a[i]的地址开始新的计算。
  • a[i]int的数组,所以a[i]的一个元素大小为4字节。
  • 将 4 个字节乘以 j
  • 将其添加到 a[i] 的地址。这给出了 a[i][j].
  • 的地址

总结一下,如果sa的起始地址,我们使用字节为单位,那么a[i][j]的地址就是s + 16•i + 4•j.