当前位置: 首页 > news >正文

指令系统(2017统考真题)

指令系统(2017统考真题)

原始 C 语言函数为

int f1(unsigned n){
    int sum = 1, power = 1;
    for (unsigned i = 0; i < n-1; i++){
        power *= 2;
        sum   += power;
    }
    return sum;
}

该函数计算的是一个几何级数的和,其数学表达式为

f ( n ) = 1 + 2 + 2 2 + ⋯ + 2 n − 1 = 2 n − 1. f(n) = 1 + 2 + 2^2 + \cdots + 2^{n-1} = 2^n - 1. f(n)=1+2+22++2n1=2n1.

题目的要求是:将函数中所有的 int 换成 float 得到函数 f2(利用浮点运算计算 f(n)),同时给出与 f1 相关的机器级代码,提出下面四个问题,从汇编指令、机器代码占用、运算和浮点实现等角度考察对底层机制的理解。

附上的部分机器代码如下(每行包括行号、虚拟地址、机器指令及对应汇编指令):

int f1(unsigned n)
    1    00401020    55        push ebp
    ...    ...
    for(unsigned i=0;i<n-1;i++)
    ...    ...
    20    0040105E    39 4D F4    cmp dword ptr [ebp-0Ch], ecx
    ...    ...
        power *= 2;
    ...    ...
    23    00401066    D1 E2    shl edx,1
    ...    ...
        return sum;
    35    0040107F    C3        ret

下面依次对每个问题做详细分析和解释。


问题 1:机器 M 是 RISC 还是 CISC?为什么?

解答与分析:

  • 题目中给出的指令包括 push ebpcmp dword ptr [ebp-0Ch], ecxshl edx,1ret 等。
  • 观察这些指令可以发现:
    • 指令长度不固定(例如 push ebp 占 1 个字节,而 cmp 指令可能占 3 个字节)。
    • 存在复杂的寻址方式,如 dword ptr [ebp-0Ch] 表示基址+偏移的内存访问。
  • 这些都是典型的**CISC(复杂指令集计算机)**特点,而非 RISC(精简指令集计算机)的特征。
    • RISC 通常要求固定指令长度和简单的寻址模式,且大多数操作要求在寄存器间进行。
    • x86 这类采用可变长度和丰富寻址方式的体系正是 CISC。

答案:
机器 M 属于 CISC 架构,因为它使用了可变长度(例如 pushcmpshl 等)和复杂寻址模式,这些都是 CISC 的典型特征。


问题 2:f1 的机器指令代码共占多少个字节?要求给出计算过程。

解答与分析:

从给出的机器代码中我们知道:

  • 第一条指令出现在虚拟地址
    00401020 \mathtt{00401020} 00401020
  • 最后一条指令(ret)出现在虚拟地址
    0040107 F \mathtt{0040107F} 0040107F

计算连续代码区域所占的字节数时,可以按照下式计算(包含首尾地址上的所有字节):

总字节数 = ( 最后地址 − 首地址 ) + 最后一条指令的字节数 \text{总字节数} = (\text{最后地址} - \text{首地址}) + \text{最后一条指令的字节数} 总字节数=(最后地址首地址)+最后一条指令的字节数

其中:

  • 004010200040107F 的地址差为
    0040107 F − 00401020 = 0 x 7 F − 0 x 20 = 0 x 5 F ( 十六进制 ) \mathtt{0040107F} - \mathtt{00401020} = 0x7F - 0x20 = 0x5F \quad (\text{十六进制}) 0040107F00401020=0x7F0x20=0x5F(十六进制)

  • 但由于地址是连续且包含首尾,应再加 1 字节(而每个地址对应 1 个字节)。

  • 因此,总字节数为
    0 x 5 F + 1 = 0 x 60 = 96  字节 . 0x5F + 1 = 0x60 = 96 \text{ 字节}. 0x5F+1=0x60=96 字节.

