2016-11-01 8 views
0

Как вы собираетесь решать фиксированные константы массива, если у вас есть 3 измерения? Я могу вычислить, что код сборки получает формулу ((32k + j) 16 + i) в% 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 
+0

Это должно быть очевидно. Если вы посмотрите на каждый массив отдельно, вы должны знать размер последних двух измерений, но не первое измерение. –

+0

Какие номера соответствуют M, N и L? K совпадает с L для массива 2, и мы имеем 32 в качестве нашего фактора. Но ответ, по-видимому, M = 16, N = 32 и L = 16. Я просто не знаю, как связать значения с правыми константами. –

+0

'array1' - массив MxNxL. 'array1 [0]' - массив NxL, 'array1 [0] [0]' - массив длины L, 'array1 [0] [0] [0]' - это один 'int'. –

ответ

0

Допустим, у вас есть:

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) 

Затем память массив выглядит следующим образом [значение (с указанием TRIO-индексов)] (индекс в " 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;.

Также отметим, что, как содержимое памяти выглядит, строка за строкой, т.е. в шестигранных двойных слов это:
00000000 00000001 00000002 00000003 0000000A 0000000B 0000000C 0000000D 00000014 00000015 ... (0xA = «010» в десятичной системе).

Итак, вы должны понять, как работает этот «сплющенный» индекс, тогда ваш «(32k + j) 16 + i)» и «((32i + j) 16 + k)» дает достаточно информации для выяснения оригинал M, N, L.