frage an assembler-coder...

dettus

Bicycle User
guten tag.

folgendes: ich bastel hier im urlaub gerade eine kleine risc-cpu.
und der wollte ich jetzt vier adressierungsmodi verpassen:
Code:
indirekt              LDA [R2]         R3
indirekt indiziert 1  LDA [R2+R4]      R3
indirekt indiziert 2  LDA [R2+=R4]     R3
indirekt indiziert 3  LDA [R2; R2+=R4] R3
wobei ich jetzt keine ahnung habe wie ich ii1, ii2, ii3 anders benamsen soll. ausserdem faellt mir nicht ein, wie man das im quellcode deutlicher machen kann.

ich habe vor, dass bei ii1 einfach nur die summe zwischen [R2] und [R4] gebildet wird. und das ist die adresse.
bei ii2 soll ebenfalls die summe gebildet werden, aber zusaetzlich noch der neue wert von R2+R4 in R2 stehen.
also eigentlich waere das ein zweizeiler:

Code:
ADD R2 R2 R4  ; R2=R2+R4
LDA [R2] R3  ; load R3 from the address stored in [R2]

iis3 ist genauso, nur andersrum:

Code:
LDA [R2] R3  ; load R3 from the address stored in [R2]
ADD R2 R2 R4  ; R2=R2+R4

meine frage ist jetzt: faellt euch ein besserer name ein als ii1, ii2, ii3? und vor allen dingen: faellt euch eine bessere nomenklatur ein?
 
Deine ii2 und ii3 sind, glaube ich, nicht so ganz beliebt, weil sie Seiteneffekte haben können, wenn Interrupts ausgelöst werden und die Atomizität garantiert werden muss. Sieh Dir mal die Auto-Increment-Problematik mal an. Schau dazu hier über Adressierungsmodi.

Vorsicht auch mit LDA als Mnemonic. Das heißt für die meisten Leute "Load Accumulator". Ich glaube, dass LD üblicher ist.

Noch ein Hinweis... das "Auto-Add" macht nur Sinn, wenn Du die Busbreite respektierst, sonst hast Du massig Penalties bei der Adressierung. Vielleicht würde ich ii2 so etwas wie pre-Auto-Add und das ii3 so etwas wie post-Auto-Add nennen. Übrigens erzeugst Du bei superskalaren Architekturen auch noch viele Bubbles, weil die parallele Instruktionen nicht anfangen können bevor das Adaptieren des Summenregisters abgeschlossen wurde. Das ist nicht so schön.

Aber wie gesagt, überleg's Dir nochmal. Guck Dir auch mal das Papier bei Wikipedia an "How many addressing modes are enough". Da haben sich die Leute etwas Gedanken dazu gemacht.
 
Ein paar Punkte, die mir so auffallen:
- Summe aus mehr als zwei Registern ist bei RISC-Maschinen sehr unüblich. Insbesondere, weil man mehrfach durch die ALU muss in einem Befehl, was /sehr/ un-RISC-ig ist.
- Wenn es ein (Prä-)Inkrement gibt, dann üblicherweise nur um die Breite des geladenen Wortes.
- Üblicherweise verpasst man RISC-Maschinen ein Nullregister. Dann fallen die ersten beiden und die letzten beiden Fälle jeweils zusammen, denn man benutzt als eines der Adressierungsregister einfach das Nullregister.

Dann bliebe einfach a) Laden (mit Summe aus zwei Registern) und b) Laden mit Präinkrement.

Noch etwas: Es ist unüblich keine Laden von Register + konstanter Versatz zu haben. Ich schlage vor, du schaust mal, was die üblichen Verdächtigen, sprich SPARC, MIPS, ARM und POWER, so anbieten und orientierst dich etwas daran.
 
Das hieß es doch immer und ist vielleicht auch das, was dettus will?

Akkumulator? Mag sein, dass sich das jetzt irgendwie geändert hat, aber Akku brauchte man damals eher für Einadressmaschinen. Das war ein besonderes Register mit dem man mehr machen konnte als mit den anderen (insbesondere war der Akku mit voller ALU-Funktionalität ausgestattet). Ich dachte, dass dettus typische RISC-Register benutzt mit Rx, die bis auf wenige Ausnahmen gleichberechtigt sind.

6502 hatte LDA, LDX und LDY. Schon bei Z80, welcher auch nur einfache Adressierungen benutzt hat, hat LD als Mnemonic benutzt.
 
einigen wir uns darauf dass ich den befehl LDW (load WORD) nenne.
ich hab naemlich noch ein LDB (load byte), welches nur 8 bit aus dem speicher liest.

und was die alu angeht: die langweilt sich bei einem ld/st befehl eigentlich.
deswegen hab ich ja mit den adressierungsmodi rumgespielt.


und die cpu ist eigentlich auch schon fertig, und laesst sich auf einem stratix ii mit 50mhz takten. (freu)


aber wie gesagt: jetzt sitz ich an der doku, und weiss nicht wie ich die modi nennen soll. oder im quellcode deutlich machen.

ich hab schon an sowas gedacht:
Code:
R2+=R4
R2=+R4

um zu unterscheiden dass die addition VOR oder NACH dem speicherzugriff kommt.
aber das ist doch auch doof.
 
einigen wir uns darauf dass ich den befehl LDW (load WORD) nenne.
ich hab naemlich noch ein LDB (load byte), welches nur 8 bit aus dem speicher liest.

Ja natürlich. LD ist ja nur sinnvoll, wenn man die Breite direkt erkennen kann.

und was die alu angeht: die langweilt sich bei einem ld/st befehl eigentlich.
deswegen hab ich ja mit den adressierungsmodi rumgespielt.

Naja. Wahrscheinlich kriegt man das sogar auch effizient fürs Pipelining hin. Nur RISC ist deswegen gut, weil die Befehle sich gut parallel ausführen lassen. Und das liegt in der RISC-Natur, weil die Befehle sehr einfach gestrickt sind.

Überleg mal folgendes, wenn ALU während LD/ST sowieso nichts zu tun hat, dann bedeutet das eher, dass nachfolgende Befehle ohne Bubbles laufen und deswegen höchst effizient arbeiten. So kann vielleicht sogar eine Sequenz von ADD, LD oder umgekehrt schneller laufen (aber mindestens gleich schnell) wie Dein zusammengesetzter Befehl.

um zu unterscheiden dass die addition VOR oder NACH dem speicherzugriff kommt.
aber das ist doch auch doof.

Ne, so doof ist das nicht, das gibt es ja bei C auch mit Prä/Postfix Inkrementoperator:
Code:
++i;
i++;

Deswegen hatte ich die pre/post-Namen im Kopf.
 
oh, so wie ich die gebaut habe langweilt die sich ;)

hmm... "pre-increased, pre-decreased, post-increased, post-decreased indexed addressing" klingt schonmal gut.

okay, was haelst du von dieser notation?

Code:
LDW [++(R4)R2] R3
LDW [R2++(R4)] R3
LDW [R2+R4]    R3

kann man das gut unterscheiden?
 
Zuletzt bearbeitet:
Zurück
Oben