首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > VSTS >

朝花夕拾-二-Arrays VS Pointers

2013-11-09 
朝花夕拾-2-Arrays VS Pointers引言这个标题是俗点,但是,别误会,不是老生常谈。都说数组和指针的区别啊,怎

朝花夕拾-2-Arrays VS Pointers

引言 

这个标题是俗点,但是,别误会,不是老生常谈。

都说数组和指针的区别啊,怎么定义指针啊,怎么定义数组啊,给你两个小程序让你说打印出来的是什么呀,等等之类的题目。本小节不打算说这些。整一个小例子,然后分别看一下数组和指针的汇编结果,自己体会一下。

数组VS指针(Arrays versus Pointers),开始......

 

2.1 C code

同样的功能,两段小代码:

clear1(int array[], int size)  {   int i;   for (i = 0; i < size; i += 1)   array[i] = 0;  }    clear2(int  *array, int size)  {   int*p;   for (p = &array[0]; p < &array[size]; p = p + 1)   *p = 0;  }

 


2.2 clear1的MIPS汇编

需要说明一下,不考虑过程调用的汇编,保存SP啊之类的动作,我们主要关注循环本身。

假设array,size两个参数用$a0,$a1,i用$t0,三个寄存器。

1》for循环第一部分,i初始化

move $t0,$zero # i = 0 (register $t0 = 0)
2》为了把array[i]清零,我们要先得到他的地址,即i*4

loop1:sll $t1,$t0,2 # $t1 = i * 4

3》然后加上数组的起始地址,这个起始地址放在寄存器中
add $t2,$a0,$t1 # $t2 = address of array[i]

4》然后将这个地址清零

sw $zero, 0($t2) # array[i] = 0
5》i自增

addi $t0,$t0,1 # i = i + 1

6》最后循环条件判断

slt $t3,$t0,$a1 # $t3 = (i < size)
bne $t3,$zero,loop1 # if (i < size) go to loop1

咱们把上面的代码拼起来就是:

 

move $t0,$zero # i = 0loop1:sll $t1,$t0,2 # $t1 = i * 4add $t2,$a0,$t1 # $t2 = address of array[i]sw $zero, 0($t2) # array[i] = 0addi $t0,$t0,1 # i = i + 1slt $t3,$t0,$a1 # $t3 = (i < size)bne $t3,$zero,loop1# if (i < size) go to loop1

 


2.3 clear2的MIPS汇编

参数和clear1一样,p用$t0

1》先给指针赋值为数组的第一个元素的地址

move $t0,$a0 # p = address of array[0]

2》for循环开始,将0放入p

loop2:sw $zero,0($t0) # Memory[p] = 0

3》p自增4

addi $t0,$t0,4 # p = p + 4

4》循环判断之计算array最末元素的地址

add $t1,$a1,$a1 # $t1 = size * 2
add $t1,$t1,$t1 # $t1 = size * 4

5》然后将结果加到数组的开始地址

add $t2,$a0,$t1 # $t2 = address of array[size]

6》循环判断之p是否小于array最后一个元素的地址

slt $t3,$t0,$t2 # $t3 = (p<&array[size])
bne $t3,$zero,loop2 # if (p<&array[size]) go to loop2 

再把上面的代码拼起来:

move $t0,$a0 # p = address of array[0]loop2:sw$zero,0($t0) # Memory[p] = 0addi $t0,$t0,4 # p = p + 4add $t1,$a1,$a1 # $t1 = size * 2add $t1,$t1,$t1 # $t1 = size * 4add $t2,$a0,$t1 # $t2 = address of array[size]slt $t3,$t0,$t2 # $t3 = (p<&array[size])bne $t3,$zero,loop2 # if (p<&array[size]) go to loop2

再优化一下,将每次计算数组末端地址移到循环外边 

move $t0,$a0 # p = address of array[0]sll $t1,$a1,2 # $t1 = size * 4add $t2,$a0,$t1 # $t2 = address of array[size]loop2:sw $zero,0($t0) # Memory[p] = 0addi $t0,$t0,4 # p = p + 4slt $t3,$t0,$t2 # $t3 = (p<&array[size])bne $t3,$zero,loop2 # if (p<&array[size]) go to loop2

 

2.4 放在一起比较一下


朝花夕拾-二-Arrays VS Pointers

  

2.5 比较结果

1》左边的版本循环中必须有乘法运算,右面的版本指针直接加4。

2》数组方式循环体是7条指令,指针方式循环体是4条。

 

 

2.6 小结

以后尽量用指针吧。

热点排行