gpt4 book ai didi

assembly - MIPS中基于指针的阵列访问

转载 作者:行者123 更新时间:2023-12-04 04:17:30 24 4
gpt4 key购买 nike

在MIPS中,基于指针的数组访问是什么意思?

最佳答案

“基于指针的数组访问”还有其他可能的含义或含义:

您可能有一个指向数组的指针,而不是指向固定地址的数组。实际上,在C / C ++中,“指向数组的指针”通常通常只是指向数组第一个元素的指针。基本上,您有一个数组,该数组是函数的参数,或者是一个指向结构或类的成员的数组的指针:

 void Foo(char a[]); 
/*or*/ void Foo(char *a);
struct Bar { int offset4bytes; char* a; };


通常,当您要使用这样的数组时,该数组的基地址将被加载到寄存器中。

现在说您要访问这样一个数组的元素i,

 char tmp = a[i];


假设r1包含数组地址。 (实际上,可能是调用约定为函数参数指定了一个不同的寄存器。无论编译器发现什么可用于其他代码。)

假设我住在寄存器r2中。

并且,从好的方面来说,让tmp为r3。

在某些指令集上,例如Intel x86,有一个寻址模式,看起来像

  MOV r3, (r2,r1)4


即寻址模式可以添加两个寄存器和一个偏移量(我在结构示例中任意添加了一个字段,以便可以显示出来)。

哎呀,它们甚至可以缩放其中一个寄存器,即所谓的索引寄存器:

  MOV r3, (r2*2,r1)4


还是我更喜欢写

  r3 := load( Memory[r2<<1+r1+4]


但是,MIPS没有这种base + _index * scale + offset寻址模式。大多数MIPS存储器访问指令仅限于寄存器+偏移量。因此,对于MIPS,您可能需要做

  ADDU r10, r1,r1    ; dest on left. r10 = 2*r1
ADDU r11, r2,r10
LB r3,(r11)4


也就是说,您可能必须添加额外的RISC指令,才能以复杂的寻址模式在一个CISC指令中完成x86的功能。但是,这种寻址方式并不常见,因此通常可以避免使用。



此外,即使只是在固定地址处寻址阵列,也可能需要MIPS中的其他指令。 x86指令可以具有32位内存偏移量-在这种情况下,它实际上可能是数组的绝对地址。 MIPS指令的偏移量限制为16位-MIPS指令的宽度为固定宽度,为32位。因此,甚至可能需要单独的指令来访问固定地址处的数组,通常将地址的高位加载到寄存器中。

以及更多-MIPS具有更新的指令,例如LUXC1,具有reg + reg寻址模式。但没有缩放索引,也没有第三个偏移量分量。



由于这种受限的寻址方式,天真的编译器为诸如

   for(int i=0;i<N;i++) {
this->a[i] = 0;
}


如果循环包含上面提到的多条指令序列,将是低效的。

像这样的循环

   for(char *p=this->a;p<&(this->a[N]);p++) {
*p=0;
}


或者,等效地

   for(char *p=this->a;p<this->a+N;p++) {
*p;
}


甚至有时

   for(i=-N,*p=this->a;i<0;i++,p++) {
*p=0;
}


可能会更有效率,因为在前两个中,只有一条指令可以进行存储。 (最后一个通常只有遍历多个数组才能获胜。

现在,在一个简单的示例中,任何优秀的编译器都将为您进行此优化。但是有时编译器更喜欢这种基于指针的访问。

关于assembly - MIPS中基于指针的阵列访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3554698/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com