5. Tip's in Verbindung mit dem Inline-Assembler (Teil 2)

English


Tip's in Verbindung mit dem Inline-Assembler (Teil 1)

5.10. Parameterrückgabe mit dem Inline-ASM

Im Gegensatz zum reinem Assembler läuft die Rückgabe einer Variablen im PowerBASIC Inline-Assembler leicht anders ab. PowerBASIC 3.0 gestattet z.B. nicht die direkte Übergabe aus dem Inline-Assembler an die FUNCTION, dies ist nur über einen kleinen Trick möglich.
    Beispiel:
            High% = &h1234
            Low%  = &h4578
            PRINT HEX$(Demo1&(High%, Low%))

            FUNCTION Demo1&(BYVAL High%, BYVAL Low%)
                    LOCAL Dummy&
                    ! mov dx, High%
                    ! mov ax, Low%
                    ! mov Dummy&[02], dx
                    ! mov Dummy&[00], ax
                    Demo1& = Dummy&
            END FUNCTION
Ab PowerBASIC 3.1 können Sie den Rückgabewert aber direkt an die FUNCTION übergeben, nur bei 32bit (und größeren) Werten müssen Sie wieder einen kleinen Kniff anwenden:
    Beispiel:
            High% = &h1234
            Low%  = &h4578
            PRINT HEX$(Demo2&(High%, Low%))

            FUNCTION Demo2&(BYVAL High%, BYVAL Low%)
                    ! mov dx, High%
                    ! mov ax, Low%
                    ! mov FUNCTION[02], dx
                    ! mov FUNCTION[00], ax
            END FUNCTION

5.11. Variablenübergabe in Interrupt-Prozeduren

Sehr schwierig ist die Übergabe von Variablen innerhalb einer eigenen Interruptroutine, da sie davon ausgehen können, das das Datensegment mit hoher Sicherheit nicht dem benötigtem Datensegment von PowerBASIC entspricht. Allerdings auch hier haben uns die Entwickler von PowerBASIC eine große Hintertür offen gelassen. Die Adressierung über das Codesegment, welches in der Regel immer gleich ist! Allerdings klappt dieser Trick nur im Inline-Assembler, zur Übergabe von/zu reinen PowerBASIC Routinen müssen sie diese Variable umkopieren.
    Beispiel:
            ! mov ax, &h1234
            ! mov Demo, ax
            ! mov bx, Demo
            ! retn

            Demo:
            ! dw 0
Sollten Sie sich diese Sache unter einem Debuger ansehen, so werden sie feststellen das PowerBASIC vor dem Variablenzugriff das Präfix &h2E (Adressierung über das Codesegment) voranstellt und das '! dw 0'-Feld den Wert &h1234 angenommen hat.

5.12. Erstellen von 32bit-Zeigern

Oft werden 32bit Zeiger benötigt um eigene Interrupt-Prozeduren, alte Interrupt-Handler oder auch Gerätetreiber wie CTVDSK/CT-VOICE und HIMEM/MSCDEX aufzurufen. Da die Erstellung des 32bit Zeigers in einem der vorangegangenden Absätze beschrieben wurde, hier nur noch der eigentliche Syntax:
    Beispiel:
            ! jmp dword Demo&
            ! jmp dword ptr Demo&
            ! call dword Demo&
            ! call dword ptr Demo&
Die Zeiger können ebenfalls dem Codesegment entnommen werden!

5.13. Konvertierung von REG nach Inline-ASM

Ebenfalls recht einfach läuft die Umsetzung von REG- nach Inline- Assemblersourcen ab. Im Gegensatz zum REG-Befehl, welcher die Inhalte der Prozessorregister in einem internen REG-Array zwischenpuffert, bewirkt ein Zugriff über den Inline-Assembler sofort eine direkte Manipulierung der Prozessorregister. Der REG-Befehl übergibt die REG-Werte erst beim Aufruf von CALL INTERRUPT. Bitte beachten Sie diesen Unterschied und Sie werden weniger Probleme haben. Ansonsten können Sie zum Beispiel folgende Befehle 1:1 umsetzen:
    Beispiele:
            REG 1, &h12345           -> ! mov ax, &h1234
            REG 2, &hFF              -> ! mov bl, &hFF
            REG 3, &h22 * 256        -> ! mov ch, &h22
            REG 4, &hAABB            -> ! mov dh, &hAA
                                        ! mov dl, &hBB
            REG 9, Demo%             -> ! mov es, Demo%
            CALL INTERRUPT &h21      -> ! int &h21
            Low?? = REG(1) AND 255   -> ! mov low??, al
            High?? = REG(1) \ 256    -> ! mov High??, ah

5.14. Konvertierung von A86 nach Inline-ASM

Prinzipiell ohne Probleme läuft eine Umsetzung von A86-Sourcen ab. Entfernen Sie einfach den Stackrahmen und binden Sie die Assemblerzeilen einfach in Ihren Inline-Assembler ein. Am besten ist es, wenn Sie dazu einen Funktionsaufruf erstellen, der die Variablen immer BYVAL übergibt, den Rest erledigt PowerBASIC.


(c) 1995/2007 by Thomas Gohel, All rights and bug's reserved