dcsimg
Results 1 to 21 of 21

Thread: [VB6] - Inline assembler Add-in.

Threaded View

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Feb 2015
    Posts
    1,344

    [VB6] - Inline assembler Add-in.

    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 to 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: 2452
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!

    https://yadi.sk/d/_yMsCu7o3So5GY

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width