数组转置及对应的汇编代码

Array transpose and corresponding assembly code

C代码:

void transpose (long A[M][M]) {
    long i, j;
    for (i = 0; i < M; i ++)
        for (j = 0; j < i; j ++) {
            long t = A[i][j];
            A[i][j] = A[j][i];
            A[j][i] = t;
        }
}

相应的汇编代码基于-O1 INNER循环优化:

.L6:
    movq   (%rdx), %rcx  //
    movq   (%rax), %rsi
    movq   %rsi, (%rdx)
    movq   %rcx, (%rax)
    addq   , %rdx
    addq   0, %rax
    cmpq   %rdi, %rax
    jne    .L6

我对汇编代码的理解:

1.  movq (%rdx), %rcx
      int *rdx = ?
      int rcx = *rdx  

2.  movq (%rax), %rsi
      int *rax = ?
      int rsi = *rax  

3.  movq %rsi, (%rdx)
      *rdx = rsi = *rax

4.  movq %rcx, (%rax)
      *rax = rcx = *rdi

5.  addq , %rdx
      rdx +=8

6.  addq 0, %rax
      rax += 120

7.  cmpq %rdi, %rax
    jne .L6
      int rdi = ?
      if (rdi != rax) jump to L6

要点:

问题:

  1. 哪个寄存器保存指向数组元素的指针A[i][j]?

  2. 哪个寄存器保存指向数组元素的指针A[j][i]?

  3. M的值是多少?

我的想法:

  1. rdxrdx 总是上升 8,所以它遍历整行。

  2. rsi 也许吧??? rsi 设置为保存 return 值,我认为 return 值是元素 A[j][i]

  3. 120 / 8 = 15

如能确认我的回答或拒绝,我们将不胜感激。

元素是 longs(8 个字节长),并且您正在检查内部循环(在 j 上),所以:

rdx +=8

表示rdx明显指向A[i][j]

rax += 120

表示rax指向A[j][i]

M 等于 15,因为一行长 120 个字节(A[j][i]A[j+1][i] 之间的字节距离),每个 long 长 8 个字节(A[i][j]A[i][j+1] 之间的距离)。