16 bit indizierte Adressierung
-
Ich arbeite zur Zeit ein Assembler Buch durch und frage mich, warum folgendes com-Programm nicht funktioniert.
.MODEL Tiny .CODE ORG 100h Start: mov al,128 mov cl,5 mov bl,5 Looptab: mov [Tabelle+bl],al shl al,1 Loop Looptab mov ah,4Ch int 21 Tabelle DB 5 DUP (?) END Start
Noch lieber wäre es mir, direkt cl zum indizieren zu nutzen. Geht das? Wenn nein, warum nicht?
-
Die genaue Fehlerbeschreibung wäre nett gewesen. So lauf ich jetzt Gefahr, falsch zu mutmaßen, aber ich nehme an, dein Problem ist, dass es nicht möglich ist, eine indirekte Adressierung über
Tabelle+bl
zu machen? Ganz einfache Antwort: Es geht halt nicht. Erlaubt nur bestimmte Kombinationen, und die gehórt nicht dazu. Mit BX würde es funktionieren, wobei man üblicherweise vorher einMOV BX, Tabelle
sagen und dann SI oder DI zum Hochzählen benutzen würde:MOV [BX+DI], AL
.
BTW dein LOOP kommt mir sehr haarig vor: Der Test bezieht sich auf CX, aber du initialisierst nur CL.Disclaimer: Kann alles Unsinn sein, meine Assemblererfahrungen sind Jahrzehnte her.
-
Oke, Problem gelöst. Man darf nur die Indexregister di oder si zum Hochzählen bei dieser Art der Adressierung nutzen.
.MODEL Tiny .CODE ORG 100h Start: mov al,128 mov cx,8 mov bx,OFFSET Tabelle mov di,0 Looptab: mov [bx+di],ax shl ax,1 inc di Loop Looptab mov ah,4Ch int 21h Tabelle DB 8 DUP (?) END Start
-
Moin.
taipier schrieb:
Man darf nur die Indexregister di oder si zum Hochzählen bei dieser Art der Adressierung nutzen.
Nö, BX kann genauso dafür verändert werden, und alle 32 Bit-Register auch (wenn vorhanden). Nur bei (E)BP und (E)SP und bei Kombinationen damit wird über das Stacksegment(SS) adressiert und bei allen anderen Adressregister das Datensegment(DS) verwendet.
Beispiel:
.MODEL Tiny .CODE ORG 100h Start: mov al,128 mov cx,8 mov di,OFFSET Tabelle Looptab: mov [bx+di],ax shl ax,1 inc bx Loop Looptab mov ah,4Ch int 21h Tabelle DB 8 DUP (?) END Start
Kleine Code-Optimierungen:
; mov ah,4Ch ; int 21h ret ; Bevor das Programm startet wird ein Word mit 0000 auf den Stack gepusht ; und den Opcode für ein "int 20h" in den PSP bei Offset 0 eingefügt. ; Wenn der Stackpointer und unser Codesegment(CS) nicht manipuliert wurde ; ist es möglich so eine *.COM-Anwendung mit nur einem "ret"-Befehl zu beenden. ; inc bx lea bx,[bx+1] ; inc di lea di,[di+1] ; Wenn für die Operation keine Flags(Flagregister) benötigt werden, ; dann ist ein LEA-Befehl sinnvoller als ein "inc", oder ein "add", ; weil LEA schneller ausgeführt wird als "inc", oder "add".
Dirk