朝花夕拾-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 = 0
loop1:sll $t1,$t0,2 # $t1 = i * 4
add $t2,$a0,$t1 # $t2 = address of array[i]
sw $zero, 0($t2) # array[i] = 0
addi $t0,$t0,1 # i = i + 1
slt $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] = 0
addi $t0,$t0,4 # p = p + 4
add $t1,$a1,$a1 # $t1 = size * 2
add $t1,$t1,$t1 # $t1 = size * 4
add $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 * 4
add $t2,$a0,$t1 # $t2 = address of array[size]
loop2:sw $zero,0($t0) # Memory[p] = 0
addi $t0,$t0,4 # p = p + 4
slt $t3,$t0,$t2 # $t3 = (p<&array[size])
bne $t3,$zero,loop2 # if (p<&array[size]) go to loop2

 

2.4 放在一起比较一下


  

2.5 比较结果

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

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

 

 

2.6 小结

以后尽量用指针吧。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值