Frage

Was meinen wir durch den Zeiger basierten Array Zugriff in MIPS?

War es hilfreich?

Lösung

Es gibt eine zusätzliche mögliche Bedeutung oder Auswirkung auf „Zeiger basierten Array Zugriff“:

Sie können einen Zeiger auf ein Array, anstatt ein Array mit einer festen Adresse. Eigentlich in C / C ++, eine „Zeiger auf ein Feld“ ist eigentlich in der Regel nur ein Zeiger auf das erste Element des Arrays. Im Wesentlichen hat man eine Anordnung, die ein Parameter für eine Funktion ist, oder ein Zeiger auf ein Feld, das ein Mitglied einer Struktur oder Klasse ist:

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

Normalerweise, wenn Sie ein solches Array verwenden möchten, die Basisadresse des Arrays werden in ein Register geladen werden.

Jetzt sagen Sie zugreifen Element möchte ich eines solchen Arrays,

 char tmp = a[i];

Lassen Sie uns sagen, dass r 1 enthält die Array-Adresse. (Eigentlich wahrscheinlich ein anderes Register, durch die Aufrufkonvention festgelegt, für die Funktion Paramater. Was auch immer die Compiler für anderen Code findet.)

Lassen Sie uns sagen, dass ich im Register r2 lebt.

Und für eine gute Maßnahme, lassen r3 tmp sein.

Bei einigen Befehlssätzen, zum Beispiel Intel x86, gibt es eine Adressierungsart das aussieht wie

  MOV r3, (r2,r1)4

d. die Adressierungsart zwei Register hinzufügen und ein Offset (I willkürlich ein Feld auf die Struktur Beispiel hinzugefügt, so dass ich dies zeigen konnte).

Heck, sie können sogar eines des Registers skalieren, die so genannte Index-Register:

  MOV r3, (r2*2,r1)4

oder, wie ich es vorziehen, es zu schreiben

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

MIPS jedoch nicht über diese Art von Basis + _index * scale + Modus versetzt Adressierung. Die meisten MIPS Speicherzugriffsbefehle sind begrenzt + Offset zu registrieren. Daher ist für MIPS, könnten Sie tun müssen,

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

d. Sie könnten zusätzliche RISC-Befehle hinzufügen müssen, um zu erreichen, was x86 in einem CISC-Befehl funktioniert mit einem komplizierten Adressierungsmodus. Allerdings ist eine solche Adressierung ist nicht üblich, und canm oft vermieden werden.


Ferner kann auch nur an einer festen Adresse ein Array Adressierung kann zusätzliche Anweisungen in MIPS erfordern. x86-Befehle können ein 32-Bit-Speicher-Offset haben, - die in diesem Fall tatsächlich eine absolute Adresse eines Arrays sein. MIPS Anweisungen sind auf eine 16-Bit-Offset - MIPS Befehle mit fester Breite, 32 Bits breit. Daher ist eine separate Anweisung erforderlich sein kann, auch eine Anordnung an einer festen Adresse zuzugreifen, die typischerweise die oberen Bits der Adresse in ein Register zu laden.

Und mehr - MIPS hat neue Befehle wie LUXC1, die haben reg + reg Adressierungsart. Aber nicht skalierten Index und keine dritte Offset-Komponente.


Aufgrund dieser eingeschränkten Adressierungsmodi, dass der Code ein naiver Compiler generiert für eine lop wie

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

wäre ineffizient sein, wenn die Schleife die mehrere Befehlssequenz enthalten ist oben erwähnt.

Eine Schleife wie

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

oder äquivalent

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

oder sogar manchmal

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

könnte effizienter sein, weil beispiel in den ersten beiden gäbe es nur eine einzige Anweisung, den Speicher zu tun. (Die letzte ist in der Regel nur ein Sieg, wenn mehrere Arrays durchlaufen.

Nun, in einem einfachen Beispiel jeden guter Compiler wird für Dich diese Optimierung tun. Aber manchmal ist die Compiler bevorzugt solche Zeiger basierte Zugriffe.

Andere Tipps

In Kürze erhalten Sie haben einen Zeiger, der auf den Anfang des Arrays von Werten. Um die Anordnung zu durchqueren, werden Sie Zeigerarithmetik verwendet werden (in der Regel Addier / Subtrahier- 1, 2, oder 4), um den Zeiger auf den nächsten / vorherigen Element im Array zu fördern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top