视频加载失败

课程

1078 字
约 4 分钟

GPT

计算机系统基础exercises/Homework/RainClass/chapter03·更新于 2026-09-15

CSAPP P.179

int a [M][N], b [N] [M];

int sumij (int i, int j) {

    return a[i] [j] + b[j] [i];

}
1   movl        8(%ebp), %ecx   // i

2   movl        12(%ebp), %edx  // j

3   leal        (,%ecx, 8), %eax    // i * 8 -> eax

4   subl        %ecx, %eax      // i * 8 - i -> eax

5   addl        %edx, %eax      // i * 8 - i + j -> eax         得到a[M][N],    N = 7

6   leal        (%edx, %edx, 4), %edx       // j * 5 -> edx

7   addl        %ecx, %edx      // j * 5 + i -> edx       得到b[N][M],  M = 5

8   movl        a(,%eax, 4), %eax       // a[i][j]

9   addl        b(,%edx, 4), %eax       // b[j][i]

N = 7, M = 5

GPT

汇编代码分析:

  1. 函数参数传递

    1   movl        8(%ebp), %ecx   // 将参数 i 存入 %ecx
    2   movl        12(%ebp), %edx  // 将参数 j 存入 %edx

    参数 ij 分别存入寄存器 %ecx%edx


  1. 计算数组 a[i][j]的索引

    3   leal        (,%ecx, 8), %eax  // 计算 i * 8,存入 %eax
    4   subl        %ecx, %eax        // 计算 i * 8 - i
    5   addl        %edx, %eax        // 加上 j,最终计算 a[i][j] 的索引
    8   movl        a(,%eax, 4), %eax // 从数组 a 中取值
    • 第3行:leal (,%ecx, 8)表示 i × 8,对应数组a每行的大小为8 × 4 = 32字节。

      • 每行有 N = 8个元素(每个元素占 4 字节)。
    • 第 4 行:计算 i × 8 − i = i × 7,表明每行的元素索引与 i 有额外的调整。

    • 第 5 行:最终索引为 i × 7 + j,用于访问数组 a


  1. 计算数组 b[j][i] 的索引

    6   leal        (%edx, %edx, 4), %edx  // 计算 j * 5,存入 %edx
    7   addl        %ecx, %edx             // 加上 i,最终计算 b[j][i] 的索引
    9   addl        b(,%edx, 4), %eax      // 从数组 b 中取值并加到 %eax
    • 第 6 行: leal (%edx, %edx, 4) 表示 j + 4j = j × 5,对应数组 b每行的大小为 5 × 4 = 20 字节。

      • 每行有 M = 5 个元素(每个元素占 4 字节)。
    • 第 7 行:索引为 j × 5 + i,用于访问数组 b


推导出数组的维度:

  • 数组 a 的列数 N
    • a 每行占 8 × 4 = 32 字节,说明 N = 8。
  • 数组 b 的列数 M
    • b 每行占 5 × 4 = 20 字节,说明 M=5。

总结:

  • 数组 a 的大小为:int a[M][N],即 M × N = 5 × 8。
  • 数组 b 的大小为:int b[N][M],即 N × M = 8 × 5。

Copilot

根据汇编代码,可以推断出数组 ab 的维度 MN 的值。

汇编代码分析

1   movl        8(%ebp), %ecx       ; 将参数 i 的值加载到寄存器 %ecx 中

2   movl        12(%ebp), %edx      ; 将参数 j 的值加载到寄存器 %edx 中

3   leal        (,%ecx, 8), %eax    ; 计算 %ecx * 8,结果存入 %eax 中

4   subl        %ecx, %eax          ; 计算 %eax - %ecx,即 %ecx * 8 - %ecx = %ecx * 7

5   addl        %edx, %eax          ; 计算 %eax + %edx,即 %ecx * 7 + %edx

6   leal        (%edx, %edx, 4), %edx ; 计算 %edx + %edx * 4,即 %edx * 5

7   addl        %ecx, %edx          ; 计算 %edx + %ecx,即 %edx * 5 + %ecx

8   movl        a(,%eax, 4), %eax   ; 访问 a[%eax],即 a[i * 7 + j]

9   addl        b(,%edx, 4), %eax   ; 访问 b[%edx],即 b[j * 5 + i]

确定 M 和 N 的值

从汇编代码中可以看出,数组 ab 的访问方式如下:

  • a[i][j] 被转换为 a[i * 7 + j]
  • b[j][i] 被转换为 b[j * 5 + i]

这意味着:

  • 数组 a 的列数 N 为 7
  • 数组 b 的列数 M 为 5

因此,MN 的值分别为:

  • M = 5
  • N = 7
Profile Image of the Author
Sonder
好想要技术
这是公告标题
这只是一个公告
分类
标签
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录