Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1461

[VB6] - Inline assembler Add-in.

$
0
0
Hello everyone!
There are cases where you need to use the assembly code in your VB6 projects. Usually this is done using a previously-compiled code that is placed into the the memory. Then this code is run using one of millions method. Unfortunately this method has the disadvantages. For instance, you will have to change the procedures of the placement code in the memory If you change the asm-code. In addition it is quite slow process. I've written the Add-in that does these process automatically, also after compilation any processes of the placement of the code in the memory are not performed. Asm-code links to EXE. This add-in supports the asm-code either IDE or the compiled form (native only!).

How does it use?
First you have to install the Add-in (installer available at the end of article). After installing you should run the Add-in from VB6 IDE (Add-Ins -> Add-in Manager -> Inline assembler). It adds the new item to Add-Ins menu. If current project does not use the add-In features yet it will add the new module to project. You should add the prototypes of the functions in this module in order to call them from VB6 code. You can rename this module, place the prototypes of the functions, but you can't place the code to this module. After creating of the module you can run the ASM-editor. There is the combobox with the the functions which you defined in the module. For each function you can override the code using the NASM syntax. However if you don't override code (just leaving it empty) a function won't be overridden (this function is left a typical vb6 function). Each project (if you use this Add-in) is associated the additional file with *.ia extension in the project folder. This file contains the asm-codes for each function that is overridden by user. This add-in works "transparently", i.e. if you disable add-in project will work and compile, only "stub-functions" will work without overrides. *.ia file isn't "vitally essential" for working of the project, i.e. this project will work anyway.
Let's consider working of Add-in with the simple example. For instance, we need to mix the two integers-arrays without overflowing, i.e. if the result of the addition is greater than 32767 it should be left to 32767. Opposite, if the result of the addition is smaller than -32768 it should be left to -32768. For this very well suit MMX-extension. It has the instructions for working with the vector data with the saturation. Ok, let's go! Create new project, open Add-in. It adds the new module, rename this module to modInlineAsm. Now define the prototype of the function:
Code:

Public Function MMXAdd( _
                ByRef dest As Integer, _
                ByRef src As Integer, _
                ByVal count As Long) As Long
End Function

At the first parameter we pass the first element of the array, also this array is result; at the second parameter we pass the first element of the second array; finally, at the third parameter we pass the number of the elements. Note that the size should be a multiple of 8 bytes, because we will use the vector instructions, which work with 8 bytes simultaneously. Now define the procedure that will call this function:
Code:

Private Sub Form_Load()
    Dim src()  As Integer
    Dim dst()  As Integer
    Dim size    As Long
    Dim index  As Long
   
    size = 1024
   
    ReDim src(size - 1)
    ReDim dst(size - 1)
   
    For index = 0 To size - 1
        ' // Fill arrays with sine
        src(index) = Sin(index / 40) * 20000
        dst(index) = Sin(index / 23) * 20000
    Next
   
    ' // Add with saturation
    MMXAdd dst(0), src(0), size
   
    '// Draw result
    AutoRedraw = True
   
    Scale (0, 32767)-(index, -32768)
   
    For index = 0 To size - 1
        If index Then
            Me.Line -(index, dst(index))
        Else
            Me.PSet (index, dst(index))
        End If
    Next
   
End Sub

As you can see here both arrays are filled with sines which have the different period. Further we mix these arrays using MMXAdd function. Eventually the result array is being shown to the screen. Now we should override the MMXAdd function. For this activate the Add-in. The editor window will be opened, and there we select the MMXAdd function and add the following code:
Code:

BITS 32

; Addition of two arrays using saturation
; Size of arrays should be a multiple of 8

push    EBP
mov  EBP, ESP
push    EBX
push    ESI
push    EDI
mov  ESI,DWORD [EBP+0x8]
mov  EDI,DWORD [EBP+0x0C]
mov  ECX,DWORD [EBP+0x10]
shr  ECX,2

test  ECX,ECX
je  EXIT_PROC
emms  ; Initialize MMX

CYCLE:
  movq  MM0,QWORD [EDI]
  movq  MM1,QWORD [ESI]
  paddsw  MM1,MM0
  movq  QWORD [ESI],MM1
  add  ESI,0x8
  add  EDI,0x8
loop  CYCLE

emms

EXIT_PROC:
pop    EDI
pop  ESI
pop  EBX
mov  esp, ebp
pop  ebp

ret  0x0c

It's very simple if you know the instruction set. The main instruction is paddsw that adds two four-dimensional 16 bits integer vectors with sign by single operation. Now save project and run it:
Name:  MMX_test.PNG
Views: 41
Size:  20.7 KB
Nice! As you can see at the screenshot, the two sines are added with the saturation. You can notice the saturation by the peaks.
Okay, now let's try to compile the EXE file and check what is called and what is compiled:

As you can see, the code is already inside EXE, without memory allocation and unnecessary stuff.

How does it work?
Actually everything is very simple. When Add-in is connected the handlers of key events are set: the compilation start event, running code event, close/save project event etc. When you run code in IDE the all asm-codes are being compiled, also the addresses of the overrides function are calculated. Further the code of the original stub-functions is replaced to asm-code. When you call the stub-function it calls the asm-code. When you stop the execution the Add-in restores the original code. When you compile to the native code (or rather before linking) it finds the OBJ-file of the overridable module and replaces the code of the stub functions to asm-code and resaves file. For this functionality i write the COFF parser. Generally it can provides the lot of different features.
This project is very poorly tested, because i don't have enough time, therefore i think it'll contain very many bugs. Considering that the half of the project uses the undocumented features and trick, which perhaps don't work as i know. In this project even isn't syntax highlighting, because i don't have the possibility to finish the my highlighter textbox yet. Still i'm using the simple textbox. If someone have found the bugs write here.
Thanks for attention!

Download Add-in.
Attached Images
 

Viewing all articles
Browse latest Browse all 1461

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>