多维数组索引是否调用函数来计算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]
如果您像示例中那样编写索引,编译器将在编译时计算所需的确切内存地址。
如果索引是变量,那么地址将在运行时计算。
在不考虑优化的情况下,编译器实现对数组元素的引用的标准方式,比如 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]
. 的地址
总结一下,如果s
是a
的起始地址,我们使用字节为单位,那么a[i][j]
的地址就是s
+ 16•i
+ 4•j
.
假设我正在使用 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]
如果您像示例中那样编写索引,编译器将在编译时计算所需的确切内存地址。
如果索引是变量,那么地址将在运行时计算。
在不考虑优化的情况下,编译器实现对数组元素的引用的标准方式,比如 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]
. 的地址
总结一下,如果s
是a
的起始地址,我们使用字节为单位,那么a[i][j]
的地址就是s
+ 16•i
+ 4•j
.