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 $8, %rdx
addq $120, %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 $8, %rdx
rdx +=8
6. addq $120, %rax
rax += 120
7. cmpq %rdi, %rax
jne .L6
int rdi = ?
if (rdi != rax) jump to L6
要点:
-
rdx
增加 8。 -
rdx
就像j
在C代码中。 - 数组中每行的长度为 120 字节。
for
之外循环rdx
可能初始化为0
。- 我还是不太明白
rax
正在返回。
问题:
哪个寄存器保存指向数组元素
A[i][j]
的指针?哪个寄存器保存指向数组元素
A[j][i]
的指针?M
的值是多少? ?
我的想法:
rdx
。rdx
总是增加 8,因此它会遍历整行。rsi
或许???rsi
设置为保存返回值,我认为返回值是元素A[j][i]
120 / 8 = 15
任何对我的回答的确认或拒绝将不胜感激。
最佳答案
元素是long
(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]
)。
关于c - 数组转置及对应的汇编代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35533075/