5. Hints in connection with the Inline-Assembler (Part 2)


Hints in connection with the Inline-Assembler (Part 1)

5.10. Parameter return with the Inline-Assembler

In opposite to true Assembler the return of a variable works slightly different in the PowerBASIC Inline-Assemble. PowerBASIC 3.0 for example does not allow the direct return from the Inline-Assembler to the FUNCTION, this is only possible with a little trick.
            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
From PowerBASIC 3.1 on you can directly pass the return value to the FUNCTION, only with 32bit (and bigger) values have to be passed using a little trick:
            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. Parameter return in Interrupt-Procedures

Very hard is the passing of variables from within an own Interruptroutine, because you can guess that the Datasegment isn't the same as the one used by PowerBASIC. But the developers of PowerBASIC have left us a big back door here. The addressing using the Codesegment, which is usually the same! Yet this trick only works with the Inline-Assembler, to pass from/ to true PowerBASIC-Routines you will have to recopy this variable.
            ! mov ax, &h1234
            ! mov Demo, ax
            ! mov bx, Demo
            ! retn

            ! dw 0
Should you look at this thing with a Debugger, you will notice that PowerBASIC will add the Prefix &h2E (addressing using the Codesegment) in front of the access to the variable and the '!dw 0' field will hold the value &h1234.

5.12. Creating 32Bit-Pointers

Often 32Bit Pointers are needed for some Interrupt-Procedures to call old Interrupt-Handlers or Devicedrivers like CTVDSK/CT-VOICE and HIMEM/ MSCDEX. Because the creation of a 32Bit Pointer was described in a previous Chapter, here is the actual Syntax:
            ! jmp dword Demo&
            ! jmp dword ptr Demo&
            ! call dword Demo&
            ! call dword ptr Demo&
The pointers can also be taken from the Codesegment!

5.13. Converting from REG to Inline-Assembler

The conversion from REG- to Inline-Assemblersources is also relatively simple. Instrad of the REG-Command, which buffers the Contents of the Processorregisters in an internal REG-Array, an access over the Inline- Assembler causes a direct manipulation of the Processorregister. The REG-Command passes the REG-Values when CALL INTERRUPT is executed. Please not this difference and you will have not as many problems. You can translate all other commands 1:1:
            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. Converting from A86 to Inline-Assembler

Usually a translation of A86-Sources can be done without problems. Remove the Stackborder and include the Assemblerlines into the Inline- Assembler. It will be best ig you create a FUNCTION call that passes the variables BYVAL, the rest is done by PowerBASIC.

(c) 1996/2007 by Thomas Gohel, All rights and bugs reserved
(c) 1996/1997 by Thomas Geiger, english version