IT铁人
不知道各位有没有试试看前面的题目呢??这边稍微讲解一下ㄅ
首先是a.
op=0 (代表R-type), funct=32 (也就是100000)
代表加法ADD指令rs=1, rt=2, rd=3
分别代表$at, $v0, $v1
所以代表将$at+$v0的结果放在$v1
Assembly的写法就会是
add $v1, $at, $v0
再来是b.
op=43 (101011)
代表sw指令rs=16, rt=5
分别代表$s0, $a1而immediate只是代表位移的数量而已
所以代表将$s0中存的位置加上4
结果所指到的位址中的资料放进$a1中
Assembly的写法为
sw $a1, 4($s0)
你答对了吗??
稍微有点困难啦,毕竟sw上次没有提到。
不过大学就是这样嘛,东西很多教授不可能全部讲一次。
所以我们继续努力吧!
前面我们在标记register的位置时,使用2进位制,也就是说最初的代表2的0次方,在往前为2的1次方,以此类推,所以当我们要将数字从10进位制转换成2进位制时,基本上用短除法就能够做出来,或是一直用小於当下数字且最大的2的次方减下去也可以,以109来举例的话…
109 - 64 = 45 (1xxxxxx)
45 - 32 = 13 (11xxxxx)
13 < 16 (110xxxx)
13 - 8 = 5 (1101xxx)
5 - 4 = 1 (11011xx)
1 < 2 (110110x)
1 - 1 = 0 (1101101)
当啷!是不是很简单阿~结果就是1101101喔!
那麽既然正数可以如此表示,那麽负数呢?
既然负数会有一个减号在前面,我们可以在2进位的最前面多增加一个代表正负数的bit。
这就叫做sign and magnitude
所以 109 = 01101101
如果-109 = 11101101
那麽问题来了,以8个bit来表示数字的话
0就有正负0两种可能
+0 = 00000000
-0 = 10000000
另外一种没什麽在用的方法称为1's Complement
就是直接取补数就好(1变0,0变1)
所以 109 = 01101101
那麽-109 = 10010010
这麽一来有些加减法可以正常运作,有些不行
不过0一样有正负0两种表示方法,所以
最後一个最实用的,升级版的前者:2's Complement
取完补数後将结果+1
这麽一来
0 = 00000000
-0 = 11111111 + 1 = 1 00000000
最前面的1会跑出我们在意的8 bit
所以结果仍然是00000000
并且负数换成正数也是同样的作法
有兴趣的同学可以试试看
采用了2's Complement,可以解决正负0的问题 不会撞号
定义好数字的正负如何表示之後,加减法的部份就简单多了。
加法只要将两者加起来;减法则要将後者变号,再使用加法即可。
举例来说
7 + 9 = 16 | |
---|---|
00000111 | |
+ | 00001001 |
= | 00010000 |
13 - 20 = -7 | ||
---|---|---|
00001101 | ||
+ | 11101100 | (00010100的负数) |
= | 11111001 | (00000111的负数) |
要特别注意的是,在7+9=16之中,发生了进位,要是进位的时候压到了最前面的bit,就会让人认为结果是负数,这种情况称为Overflow
写过程序的同学,应该听过这个词,中文称为溢位(腋味)。
![](https://i.imgur.com/REO8ZFr.jpg =30%x30%)
如果在c语言中执行以下程序码片段
int x = 1000000000;
int y = 2000000000;
printf("%d\n", x+y);
则会出现
-1294967296
这就是因为加法之後进位压到了sign bit,导致程序以为结果为负数。
所以做计算的时候要特别注意,基本上正数加上正数,以及负数加上负数都有可能发生溢位。
以int来说,最大的数字为 ${2}^{31}-1$,也就是说如果要一次加起两个数字,我们需要一个32 bit的加法器,不过太大了,并且如果又要支援更大的加法,又会需要更大的加法器来一次实施,所以我们不是这样想的,我们用的是多个加法器连接来计算。
也就是说,以一个32 bit的加法来看,我们用的是32个1 bit的加法器,一个一个的加上去,并且将进位往後传,就像是国小老师教的那样,那个我们单纯将一堆加法器连接在一起,就称为Ripple Carry Adder。
![](https://i.imgur.com/E40bA13.png =70%x70%)
不过这代表每次都要等前面一个adder做完运算才能轮到下一位。
为了加快速度,出现了新的加法加速器,这就是Carry Lookahead Adder(CLA)
透过逻辑运算,我们可以将前面是否会进位提早告诉後面的adder,这麽一来就能将结果加速,至於CLA的原理,碍於篇幅的关系,杰哥打算留到下一篇再跟各位介绍。
这篇轻轻松松,我们做两个简单的加减法就好了,题目如下:
a. | 28 + 90 |
---|---|
b. | 30 - 120 |
在纸上写出计算过程吧~~
上一篇 | 下一篇 |
---|---|
我也...可以跟电脑娘说话吗 | CLA以及bit乘法 |
>>: 【Day4】[资料结构]-链结串列Linked List-实作
SQL Server 资料库备份是将存放在资料库里面的资料,转成单一档案保存,通常是副档名为 bak...
我们现在有了基本的日志,但是每次输入完重整页面都会刷新,因为这些资料都只存在於浏览器,没有真正储存到...
测试左移(Shift Left Testing ) 如何事件左移 事先演练未来排定作业 因为团队会在...
开发这个 App 至今,已经帮我带来千万以上的收益,但是还是有很多我们常用的服务跟工具,居然到现在都...
Block说:我让Ruby发光发亮。 Ruby中少数天生不属於物件的存在。 未物件化前,只能依附在有...