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 ein MOV 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


Anmelden zum Antworten