2017年真题
【2017年题43】(13分)已知 ,计算 的 C 语言函数 f1 如下:
cint f1(unsigned n){int sum=1, power=1;for(unsigned i=0;i<=n-1;i++){power *= 2;sum += power;}return sum;}
将 f1 中的 int 都改为 float,可得到计算 的另一个函数 f2。假设 unsigned 和 int 型数据都占 32 位,float 采用 IEEE 754 单精度标准。请回答下列问题。
(1)当 n=0 时,f1 会出现死循环,为什么?若将 f1 中的变量 i 和 n 都定义为 int 型,则 f1 是否还会出现死循环?为什么?
(2)f1(23)和 f2(23)的返回值是否相等?机器数各是什么(用十六进制表示)?
(3)f1(24)和 f2(24)的返回值分别为 33 554 431 和 33 554 432.0,为什么不相等?
(4),而 f1(31)的返回值却为-1,为什么?若使 f1(n)的返回值与 相等,则最大的 n 是多少?
(5)f2(127)的机器数为 7F80 0000H,对应的值是什么?若使 f2(n)的结果不溢出,则最大的 n 是多少?若使 f2(n)的结果精确(无舍入),则最大的 n 是多少?
解析:
(1)由于 i 和 n 是 unsigned 型,故“i <= n-1”是无符号数比较,n = 0 时,n - 1 的机器数为全 1,值是 ,为 unsigned 型可表示的最大数,条件“i <= n-1”永真,因此出现死循环。(2分)
若 i 和 n 改为 int 类型,则不会出现死循环。(1分)
因为“i <= n-1”是带符号整数比较,n = 0 时,n - 1 的值是-1,当 i = 0 时条件“i <= n-1”不成立,此时退出 for 循环。(1分)
(2)f1(23)与 f2(23)的返回值相等。(1分),它的二进制形式是 24 个 1。int 占 32 位,没有溢出。float 有 1 个符号位,8 个指数位,23 个底数位,23 个底数位可以表示 24 位的底数。所以两者返回值相等。
f1(23)的机器数是 00FF FFFFH。(1分)
f2(23)的机器数是 4B7F FFFFH。(1分)
显而易见前者是 24 个 1,即 ,后者符号位是 0,指数位为 ,底数位是 。
(3)当 n = 24 时,,而 float 型数只有 24 位有效位,舍入后数值增大,所以 f2(24)比 f1(24)大 1。(1分)
【评分说明】只要说明 f2(24)需舍入处理即可给分。
(4)显然 已超出了 int 型数据的表示范围,用 f1(31)实现时得到的机器数为 32 个 1,作为 int 型数解释时其值为-1,即 f1(31)的返回值为-1。(1分)
因为 int 型最大可表示数是 0 后面加 31 个 1,故使 f1(n)的返回值与 相等的最大 n 值是 30。(1分)
【评分说明】对于第二问,只要给出 n = 30 即可给分。
(5)IEEE 754 标准用“阶码全 1、尾数全 0”表示无穷大。f2 返回值为 float 型,机器数 7F80 0000H 对应的值是 。(1分)
当 n = 126 时,,对应阶码为 ,尾数部分舍入后阶码加 1,最终阶码为 254,是 IEEE 754 单精度格式表示的最大阶码。故使 f2 结果不溢出的最大 n 值为 126。(1分)
当 n = 23 时, 为 24 位 1,float 型数有 24 位有效位,所以不需舍入,结果精确。故使 f2 获得精确结果的最大 n 值为 23。(1分)
【评分说明】对于第二问,只要给出 n = 23,即可给分。对于第三问,只要给出 n = 126,即可给分。
【2017年题44】(10分)在按字节编址的计算机 M 上,题 43 中 f1 的部分源程序(阴影部分)与对应的机器级代码(包括指令的虚拟地址)如下图所示。
其中,机器级代码行包括行号、虚拟地址、机器指令和汇编指令。请回答下列问题。
(1)计算机 M 是 RISC 还是 CISC?为什么?
(2)f1 的机器指令代码共占多少字节?要求给出计算过程。
(3)第 20 条指令 cmp 通过 i 减 n-1 实现对 i 和 n-1 的比较。执行 f1(0)过程中,当 i=0 时,cmp 指令执行后,进/借位标志 CF 的内容是什么?要求给出计算过程。
(4)第 23 条指令 shl 通过左移操作实现了 power2 运算,在 f2 中能否也用 shl 指令实现 power2?为什么?
解析:
(1)M 为 CISC。(1分)
M 的指令长短不一,不符合 RISC 指令系统特点。(1分)
(2)f1 的机器代码占 96B。(1分)
因为 f1 的第一条指令“push ebp”所在的虚拟地址为 0040 1020H,最后一条指令“ret”所在的虚拟地址为 0040 107FH,所以,f1 的机器指令代码长度为 个字节。(1分)
(3)CF = 1。(1分)
cmp 指令实现 i 与 n - 1 的比较功能,进行的是减法运算。在执行 f1(0)过程中,n = 0,当 i = 0 时,i = 0000 0000H,并且 n - 1 = FFFF FFFFH。因此,当执行第 20 条指令时,在补码加/减运算器中执行“0 减 FFFF FFFFH”的操作,即 ,此时,进位输出 C = 0,减法运算时的借位标志 。(2分)
(4)f2 中不能用 shl 指令实现 power2。(1分)
因为 shl 指令用来将一个整数的所有有效数位作为一个整体左移;而 f2 中的变量 power 是 float 型,其机器数中不包含最高有效数位,但包含了阶码部分,将其作为一个整体左移时并不能实现“乘 2”的功能,因而 f2 中不能用 shl 指令实现 power2。(2分)浮点数运算比整型运算要复杂,耗时也较长。
【2017年题45】(7分)假定题 44 给出的计算机 M 采用二级分页虚拟存储管理方式,虚拟地址格式如下:
请针对题 43 的函数 f1 和题 44 中的机器指令代码,回答下列问题。
(1)函数 f1 的机器指令代码占多少页?
(2)取第 1 条指令(push ebp)时,若在进行地址变换的过程中需要访问内存中的页目录和页表,则会分别访问它们各自的第几个表项(编号从 0 开始)?
(3)M 的 I/O 采用中断控制方式。若进程 P 在调用 f1 之前通过 scanf()获取 n 的值,则在执行 scanf()的过程中,进程 P 的状态会如何变化?CPU 是否会进入内核态?
解析:
(1)函数 f1 的代码段中所有指令的虚拟地址的高 20 位相同,因此 f1 的机器指令代码在同一页中,仅占用 1 页。(1分)页目录号用于寻找页目录的表项,该表项包含页表的位置。页表索引用寻找页表的表项,该表项包含页的位置。
(2)push ebp 指令的虚拟地址的最高 10 位(页目录号)为 00 0000 0001,中间 10 位(页表索引)为 00 0000 0001,所以,取该指令时访问了页目录的第 1 个表项,(1分)在对应的页表中访问了第 1 个表项。(1分)
(3)在执行 scanf()的过程中,进程 P 因等待输入而从执行态变为阻塞态。(1分)输入结束时,P 被中断处理程序唤醒,变为就绪态。(1分)P 被调度程序调度,变为运行态。(1分)CPU 状态会从用户态变为内核态。(1分)
【2017年题46】(8分)某进程中有 3 个并发执行的线程 thread1、thread2 和 thread3,其伪代码如下所示。
请添加必要的信号量和 P、V(或 wait()、signal())操作,要求确保线程互斥访问临界资源,并且最大限度地并发执行。
解析:
先找出线程对在各个变量上的互斥、并发关系。如果是一读一写或两个都是写,那么这就是互斥关系。每一个互斥关系都需要一个信号量进行调节。
csemaphore mutex_y1=1; //mutex_y1 用于 thread1 与 thread3 对变量 y 的互斥访问。semaphore mutex_y2=1; //mutex_y2 用于 thread2 与 thread3 对变量 y 的互斥访问。semaphore mutex_z=1; //mutex_z 用于变量 z 的互斥访问。
互斥代码如下:(5分)
【评分说明】
① 各线程与变量之间的互斥、并发情况及相应评分见下表。
② 若考生仅使用一个互斥信号量,互斥代码部分的得分最多给 2 分。
③ 答案部分正确,酌情给分。
html<!-- 题 45 虚拟地址格式图 --><img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 540 50' width='100%25' height='50'%3E%3Cdefs%3E%3Cstyle%3E .tbl-cell %7B font-family: 'SimSun', 'STSong', 'Songti SC', 'Times New Roman', serif; font-size: 13px; fill: %23111; text-anchor: middle; dominant-baseline: central; %7D .tbl-line %7B stroke: %23111; stroke-width: 1.5; %7D %3C/style%3E%3C/defs%3E%3Cline x1='20' y1='10' x2='520' y2='10' class='tbl-line' /%3E%3Cline x1='20' y1='40' x2='520' y2='40' class='tbl-line' /%3E%3Cline x1='180' y1='10' x2='180' y2='40' stroke='%23111' stroke-width='1.2' /%3E%3Cline x1='340' y1='10' x2='340' y2='40' stroke='%23111' stroke-width='1.2' /%3E%3Ctext x='100' y='25' class='tbl-cell'%3E页目录号(10 位)%3C/text%3E%3Ctext x='260' y='25' class='tbl-cell'%3E页表索引(10 位)%3C/text%3E%3Ctext x='430' y='25' class='tbl-cell'%3E页内偏移量(12 位)%3C/text%3E%3C/svg%3E" /><!-- 题 46 题目伪代码图 --><img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 350' width='100%25' height='350'%3E%3Cdefs%3E%3Cstyle%3E .code-txt %7B font-family: 'SimSun', 'STSong', 'Songti SC', 'Times New Roman', serif; font-size: 13px; fill: %23111; dominant-baseline: central; %7D .tbl-border %7B fill: %23ffffff; stroke: %23111; stroke-width: 1.2; %7D %3C/style%3E%3C/defs%3E%3Crect x='20' y='10' width='560' height='330' class='tbl-border' /%3E%3Cline x1='260' y1='10' x2='260' y2='340' stroke='%23111' stroke-width='1.2' /%3E%3Cline x1='420' y1='10' x2='420' y2='340' stroke='%23111' stroke-width='1.2' /%3E%3Ctext x='30' y='28' class='code-txt'%3E//复数的结构类型定义%3C/text%3E%3Ctext x='30' y='48' class='code-txt'%3Etypedef struct%3C/text%3E%3Ctext x='30' y='68' class='code-txt'%3E%7B%3C/text%3E%3Ctext x='45' y='88' class='code-txt'%3Efloat a;%3C/text%3E%3Ctext x='45' y='108' class='code-txt'%3Efloat b;%3C/text%3E%3Ctext x='30' y='128' class='code-txt'%3E%7D cnum;%3C/text%3E%3Ctext x='30' y='148' class='code-txt'%3Ecnum x, y, z; // 全局变量%3C/text%3E%3Ctext x='30' y='188' class='code-txt'%3E//计算两个复数之和%3C/text%3E%3Ctext x='30' y='208' class='code-txt'%3Ecnum add( cnum p, cnum q)%3C/text%3E%3Ctext x='30' y='228' class='code-txt'%3E%7B%3C/text%3E%3Ctext x='45' y='248' class='code-txt'%3Ecnum s;%3C/text%3E%3Ctext x='45' y='268' class='code-txt'%3Es.a = p.a+q.a;%3C/text%3E%3Ctext x='45' y='288' class='code-txt'%3Es.b = p.b+q.b;%3C/text%3E%3Ctext x='45' y='308' class='code-txt'%3Ereturn s;%3C/text%3E%3Ctext x='30' y='328' class='code-txt'%3E%7D%3C/text%3E%3Ctext x='270' y='28' class='code-txt'%3Ethread1%3C/text%3E%3Ctext x='270' y='48' class='code-txt'%3E%7B%3C/text%3E%3Ctext x='285' y='68' class='code-txt'%3Ecnum w;%3C/text%3E%3Ctext x='285' y='88' class='code-txt'%3Ew = add( x, y);%3C/text%3E%3Ctext x='285' y='108' class='code-txt'%3E...%3C/text%3E%3Ctext x='270' y='128' class='code-txt'%3E%7D%3C/text%3E%3Ctext x='270' y='168' class='code-txt'%3Ethread2%3C/text%3E%3Ctext x='270' y='188' class='code-txt'%3E%7B%3C/text%3E%3Ctext x='285' y='208' class='code-txt'%3Ecnum w;%3C/text%3E%3Ctext x='285' y='228' class='code-txt'%3Ew = add( y, z);%3C/text%3E%3Ctext x='285' y='248' class='code-txt'%3E...%3C/text%3E%3Ctext x='270' y='268' class='code-txt'%3E%7D%3C/text%3E%3Ctext x='430' y='28' class='code-txt'%3Ethread3%3C/text%3E%3Ctext x='430' y='48' class='code-txt'%3E%7B%3C/text%3E%3Ctext x='445' y='68' class='code-txt'%3Ecnum w;%3C/text%3E%3Ctext x='445' y='88' class='code-txt'%3Ew.a = 1;%3C/text%3E%3Ctext x='445' y='108' class='code-txt'%3Ew.b = 1;%3C/text%3E%3Ctext x='445' y='128' class='code-txt'%3Ez = add( z, w);%3C/text%3E%3Ctext x='445' y='148' class='code-txt'%3Ey = add( y, w);%3C/text%3E%3Ctext x='445' y='168' class='code-txt'%3E...%3C/text%3E%3Ctext x='430' y='188' class='code-txt'%3E%7D%3C/text%3E%3C/svg%3E
更新于2026-11-08
更新于2026-11-08
更新于2026-11-08