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

标签 c arrays assembly reverse-engineering x86-64

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正在返回。

问题:

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

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

  3. M 的值是多少? ?

我的想法:

  1. rdxrdx总是增加 8,因此它会遍历整行。

  2. rsi或许??? rsi设置为保存返回值,我认为返回值是元素 A[j][i]

  3. 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/

相关文章:

java - 整数数组的交替元素之和

linux - 为什么 gdb 以这种方式打印寄存器值

c - sparc64 上 sparc 汇编代码的 unsigned long long int 问题

c# 从带有 char * 的 C DLL 回调

编译多个 .c 和 .h 文件

c - 测试或验证红黑树的属性

python - 优化大型阵列沿一个轴的平均值的异常计算

python - 在 numpy 数组中,我想将一列复制到另一个矩阵并从原始矩阵中删除该列

linux - x64 NASM 汇编程序在程序开始时显示段错误

python - 如果Python元组中的ob_item指针是静态数组,我们如何移动它?