第一题
下列两个程序分别在C, 32位系统上运行,请分析最后的运行结果。
程序一:
int main(){
int value, count_value;
float sota;
scanf("%d\n", &value);
sota = (float)value;
count_value = (int)sota;
printf("%d", sota - count_value);
}
程序二:
int main(){
float sota = 0.1*INT_MAX;
float sum = 0.1;
while(1){
if(sum >= sota)break;
sum += 0.1;
}
printf("%lf", sum);
}
各位客官先不要着急看答案,可以自己思考一下,有基本的系统结构的知识的同学应该不难回答这两个问题,所以,请大家把答案打在下方的评论区,然后再来看吧!
第二题
请详细分析下列语句中出现的相关性种类。
L.D F0, 0(R1) S1;
MuL.D F4, F0, F2 S2;
S.D F4, 0(R1) S3;
DADDIU R1, R1, #-8 S4;
BNE R1, R2 loop S5;
L.D F0, 0(R1) S6;
MUL.D F4, F0, F2 S7;
S.D F4, 0(R1) S8;
DADDIU R1, R1, #-8 S9;
BNE R1, R2, loop S10;
答案揭晓
程序一 : 输出为 -64 至 63 之间的整数值,都为合理。
因为这是系统中所有的误差值,三十二位的操作系统,其有效值位为23,一个符号位,七个指数位,故输出的可能值是 最大的截断值,全一指数(127),然后右移一位,即128/2 - 1 = 63, 负数因为使用符号位,补码表示,则是-64,
所以答案是一个区间,[-64, 63] 。
程序二 : 死循环
此程序表达的意思为,充分理解浮点数和整数的关系,为什么会是死循环呢?
因为当程序运行到一定阶段,每次只加0.1就没有用了,加不上去,相加产生的误差就是第一个程序那样,高达七位,那样0.1*INT_MAX这个指标永远也实现不了,所以出不来!
所以答案是程序会陷入循环中出不来 。
作者在写这道题的时候,天真的以为,强制类型转换不就是截断和加长吗,第一题就是0啊,第二题那不就输出 0.1*INT_MAX+0.1吗,这下一看,恍然大悟,不是一个层面啊,虽然0也是合理的,毕竟0属于[-64, 63]的区间内,第二题就跑的没边了!
第二题
怎么说呢, 本题主要考两个知识,第一,就是数据相关的种类,读后写,写后读,写后写。还有名称相关,控制相关。这一题中没有用到名称相关,因为那是在同一个寄存器上进行写操作的相关。 还有一点冷门知识:
"""
L.D 取指令 也就是往寄存器里写。
S.D 存储指令,还是往寄存器里写。
MUL.D 乘法指令,后两个操作数进行相乘,结果放到第一个操作数中。
DADDIU. 加法指令,把一个寄存器的内容加上一个立即数并忽略溢出,
其中D是定点寄存器, ADD是加法 I是立即数,U是忽略溢出
BNE 判断两个数相不相等, 若不相等则继续,相等就跳转, N是not, E是equal.
"""
所以呢,S1与 S2,S2与S3, S3与S4,S4与S5, S6与 S7, S7与S8, S8与S9, S9与S10都存在数据相关,其中
S1 , S2 写后读, RAW.
S2 , S3 写后写, WAW.
S3 , S4 读后写, WAR.
S4 , S5 写后读, RAW. + 控制相关
S6 , S7 写后读, RAW.
S7 , S8 写后写, WAW.
S8 , S9 读后写, WAR.
S9 , S10 写后读, RAW. + 控制相关
明确概念,才能少出错误!