答案:
f1 的机器指令代码占 96 字节,其计算过程为
总字节数 = ( 0040107 F − 00401020 ) + 1 = 0 x 5 F + 1 = 0 x 60 = 96  字节 . \text{总字节数} = (0040107F - 00401020) + 1 = 0x5F + 1 = 0x60 = 96 \text{ 字节}. 总字节数=(0040107F00401020)+1=0x5F+1=0x60=96 字节.


问题 3:关于第 20 行 cmp 指令

“cmp 通过 i 减小 1 实现对 i 与 n-1 的比较。在执行 f1(0) 的过程中,当 i = 0 时,cmp 指令执行后进位置/借位置标志 CF 的内容是什么?要求给出计算过程。”

解答与分析:

  • 根据编译器生成的代码,变量 i 存于内存地址 [ebp-0Ch],而寄存器 ecx 中传递的值为 n-1

  • 注意:由于传入参数 n 为无符号整数,当 n = 0 时,
    n − 1 = 0 − 1 ≡ 0 x F F F F F F F F ( 以 32 位无符号数理解 ) n - 1 = 0 - 1 \equiv 0xFFFFFFFF \quad (\text{以 32 位无符号数理解}) n1=010xFFFFFFFF( 32 位无符号数理解)

在循环初始时,i 被初始化为 0,所以 cmp 指令执行时是:

cmp    [ e b p − 0 C h ] ,    e c x ⟹ 比较  0  和  0 x F F F F F F F F . \text{cmp} \; [\mathtt{ebp-0Ch}], \; \mathtt{ecx} \quad\Longrightarrow\quad \text{比较 } 0 \text{ 和 } 0xFFFFFFFF. cmp[ebp0Ch],ecx比较 0  0xFFFFFFFF.

  • cmp 指令内部执行的运算相当于
    0 − 0 x F F F F F F F F . 0 - 0xFFFFFFFF. 00xFFFFFFFF.

  • 无符号运算中,如果被减数小于减数,则产生借位。

    • 由于 0 < 0 x F F F F F F F F 0 < 0xFFFFFFFF 0<0xFFFFFFFF,因此当执行 0 − 0 x F F F F F F F F 0 - 0xFFFFFFFF 00xFFFFFFFF 时,会造成借位,进而 CF(进位标志)被置为 1

(顺便说明:尽管模 2 32 2^{32} 232 的减法结果为
0 x 100000000 − 0 x F F F F F F F F = 1 , 0x100000000 - 0xFFFFFFFF = 1, 0x1000000000xFFFFFFFF=1,
但关键是对无符号减法而言,CF 用于表示是否产生借位。)

答案:
对于 f1(0),当 i = 0 时,执行
0 − 0 x F F F F F F F F 0 - 0xFFFFFFFF 00xFFFFFFFF
导致产生借位,故 cmp 指令执行后,CF = 1


问题 4:关于第 23 行 shl 指令

“第 23 行指令 shl 通过左移操作实现了 power2 的运算,请问在 f2 中能否用 shl 指令实现 power2?为什么?”

解答与分析:

  • f1 中,power 为整数,通过 shl edx, 1 实现左移 1 位(即乘以 2)的操作。这在整数的补码表示下是正确且高效的。
  • 而在 f2 中,所有的 int 都改成 float,也就是使用浮点数进行运算。
  • 浮点数(通常遵循 IEEE 754 标准)的内部表示与整数截然不同:
    • 浮点数由符号位、指数和尾数(有效数字)组成,
    • 并非连续的数值二进制序列,直接对其进行位移操作将破坏其格式,不会实现数学上乘 2 的效果。
  • 因此,在 f2 中,若使用整数指令 shl 对浮点数的二进制表示进行左移,其结果既不能正确计算 p o w e r × 2 power \times 2 power×2,也不会遵循浮点数运算规则。

答案:
在 f2 中无法使用 shl 指令实现 power*2 运算。因为浮点数采用 IEEE 754 格式,其二进制表示不适合直接位移运算。正确的做法应当使用浮点乘法指令(例如 fmul 或 SIMD 指令)以保证乘法运算的正确性。


