视频加载失败

课程

1896 字
约 6 分钟

GPT

计算机系统基础exercises/Homework/RainClass/chapter03·更新于 2026-09-15
int refunc (unsigned x) {

    if( ___ )

        return ___ ;

    unsigned nx = ___ ;

    int rv = refunc(nx) ;

    return ___ ;

}
1   movl        8(%ebp), %ebx

2   movl        $0, %eax

3   testl        %ebx, %ebx

4   je              .L2

5   movl        %ebx, %eax

6   shrl        $1, %eax

7   movl        %eax, %(esp)

8   call        refunc

9   movl        %ebx, %edx

10  andl        $1, %edx

11  leal        (%edx,%eax), %eax

12  .L2 :

            ...

            ret

GPT

填写完整的 C 代码:

int refunc(unsigned x) {
    if (x == 0)
        return 0;
    unsigned nx = x >> 1;
    int rv = refunc(nx);
    return (x & 1) + rv;
}

汇编代码分析与对应 C 代码的还原:

  1. 函数参数读取

    1   movl        8(%ebp), %ebx
    • 将函数的第一个参数 x 存入 %ebx
    • C 对应:unsigned x
  2. 初始化返回值

    2   movl        $0, %eax
    • 初始化 %eax 为 0,对应 if (x == 0) return 0; 的返回值。
  3. 判断条件

    3   testl        %ebx, %ebx
    4   je              .L2
    • 检查 %ebx 是否为 0。如果是 0,则跳转到 .L2 并直接返回。
    • C 对应:if (x == 0) return 0;
  4. 计算 nx

    5   movl        %ebx, %eax
    6   shrl        $1, %eax
    • %ebx(x 的值)右移 1 位,将结果存入 %eax
    • C 对应:unsigned nx = x >> 1;
  5. 递归调用

    7   movl        %eax, %(esp)
    8   call        refunc
    • %eax 的值(nx)压入栈并调用函数 refunc
    • C 对应:int rv = refunc(nx);
  6. 计算返回值

    9   movl        %ebx, %edx
    10  andl        $1, %edx
    11  leal        (%edx,%eax), %eax
    • 第 9 行:将 %ebx 的值复制到 %edx
    • 第 10 行:计算 x & 1 并存入 %edx
    • 第 11 行:计算 (%edx + %eax),将结果存入 %eax
    • C 对应:return (x & 1) + rv;

函数的功能:

  • 功能描述:此函数计算一个非负整数 x 的二进制表示中有多少个 1(即汉明重量,Hamming Weight)。

  • 递归过程

    • 如果 x == 0,直接返回 0。
    • x 的二进制表示右移 1 位,递归调用 refunc 计算其低位的 1 的个数。
    • 最后将当前最低位的 1 与递归结果相加返回。

示例运行:

  • 输入: refunc(5)(5 的二进制为101

    • refunc(5)(5 & 1) + refunc(2)
    • refunc(2)(2 & 1) + refunc(1)
    • refunc(1)(1 & 1) + refunc(0)
    • refunc(0)0
    • 结果:(1) + (0) + (1) + (0) = 2
  • 输出25 的二进制表示有 2 个 1)。

Copilot

根据汇编代码,可以推断出C代码中缺失的部分,并说明函数的功能。

填写缺失的C代码

int refunc (unsigned x) {

    if (x == 0)

        return 0;

    unsigned nx = x >> 1;

    int rv = refunc(nx);

    return (x & 1) + rv;

}

说明函数的功能

函数 refunc 的功能是计算输入的无符号整数 x 的二进制表示中1的个数。也就是计算 x 的二进制表示中有多少个1。

对应的汇编代码解释

  1. movl 8(%ebp), %ebx:将参数 x 的值加载到寄存器 ebx 中。
  2. movl $0, %eax:将寄存器 eax 置为0。
  3. testl %ebx, %ebx:测试 ebx 是否为0。
  4. je .L2:如果 ebx 为0,跳转到标签 .L2,返回0。
  5. movl %ebx, %eax:将 ebx 的值复制到 eax 中。
  6. shrl $1, %eax:将 eax 的值右移1位(相当于 x >> 1)。
  7. movl %eax, (%esp):将 eax 的值压入栈中,作为递归调用 refunc 的参数。
  8. call refunc:递归调用 refunc
  9. movl %ebx, %edx:将 ebx 的值复制到 edx 中。
  10. andl $1, %edx:将 edx 与1进行按位与操作,得到 x 的最低位(即 x & 1)。
  11. leal (%edx,%eax), %eax:将 edxeax 的值相加,结果存入 eax 中。
  12. .L2:返回 eax 的值。

通过这些汇编指令,可以看出函数 refunc 通过递归计算 x 的二进制表示中1的个数。

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