如果你有三维数组,你如何解决数组的固定常数?我可以通过汇编代码计算出公式((32k + j)16 + i) in %rax用于索引array2和((32i + j)16 + k)在%rdx中用于索引array1,但这如何帮助我们找到常数M, N和L?
#define M ___________
#define N ____________
#define L ____________
int array1[M][N][L];
int array2[L][N][M];
int copyandsub(int i, int j, int k){
array1[i][j][k] = array2[k][j][i] - 1;
}
生成的汇编代码:
Copandsub:
movslq %edi, %rdi
movslq %edx, %rdx
movslq %esi, %rsi
movq %rdx, %rax
salq $5, %rax
addq %rsi, %rax
salq $4, %rax
addq %rdi, %rax
movl array2(,%rax,4), %eax
subl $1, %eax
salq $5, %rdi
addq %rdi, %rsi
salq $4, %rsi
addq %rsi, %rdx
movl %eax, array1(,%rdx,4)
ret
假设你有:
int arrayTest[2][3][4];
// = technically equivalent of int flatArray[2*3*4]; for compiler
// That's how rest of the C++ compiled code will address it
for (auto m = 0; m < 2; ++m)
for (auto n = 0; n < 3; ++n)
for (auto l = 0; l < 4; ++l)
arrayTest[m][n][l] = m*100 + n*10 + l;
// value of each cell looks like "mnl" (ie arrayTest[1][2][0] == 120)
那么数组内存看起来像这样[value(显示三个索引)](索引到"flatArray"):
[000] ( 0) [001] ( 1) [002] ( 2) [003] ( 3)
[010] ( 4) [011] ( 5) [012] ( 6) [013] ( 7)
[020] ( 8) [021] ( 9) [022] (10) [023] (11)
[100] (12) [101] (13) [102] (14) [103] (15)
[110] (16) [111] (17) [112] (18) [113] (19)
[120] (20) [121] (21) [122] (22) [123] (23)
其中"扁平"索引为i = m*3*4 + n*4 + l;
。
还要注意的是内存内容的样子,逐行,即十六进制的dwords,它是:00000000 00000001 00000002 00000003 0000000A 0000000B 0000000C 0000000D 00000014 00000015 ...
(0xA = "010" in decimal).
所以你必须理解"扁平"索引是如何工作的,然后你的"((32k + j)16 + i)"one_answers"((32i + j)16 + k)"提供了足够的信息来计算原始M N l