wann welches Register????
-
Hi.
wasiliy schrieb:
@code-hacker: du hast die götter erzürnt!!! =p
Jo, wahrlich.
:p
Code-Hacker schrieb:
Jedes Register hat seine Vorteile und kann Operationen schneller ausführen als ein anderes, deswegen sollte man, wenn man Wert auf Geschwindigkeit legt, sich an die dafür vorgesehenen Register halten.
Seitdem es die 32Bit-Register gibt, ist es bis auf wenige Ausnahmen eigentlich ziemlich egal wofuer man welches Register Benutzt.
(Ausnahmen sind bp/sp, die Segmentregister und einige Opcodes, die Werte in bestimmten Registern erwarten - zB. movsb/div/cpuid o.ae.)
Code-Hacker schrieb:
Wenn der oberen 16 bit keinen Namen haben, wie kann ich dann auf die zugreifen?
Nur ueber Umwege...
Entweder indem du den ganzen 32Bit-Register auf einmal mit einem Wert belegst oder ueber das dazugehoerige untere 16Bit-Register.
zB.:;obere 16bit befuellen (untere 16Bit werden geloescht) mov ax,[1234h] shl eax,16 ;und: obere 16bit lesen (untere 16Bit werden geloescht) shr eax,16 mov [1234h],ax
Und zu guter Letzt:
@Bashar: Auch wenn es weh tun mag, halt dich doch bitte etwas zurueck.
Ein freundlicher Hinweis haette hier auch genuegt.und nochmal @Code-Hacker:
Normalerweise ist es hier ueblich, Vermutungen auch als solche zu kennzeichnen.
zB. durch Vorsetzen des Kuerzels IMHO oder des gleichbedeutenden Teilsatzes "Ich glaube, dass..."
Ansonsten koennte das fuer Verwirrung sorgen.
-
Nobuo T schrieb:
Seitdem es die 32Bit-Register gibt, ist es bis auf wenige Ausnahmen eigentlich ziemlich egal wofuer man welches Register Benutzt.
(Ausnahmen sind bp/sp, die Segmentregister und einige Opcodes, die Werte in bestimmten Registern erwarten - zB. movsb/div/cpuid o.ae.)
Achso. Ich kenne nur das Arbeiten mit den 16bit-Registern.
Nobuo T schrieb:
Nur ueber Umwege...
Entweder indem du den ganzen 32Bit-Register auf einmal mit einem Wert belegst oder ueber das dazugehoerige untere 16Bit-Register.
zB.:;obere 16bit befuellen (untere 16Bit werden geloescht) mov ax,[1234h] shl eax,16 ;und: obere 16bit lesen (untere 16Bit werden geloescht) shr eax,16 mov [1234h],ax
Hmm. Irgendwie umständlich und IHMO schade um den Inhalt des 16bit-Registers. Naja, kommt halt immer darauf an wofür man es braucht. Ich denke für mich kommt es erst in Frage wenn ich für 32bit-Werte kein 2. Register zur Verfügung habe weil das schon belegt ist.
Nobuo T schrieb:
und nochmal @Code-Hacker:
Normalerweise ist es hier ueblich, Vermutungen auch als solche zu kennzeichnen.
zB. durch Vorsetzen des Kuerzels IMHO oder des gleichbedeutenden Teilsatzes "Ich glaube, dass..."
Ansonsten koennte das fuer Verwirrung sorgen.Nagut ok, das "...habe es bisher nur bei NASM gesehen" (woher ich diese auch als einziges kenne) war wirklich nicht so das wahre
Code-Hacker
-
Wenn du im Realmode arbeitest, dann gehen für indirekte Adressierungen nur bestimmte Register. Generell gilt dort:
[base register + index register * scale + displacement]
Dabei ist:
base register = BP (base pointer) oder BX (base register)
index register = SI (source index) oder DI (destination index)
scale = 1, 2 oder 4 (da bin ich mir gerade nicht ganz sicher, habe ich
auch im real mode noch nie benutzt)
displacement = eine 16 bit große zahlIm Prinzip sind alle Sachen optional.
Beispiele:
mov ax,[bp] mov ax,[bp+si] mov ax,[bx+di+1000] mov ax,[si*2] ; bin mir da nicht sicher wegen dem "scale" wert
Im Protected Mode ist das lockerer. Da kannst du jedes Register
benutzen, das Displacement ist 32 bit breit und scale kann meines
Wissens neben oben genannten Werten auch 8 sein.Wie schon gesagt benötigen bestimmte Instruktionen bestimmte Register.
Wie z.b. LOOP, REP, REPNZ, MOVSB, STOSB, DIV, MUL, LAHF, RDTSC ...
Das es für EAX optimierte Instruktionen gibt, habe ich auch gehört.
Ich kann hier nur mit Sicherheit sagen, dass die Opcodes für die
EAX Varianten teilweise anders sind.
-
Sry, aber was 16Bit-Addressierung u. Unterschiede Addresskodierung RM/PM betrifft stimmt an dem vorherigen Beitrag leider einiges nicht:
malfunction schrieb:
Wenn du im Realmode arbeitest,...
Das ist keine Frage von RealMode/ProtectedMode - hier kommt es auf den Unterschied zwischen 16/32Bit-Addressierung an.
Beides kann sowohl im Realmode, wie auch im Protected benutzt werden, man muss nur aufpassen, dass die Segmentgrenzen nicht ueberschritten werden.malfunction schrieb:
Generell gilt dort:
[base register + index register * scale + displacement]
Ist aber sehr stark vereinfacht und dazu auch noch nicht ganz richtig:
Man mag es kaum glauben, aber der 16Bit Addressmodus unterstuetzt keine Scales.
Alles, was da geht, sind bestimmte Kombinationen von bx, si, di, bp + 8/16Bit-Werte.
Bei weitergehendem Interesse, spuckt dir Google mit ziemlicher Sicherheit eine brauchbare Tabelle mit allen Moeglichkeiten zur 16Bit-Addressbildung aus. Einfach nach 16Bit ModR/M suchen...Mit 32Bit-Addressierung kann man eigentlich fast alles machen. Da gibt es nun auch die Scales (*2/*4/*8) usw.
Das laesst sich mit der lea-Instruktion an bestimmten Stellen sogar sehr gut zur Berechnung halbwegs komplizierter Gleichungen verwenden.
Bsp:mov bx,[word ptr ss:bp+04h] ;Kartenkoordinaten... ;bx in offset umwandeln... movzx edi,bh ;YPos*3 movzx edx,bl ;+XPos lea eax,[edi+2*edi] add eax,edx ;*5... lea edi,[eax+4*eax+offset GamePlane] ;edi=(3*YPos+XPos)*5+offset GamePlane
BTW, ist zwar ein wenig OT, aber wo ich hier gerade mein eigenes Stueck code betrachte:
was wird hier wohl schneller sein: die verteilung dieser 2 Byte-werte wie hier gezeigt mit einem Read cycle oder dann doch besser 2 read cycles und nicht den Umweg ueber bx?
Dabei muss ja auch die Auslastung der Addressiereinheit bedacht werden.
(Es handelt sich dabei uebrigens um eine Prozedur, wobei das der erste Anweisungsblock ist...)
-
@Nobuo_t: Danke für die Berichtigungen. Aber bei dem Scale habe ich gleich gesagt, dass ich mir da nicht sicher bin. Ich habe halt schon sehr lange nichts mehr im Realmode programmiert.
-
Ich hab mal ne Frage bezüglich DI (Bestimmungsortindex?!) und SI (Quellindex?!) wann kannich welches benutzen muss ich beide bwnutzen oder wann darf ich nur das eine oder das andere benutzen?
Und die bezeichnungen versteh ich auch nicht so wirklich.. (mit google übersetzt)
-
eigentlich kannst du DI und SI immer zum adressieren benutzen:
mov ax,[si]
mov bx,[di]
und sowas in der art....
oder auch für die restlichen befehle add, sub ...es gibt aber noch die stringbefehle, wo die art auf die DI und SI genutzt werden festgelegt ist:
STOSB zB ist dasselbe wie: mov ds:[di],al; inc DI
und MOVSB kopiert ein byte von ds:[si] nach ds:[di] und incrementiert wieder DI und SI um eins.wobei SI der "source index" (Quellindex) ist
und DI der "destination index" (Zielindex).
denn bei solchen befehlen wird SI immer als index für die Quelle benutzt, also da wo das byte ausgelesen wird und DI wird immer als index für das Ziel benutzt, also da wo das byte dann hingeht.wenn du also zB ein array in das andere kopieren willst:
Quellarray db 10 dup (1)
Zielarray db 10 dup (?); vorausgesetzt DS zeigt auf das datensegment und die arrays sind im datensegment:
mov cx,10
mov si, offset Quellarray
mov di, offset Zielarray
rep movsb; oder du willst ein array mit einer zahl überschreiben:
mov al,5
mov di,offset Zielarray
mov cx,10
rep stosb
-
ach ja bevor buh- rufe kommen: du musst auf das direction flag achten
naja meistens hat es den richtigen wert, also beachte diesen post garnicht .
-
wasiliy schrieb:
STOSB zB ist dasselbe wie: mov ds:[di],al; inc DI
und MOVSB kopiert ein byte von ds:[si] nach ds:[di] und incrementiert wieder DI und SI um eins.*Buh* :D:p
Bei Stringoperationen wird di immer zusammen mit es zum Addressieren verwendet. => es:[di]
-
wollte euch nur testen =p
oder noch bessere ausrede: der junge mann sollte selber in einem buch nachschlagen