涉及的主要知识点

  1. 整数与浮点数表示及运算

    • 补码表示:
      负数的表示方法:先逐位取反,再加 1。补码使得 N + ( − N ) ≡ 0    ( mod  2 n ) N + (-N) \equiv 0 \;(\text{mod }2^n) N+(N)0(mod 2n)
    • 浮点数表示:
      遵循 IEEE 754 标准,由符号位、指数位和尾数位构成,不适用于直接的位移操作。
  2. CISC 与 RISC 架构

    • CISC 特点:
      可变长度指令、复杂寻址模式(如基址加偏移)、较多的操作数种类。
    • RISC 特点:
      固定长度指令、简化的寻址模式,要求大部分算术运算在寄存器中进行。
  3. 汇编指令及机器级代码分析

    • 关键指令:
      • pushret:函数调用与返回。
      • cmp 指令:通过执行减法(不保存结果)设置标志位,用于实现条件判断。尤其要理解 CF(进位标志)的含义,若无符号减法中被减数小于减数,则 CF 被置 1。
      • shl 指令:左移操作,对于整数左移 1 位等于乘以 2。
    • 机器代码空间计算:
      根据起始和结束地址,并注意地址包含性来计算总字节数。
  4. 无符号数运算与模 2 n 2^n 2n 算术

    • 当对无符号数进行减法时,若结果为负则取模 2 n 2^n 2n 得到对应补码表示,例如 0 − 1 = 2 32 − 1 = 0 x F F F F F F F F 0 - 1 = 2^{32} - 1 = 0xFFFFFFFF 01=2321=0xFFFFFFFF
  5. 高层语言到汇编代码的转换

    • 理解 C 语言循环、条件比较和算术运算如何转换成汇编指令,并反推各局部变量如何在寄存器或内存中映射。
  6. 浮点运算的特殊性

    • 位运算指令(如 shl)适用于整数,但浮点数运算需要使用专用的硬件指令以保证正确的数学运算。

相关文章:

  • 人工智能在电子信息工程信号处理中的应用调研
  • 离线黑客攻击之绕过BIOS/EFI
  • openstack安装部署
  • docker-存储卷-网络
  • 游戏MOD伴随盗号风险,仿冒网站借“风灵月影”窃密【火绒企业版V2.0】
  • 存算分离是否真的有必要?从架构之争到 Doris 实战解析
  • INT202 Complexity of Algroithms 算法的复杂度 Pt.2 Search Algorithm 搜索算法
  • Error: The resource name must start with a letter
  • 代码随想录第55期训练营第七天|LeetCode454.四数相加II、383.赎金信、15.三数之和、18.四数之和
  • 基于javaweb的SSM+Maven宠物领养宠物商城流浪动物管理系统与实现(源码+文档+部署讲解)
  • 【PCIe 总线及设备入门学习专栏 3.2 -- PCIe 在进行大数据搬运时是如何组包的?】
  • 【STM32实物】基于STM32的太阳能充电宝设计
  • Android adb调试应用程序
  • 【时时三省】(C语言基础)习题2 scanf函数
  • 在Springboot中集成unihttp后应用无法启动的解决办法
  • IoTDB TTL不生效
  • 3月21日星期五今日早报简报微语报早读
  • 精密校平机:工业制造的精度之源
  • mac上安装nvm及nvm的基本语法使用!!
  • 安装CentOS7
  • 印对巴军事打击后,巴外交部召见印度驻巴临时代办
  • 李云泽:将加快出台与房地产发展新模式相适配的系列融资制度
  • 五角大楼要裁一批四星上将
  • 抗战回望18︱《广西学生军》:“广西的政治基础是青年”
  • 郭少雄导演逝世,享年82岁
  • 出口管制不能将民用技术泛安全化,也不能破坏全球供应链稳定