前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【计算机本科补全计划】指令:计算机的语言(MIPS) Part4

【计算机本科补全计划】指令:计算机的语言(MIPS) Part4

作者头像
用户1687088
发布2018-05-07 17:02:34
7090
发布2018-05-07 17:02:34
举报
文章被收录于专栏:工科狗和生物喵

正文之前

这几天陪人玩去了,所以没怎么看书。今早某人回家了。所以我也就可以一个人继续开始在图书馆的浪荡之路了。爽歪歪!!!!而且可以一个人独占温暖的地方,实在是妙不可言。另外,特地感谢YYW同学,严重改良了我的睡眠质量,让我现在可以沾着枕头就睡着,这也是很欣慰的一件事情,YYW同学你安心的回家玩耍吧。我在这儿也还可以哦~~ 哈哈~~

正文

一、数组与指针

对于C语言的新手来说,理解指针的存在是比较困难的一件事情。那么,我们可以通过对比利用指针与直接用数组的下标码值来看看指针的便利之处在哪儿。

有如下C语言程序:

代码语言:javascript
复制
void clear1(int array[],int size )
{
    int i;
    for (i=0;i<size;i+=1)    
        array[i]=0;
}
代码语言:javascript
复制
void clear2( int *array,int size )
{
    int *p;
       for (p=&array[0];p<=&array[size];p=p+1)
        *p=0;
}

上述的程序中两者的作用都是一样的,把数组array内的所有数值清零,但是实现过程却是很不相同,一个是直接用的数组下标,另一个是用的数组首地址的指针。那么,我们从MIPS汇编程序上来看这两者之间的差异!

首先,用数组下标的代码如下:

代码语言:javascript
复制
//假设两个参数array 和 size 分别存储在 $a0 和 $a1中,i则保存在临时寄存器$t0中;
     move $t0;$zero;
Cle1://此处不算一行
     sll $t1,$t0,2;
     add $t2,$a0,$t1;
     sw $zero,0($t2);
     addi $t0,$t0,1;
     slt $t3,$t0,$a1;
     bne $t3,$zero,Cle1;

下面逐行解释代码的含义:

  • 首先对i取0;i是存放在寄存器$t0里面的;
  • 开始进入第一次循环(我们假定size肯定大于0,所以并不在此之前进行判断),取第i个元素的四倍(左移两位等同于乘以4)
  • 将i的四倍加上数组的首地址,就得到array[i]的地址;
  • 对array[i]存入0;
  • i=i+1;
  • 比较当前的i是否小于size,如果小于,那么$t3=1;
  • 如果$t3不等于0,那么就跳转到下一次循环

其实我个人觉得,是不是第六第七句太麻烦,直接用一个 bne $t0,$a1,Cle1 就行了吧~?


那么我们的第二个基于数组指针的汇编程序是怎么样的呢?

代码语言:javascript
复制
//假设两个参数array 和 size 分别存储在 $a0 和 $a1中,p则保存在临时寄存器$t0中;
     move $t0;$a0;
     sll $t1,$a1,4;
     add $t2,$a0,$t1;
Cle2://此处不算一行
     sw $zero,$t0;
     addi $t0,$t0,4;
     bne $t0,$t2,Cle2

下面逐行解释代码的含义:

  • 首先是要取出数组首地址的指针放到$t0,也就是指针p中;
  • 为了避免在每一次循环中都会对size所在的数组下标进行操作,干脆腾出一个寄存器直接记录size 的位置;
  • 求出size所对应的数组位置的地址;
  • 进入循环首先把数组第一个元素清零;
  • i=i+1;
  • 比较当前的地址是否小于size,如果小于,那么进入下一次循环,不然就继续执行下面的代码;

如果只循环一次,那么是差不多的性能,但是当这个数组进入一定的规模,那么我们就可以看出两者之间的巨大差距。

  1. 首先,Clear1的循环代码中,包括了简化乘法(左移),这是一个比较占用性能的操作
  2. 其次,Clear2的循环体经过优化之后只包含了三条语句,而Clear1则包涵六条语句,两倍的性能差距还是保守的说。

二、 ARMv8(x86)指令集中存在的一些谬误与陷阱

  • 谬误:更强大的指令意味着更强大的性能 然而并不是,很多强大的指令可以完成复杂的行为但是很显然的牺牲了一定的性能
  • 谬误:使用汇编语言来获得更高的性能 如今随着各种编译器的出现,编程语言的编译器产生大量低级指令序列的时代已经过去了。编译器与汇编语言程序员的斗争正在逐渐减少,软件工程中的几个真理之一:代码越多,需要的时间越多。那么毫无疑问的,汇编代码比之C语言等要多了很多,自然投入的时间也就多了。高级语言不仅仅可以现在使用,未来编译器升级之后还可以继续在不同性能的机器上使用,而很显然的,手工编写的汇编语言可移植性是很差的。
  • 陷阱: 忘记字节寻址的时候连续的“字”地址相差不是1,是4或者8

正文之后

今天虽然存在了淡淡的离愁,但是好歹是为了下次的见面做铺垫不是?所以整体上我还是开心的,因为好歹吃上了百景园一楼的毛细牛肉面了。爽歪歪~~ 突然有点想家了!估计是因为最近我爸妈得知我读直博了所以很开心,然后我爸爸开始放浪形骸(证据如下图)。不仅如此,一天给我不下八个视频电话,虽然我至今才接了两三个,但是面对我爸的毫无松懈的攻势,我还是有点吃不住啊。不过隐约家里有活力了不少了。大抵是压在他们身上的一份重担(我?我!)即将消亡吧!希望我博士期间可以好好地念书,然后最起码解决自己的经济问题,最好是往家里打钱。总结一句:想家了,不如晚饭加个餐,夜间吃个关东煮犒劳下自己吧(我会告诉你我是因为懒和不想挤车才没回去?)!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 工科狗和生物喵 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文之前
  • 正文
  • 正文之后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档