XXB往年作业

采用16位定点整数方案表示数值数据时(虽然我在其中都采用字母大写,但是建议养成字母小写的习惯)。

有一点要提前说明:

 -128的补码是1,0000000?
[+0]原=0,000 0000 [-0]原=1,000 0000
[+0]反=0,000 0000 [+0]反=1,111 1111
[+0]补=0,000 0000 [-0]补=0,000 0000
正数的原码补码反码一样
而负数的反码是原码数值位全部取反,负数的补码则是原码数值位全部取反+1,符号位向上进位得到第九位,得到[-0]补=10,000 0000,但是采用机器字长只有8bit,所以第九位1丢弃,最终得到的[-0]补=0,000 0000=[+0]补
因此真值0的补码只有一种表现形式,而多出来一种表现形式,则将[x]补=1,0000000表示x=-128 ,补码整数的表示范围就会比原码多表示 -2^n )(可认为补码除符号位1剩下都为0,可认为前面的那个1是数值位,符号位隐藏,也是1)。
 

  1. 原码能表示的数据范围是-(pow(2,15)-1)~+(pow(2,15)-1),即-32767~32767。
  2. 反码能表示的数据范围是-(pow(2,15)-1)~+(pow(2,15)-1),反码1后面全是0,能表示的数据最小是-3276。
  3. 补码能表示的数据范围是-(pow(2,15)~+(pow(2,15)-1),其中补码1后面全是0,能表示的数最小,是-32768(2的15次方的负数)。
  4. 补码OX8000的真值是:补码OX8000的反码是OX7FFF,原码是OX8000即32768。
    总结如下:n位定点整数原码能表示的数据范围是-(pow(2,n-1)-1)~+pow(2,n-1)-1。
    反码能表示的数据范围是-(pow(2,n-1)-1)~+pow(2,n-1)-1。
    补码能表示的数据范围是-(pow(2,n-1))~+pow(2,n-1)-1。其中补码1后面(n-1)个0,能表示的数据最小,是-pow(2,n-1)。(其对应的数值位也是1后面(n-1)个0,符号位仍然是1)。
  5. 补码OXFFFF的真值是:补码减一为OXFFFE,取反为OX8001,最高位表示符号位,对应真值是-1。
  6. 补码OXFFB7的真值是:补码减一是OXFFB6,取反为OX8049,最高位表示符号位,对应的真值是-(4*16+9)=-73。
  7. -123的补码是:-123转化为16进制为OX807B,其反码是OXFF84,补码是OXFF85。
  8. 8位补码OX8A的十六位补码是:OXFF8A,明显前面加两个F(即8个1),取反的时候全部变成0,减一的时候不影响OX8A的计算。
  9. 8位补码OX7F的十六位补码是:很明显给定的数是正数,所以直接在前面加两个0。
  10. 8位无符号数OXAF的十六位形式是:OX00AF。

采用十六位定点小数方案表示数值数据时(这次我采用小写字母表示)。

首先我们要了解,十六位定点小数,整数位为0位,小数点前面的那个是符号位。小数位有15位。

  1. 能表示的数据的精度是pow(2,-15)。(可以这样想,十进制小数,小数点后面有n位,精度为pow(10,-n),同理,二进制小数小数点后面有n位,精度是pow(2,-n)。)
  2. 原码能表示的数据范围是:最小数是符号位是1,小数部分全是1,小数部分有15位,表示的数据是-(pow(2,15)-1)/pow(2,15),最大数是符号位为0,其余位都是1,表示的数据是pow(2,15)-1/pow(2,15)。即-32767/32768~32767/32768。
  3. 反码能表示的数据范围是:同上题中16位定点整数,能表示的最小数是符号位是1,数据位都是0,对应的数据是-(pow(2,15)-1)/pow(2,15),正数原码和反码表示相同。即-32767/32768~32767/32768。
  4. 补码能表示的数据范围是:同上题中16位定点整数,能表示最小的数是符号位是1,数据位全是0,对应的数据是-1。即-1~32767/32768。
    总结如下:其实和定点整数能表示的数据范围差不多,只不过除以2的n次方(n表示小数点后面的位数(注意:.1000的n看做1)。)
  5. 补码OXffff的真值是:符号位是1,表示负数,减一为OXfffe,取反为OX8001,表示的数值是-1/32768。
  6. 补码OX8000(省略小数点,后面同理)的真值是:同16位定点整数,对应的原码是OX8000,其中最高位表示数据位,而不是符号位了,当然符号位也是1,真值是-1。
  7. 补码OXffb7的真值是:-73/32768。同理。不再解释。
  8. -0.8125的补码是:原码是1.1101,反码是1.0010,补码是1.0011。十六进制表示为OX9800。
  9. 8位补码OXa3的16位补码是:对于任意小数,其多少位的补码对应数值都是相同的,即往后面加0,补成要求的格式即可。例如1.1011101为原码,则反码是1.0100010,补码是1.0100011,要求格式数位扩大,只需要在补码的小数位后面加几个0即可。
  10. 8位补码OX7a的16位补码是:OX7a00,解释同上。
  11. 8为无符号数OXaf的十六位形式是:OXaf00。无符号小数不适用于原码反码补码,所以转化为进制指的是转化为无符号的进制。小数位前面的1表示数值位。

采用8位定点小数方案表示-0.33时

  1. -0.33的二进制形式表示为: -0.0101010001111010...(无需多言)
  2. 其二进制形式保留八位小数的近似值是-0.01010100。(-0.328125)
  3. 近似值的绝对误差是:0.001875。
  4. 此近似值的补码是:OXd6。原码是:1.01010100,反码是:1.10101011,补码是:1.10101100。即为OXd6。

下面的迷迷糊糊没事,熟悉就行。不必了解原理。

采用8位补码解答下列定点整数问题,并说明结果是否溢出:

1,(-71)+(-29)        2,111+30        3,(-80)-(-55)

对于第一个,-71的补码是Oxb9,-29的补码是Oxe3,所以补码之和是Ox9c,没有溢出。

对于第二个,111的补码是Ox6f,30的补码是Ox1e,运算结果是Ox8d,更改了符号位,显然是有溢出的。第三个,同第一题,无溢出。解决此题可以看结果范围,如果不在-127到127之间,可认为是溢出的。

采用16位浮点数,其中含有6位指数表示数值数据时。

显然,在机器格式中,1位符号位,6位指数,9位尾数位。所以偏移量是2的5次方-1=31。(以上是个人理解)

通俗来说指数位前面的和后面的都是尾数位,所以尾数位有10位。

6位补码范围是-32到31,(上节已经提到,100000表示最小数-32),指数偏移量是31。也可以 这样理解,6位无符号数的范围是0到63,0和63有特殊用途,剩下的范围是1到62,62的一半是31,所以指数偏移量是31。

规格化指数的范围是-30到31,这样理解,无符号数0和63都有特殊用途,所以规格化指数的范围是0-31到63-31即-30到31,非规格化指数是-30,(这一块儿好奇怪)。将非规格化数转化为小数*2的-30次方。

不说了,直接看题:

规格化数的尾数范围:小数点前是1,小数点后全0到全1呗。

规格化数的指数范围:-30到31。无符号数的范围是0到63,其中0和63不表示规格化数,所以无符号数范围是1到62表示规格化数,对应的有符号数是-30到31。对应的机器数是1到62。机器数就是指数范围的无符号形式。也就是对应机器格式的无符号形式。

规格化数的指数偏移量:明显是62/2=31,也可以用2的5次方-1。

非规格化尾数的范围:小数点前是0,小数点后全0到全1呗。

非规格化数的指数范围:-30,上面已经提到过,对应的机器数是0。记住,所有非规格化数的指数范围就是规格化数指数范围的最小值,机器数是0。也就是对应机器格式的指数位的无符号值。即对应机器格式的指数位都是0。

最大的规格化正数尾数位都是1,指数位是2的31次方。

最小的规格化正数,尾数位是1后面全是0,指数位是2的-30次方。

最大的非规格化负数:符号是‘-’,尾数位是除了最后一位是1外全0,指数位固定2的-30次方。

最小的非规格化负数:符号是‘-’,尾数位小数点后全部是1,指数位是2的-30次方。

尾数的精度:小数点后有9位,所以精度是2的-9次方。

-75的机器数:

如果采用截断机制,0.34的机器数:

-1.101(2)*2的-33次方超过规格化数范围,采用非规格化形式表示:

机器数0x80a3的真值是:

 

采用带5位指数位的12位浮点数,如果在尾数求和时采用3位整数,9位小数,则在计算15.75+3.15625时:

含有五位指数时:偏移量是2的4次方-1=15,五位指数真值的范围是0到31,其中0和31有特殊用途,所以指数范围是1到30,表示成有符号数为-14到15,所以规格化数的指数位是-14到15,非规格化的指数位是-14。

运算之前,15.75的规格化真值是:

运算之前,3.15625的规格化真值是:

运算中,对阶后,3.15625的真值是:对阶过程就是指数小的向指数大的看齐。

对阶后,和的真值是:

和的规格化表示是:

运算中,尾数四舍五入后,和的规格化真值是:

运算后和的机器数形式是:0100 1100 1100 =0x4cc。

到指令这一块儿了:

假设计算机中指令长度是32位,格式是:操作码+目的寄存器+源寄存器+立即数

如果有200条不同的指令,有32个寄存器,那么立即数最多有:

200条不同的指令说明操作码至少有8位(2的7次方=128,即如果只有7位,最多只能对应128条指令)。为了区分32个不同的寄存器,目的寄存器和源寄存器至少各为5位,剩下的可供立即数使用的最多有32-10-8=14位。

关于RISV-V指令格式:有以下说法:rs1和rs2总是作为源寄存器。有些指令没有funct字段,有些指令没有rd字段,rs1和rs2总是用来读的。

关于add x2,x1,x1,有以下说法:add指令是R类型指令,所有操作数都采用寄存器寻址。

addi指令是I类型指令,其imm字段长度是12位,imm字段的范围是:imm字段为12位长,采用补码,对应真值的范围是-(2的11次方)到2的11次方-1,即-2048~2047。

指令addi x0,x1,-50的imm字段是:-50的12位补码是0xfce。

指令lw采用I类型格式,其offset字段的范围是:同上,offset也是立即数(imm),字段是12位长,所以范围也是-2048~2047。

指令lw x1,-12(x2)的offset字段是:-12的12位补码。即0xff4。

设x2的内容是0x0000 0000 1001 0010,则指令lw x1 -12(x2)读内存数据使用的地址是:指令lw的源操作数为内存变量,采用基址寻址,目标地址=基址+offset(-12),所以目标地址是该内容(基址)-12。

利用指令lw读取内存中起始地址为0x0000 0000 1002 0004的一个字(连续4个字节)时,如果基址是0x0000 0000 1001 ff00,其offset字段是:显然,用目标地址(起始地址)-基址即可得到。结果是:0x104。

利用指令lw读取内存中起始地址为0x0000 0000 1002 0004的一个字(连续四个字节)时,如果基址是0x0000 0000 1002 07f4,则其offset是:offset=目标地址-基址=起始地址-基址,显然题中,基址>起始地址,offset也可以表示为:-(基址-起始地址)。

指令beq采用SB类型格式,其offset字段的范围是:很显然,SB类型的imm也是12位,采用补码,所以范围是-2048~2047。

指令beq能实现的转移范围(前后指令数):每条指令占4个字节(1个字),offset字段是以2个字节(半个字)为单位的,往前能转移到第1023(int(2047/2))条指令,往后(往回)能转移到第1024(int(2048/2))条指令。

设指令beq x1,x1,abc的地址是0x0000 0000 0040 0100,指令abc:addi x2,x2,-4的地址是0x0000 0000 0040 0200,则分支指令的offset字段为:offset=(目标地址-分支指令地址)/2=128。

设指令beq x1,x1,abc的地址是0x0000 0000 0040 0200,指令abc:addi x2,x2,-4的地址是0x0000 0000 0040 0100,则分支指令的offset字段是:-128,从向前到向后而已。

显然,目标地址是0x0000 0000 1000 0000+offset*2,offset是以半字为单位的,也就是2个字节,地址是以字节为单位的,所以,要将offset*2,表示字节偏移量。

同理,offset是以半字(2字节)为单位的偏移量,而地址是以字节为单位的偏移量,所以要将当前地址+offset*2计算出目标地址。

显然,偏移量为正,而指令的大小1个字,offset是以半字为偏移量,所以,offset/2是以字为偏移量的,往前进100条,也就是往前100个字,200个半字,所以,offset字段是200。或者说,每四个字节对应一条指令,offset是以半字(2个字节)为单位的偏移量,往前进100条指令,也就是400个字节,对应offset为200。

同上,只不过这个是往后走。

jal是UJ类型指令,imm有20位,采用补码,对应的真值是的offset字段的范围是-(2的19次方)到2的19次方-1。

同理,offset是以半字(2个字节)为单位的偏移量,所以目标地址=当前地址+offset*2。(地址是以字节为单位)。

很显然,offset=(目标地址-当前地址)/2。目标地址-当前地址=字节偏移量,而offset是以半字偏移量为单位的,所以要再除以2。

显然,x1的内容+2*offset即x1的内容-240即可。(秀逗麻袋,jalr的偏移量是以半字为单位还是以字节为单位啊?)

jump and link,x1的地址是当前地址+4。

同理,区分6种寻址方式,需要3个比特编码,2个比特只能区分4种,3个比特能区分8种。

显然,30种不同的类型,对应肯定是5个比特位,而寻址方式是5*6*6=180种,对应8位,一共有13位,这道题容易出错,主要是因为,我们要用到的是寻址方式对应的比特位,而不是源寄存器对应的比特位。

厚礼蟹:

只有分支指令和jal指令是半字偏移量,其余与立即数有关的指令,比如ld,sd,jalr都是字节偏移量。

下一篇:

注意ld x5,67(x6),ld指令加载双字,也就是8个字节,图中每个字节对应一个单元内容,采用小端模式,8个字节单元加载出来的内容分别是:(0x省略)34,56,78,9a,bc,de,f0,12。先往最小的位置存,在往高的位置存:存之后x5的内容是:0x12f0debc9a785634。注意采用小端模式,最先加载出来的存到未存数据的最低位。

上图是小插曲。

lw x5,67(x6)加载单字,四个字节,即34,56,78,9a。小端模式是9a785634。要进行有符号扩展。加载后x5的内容是0xffff ffff 9a78 56 34。任然采用小端模式,加载出来的数据首先存储到x5的低位。逐渐往高位存。

读出的32位内容是无符号数,要扩展为64位。记住,lwu读出的数据要进行扩展。

注意:有符号拓展前面全补符号位,很明显9a...最高位是1,表示负数,所以扩展为全补1,无符号扩展前面全补0。x5里面的内容是8个字节,采用小端模式,前高位四个字节要进行扩展。

插入:

lh指令,加载一个半字,一个半字是2个字节,加载出34和56,采用小端模式,所以加载出来0x5634,是有符号数,符号位是0,所以扩展前面补0,结果是0x00...005634。

lhw同理,加载出来是无符号数,前面全补0,结果也是0x00..005634。

lb指令是加载字节,只加载一个字节,就是34,有符号数扩展,符号位是0,前面全补0,lbw是无符号数,无符号数扩展,前面全补0。

lui指令,将其中的立即数加载到寄存器的高20位,在将该寄存器扩展成64位,显然将0x12345加载到x5的高20位,是0x12345000,(低12位全补0),而后将其扩展为64位,符号位是0,所以前面全补0。

在jal指令中,x5的值被赋为下一条指令的地址,也就是PC+4。jalr同理。(需要注意的是,只有分支指令和jal指令是半字偏移量(offset*2才是相应的字节偏移量),剩余其他的比如ld,sd,jalr等都是字节偏移量)。

sd存双字,即8个字节,将图示区域(刚好8个字节单元)存满。小端存储,从低位开始存。

sw存单字,即4个字节,将图示区域从左往右数前四个(低四个)字节单元存满,高位不变。

sh存半字,即2个字节,将图示区域从左往右数前两个(低两个)字节单元存满,高位不变。

sb存字节,即1个字节,将图示区域从左往右数第一个(最低位)字节单元存满,高位不变。

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丘小羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值