Форум программистов, компьютерный форум, киберфорум
The trick
Войти
Регистрация
Восстановить пароль

Inline assembler

Запись от The trick размещена 11.01.2016 в 16:38
Показов 4370 Комментарии 3
Метки asm, vb

Всем привет.
Бывают ситуации когда в VB нужно использовать ассемблер. Обычно для этого используют предварительно скомпилированный код размещенный в памяти и запускают его одним из миллиона способов. Очевидным недостатком этого метода является то, что любая модификация ассемблерного кода требует изменения в процедурах размещения кода в памяти. К тому же это является довольно медленной процедурой. Я написал Add-in, который делает вышеописанные процедуры автоматически, а также после компиляции никакие дополнительные действия по размещению кода не выполняются - ассемблерный код влинковывается в EXE. Ассемблерный код работает и в IDE и в скомпилированном (только Native!) коде.
Как этим пользоваться?
Для начала нужно установить Add-in (установщик доступен по ссылке ниже). После установки нужно запустить его из VB (Add-Ins -> Add-in Manager -> Inline assembler). После этого в меню добавится одноименный пункт. Если проект еще не использовал функционал Add-in'а то при первой активации добавится стандартный модуль, в который нужно будет добавить прототипы ассемблерных функций для VB6. Сам модуль можно переименовывать, добавлять процедуры/функции, но размещать в них какой-либо функционал запрещено. После создания модуля можно уже открыть сам редактор ассемблерного кода. В нем доступен раскрывающийся список с именами функций, определенных в добавленном модуле. Для каждой функции можно переопределить код используя синтаксис ассемблера NASM, однако если кода нет, то функция не модифицируется (т.е. получается обычный вызов пустой функции). С каждым проектом (если использовался функционал Add-in'а) связывается еще один файл с расширением *ia в папке с файлом проекта, в котором хранятся ассемблерные процедуры для проекта. Add-in работает "прозрачно", т.е. если Add-in отключен, то проект также будет работать и компилироваться, просто "функции-пустышки" будут работать как обычные. Файл *ia не является жизненно-необходимым для работы проекта, если его не будет, то соответственно "функции-пустышки" останутся нетронутыми.
Давайте посмотрим работу Add-in'а на простом примере. К примеру нам необходимо сложить два Integer-массива без переполнения, т.е. если результат сложения больше 32767 он и останется 32767, а если меньше -32768 он останется -32768. К тому же нам нужно сделать это как можно быстрее. Для этого очень хорошо подходит расширение MMX, в нем есть инструкции для работы с векторными данными с насыщением. Перейдем к реализации. Создадим новый проект, откроем Add-in. Это добавит новый модуль, переименуем его в modInlineAsm. Теперь определим прототип функции:
Visual Basic
1
2
3
4
5
Public Function MMXAdd( _
                ByRef dest As Integer, _
                ByRef src As Integer, _
                ByVal count As Long) As Long
End Function
Первым параметром передаем первый элемент массива, он же результирующий; вторым параметром первый элемент второго массива; наконец третьим параметром передаем количество элементов. Кстати размер массивов должен быть кратен 8 байтам, т.к. мы будем использовать векторные инструкции которые одновременно работают с 8-ю байтами. Теперь определим процедуру в форме, которая будет вызывать эту функцию:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
Как видно здесь просто заполняются 2 массива синусоидой, а потом мы их складываем с помощью нашей функции, и выводим результат на форму в виде графика. Теперь нам нужно переопределить процедуру, для этого активируем Add-in. Откроется окно с редактором кода. В нем мы выбираем нашу функцию и добавляем следующий ассемблерный код:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
Здесь все просто, если знать инструкции. Самая главная paddsw складывает два четырехмерных вектора 16-битных значений со знаком за одну операцию. Теперь сохраняем проект и запускаем:
Нажмите на изображение для увеличения
Название: MMX_test.PNG
Просмотров: 783
Размер:	20.7 Кб
ID:	3525
Как видно из скриншота, две синусоиды сложились причем с насыщением, это можно заметить по пикам. Теперь давайте попробуем скомпилировать EXE файл и посмотреть что у нас вызывается и во что компилируется:
Нажмите на изображение для увеличения
Название: Disasm_Listing.PNG
Просмотров: 838
Размер:	29.6 Кб
ID:	3526
Как видим код уже находится внутри EXE, без всяких выделений буферов и т.п. ненужных вещей.
Как это работает?
На самом деле все довольно просто. В самом начале ставятся обработчики на ключевые события вроде компиляции, запуска кода, закрытия/сохранения проекта и т.п. При запуске из IDE компилируются все коды заданные пользователем, а также вычисляются адреса переопределяемых функций. Затем код переписывается на код скомпилированный через NASM. И при вызове кода, вызывается наш код. При остановке, код восстанавливается. При компиляции (а точнее перед линковкой) ищется OBJ файл переопределяемого модуля и код функций пустышек переписывается на ассемблерный код, и файл пересохраняется. Для этого я специально писал COFF парсер. Вообще это открывает кучу разных возможностей от замены функций рантайма на свои до шифрования кода. Вообщем много чего можно придумать.

Проект, можно сказать, совсем не тестировался, т.к. у меня в ближайшее время не будет такой возможности, поэтому скорее-всего будет много багов, учитывая то, что половина функционала Add-in'а использует недокументированные трюки, которые возможно работают не так как я думаю. В проекте нет даже подсветки синтаксиса, у меня есть мой самодельный текстбокс с подсветкой написанный с нуля, но его нужно дебажить еще и дописывать, поэтому пока я использовать стандартный текстбокс. Если кого-нибудь заинтересует, и будут баги, пишите сюда.
Кстати, я редко стал писать сюда, да и вообще бывать на форуме, но это не значит что я перестал заниматься VB, у меня еще много проектов которые наполовину реализованы. К примеру готовится проект для использования оптимизаций компиляции в IDE, т.е. отключить переполнения при арифметических операциях для использования циклической арифметики в IDE, а также проверку границ массивов в IDE.
Также к примеру вот:

-нативная загрузка PNG а альфаканалом в IDE в любые контролы. Так что ждите).
Всем спасибо за внимание.
Скачать Add-in.
Метки asm, vb
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 3
Комментарии
  1. Старый комментарий
    Анатолий, можно установить данный Add-In на портируемую версию VB?
    Запись от CharlyChaplin размещена 07.02.2017 в 07:39 CharlyChaplin вне форума
  2. Старый комментарий
    Цитата Сообщение от CharlyChaplin
    Анатолий, можно установить данный Add-In на портируемую версию VB?
    Да. А можно узнать что за версия? На что портируете?
    Запись от The trick размещена 07.02.2017 в 16:51 The trick вне форума
  3. Старый комментарий
    Visual Basic 6.0 Portable SP6. Уже есть встроенные Add-Ins: CodeSmart, Source Code Control, vbAdvance, MouseWheel Fix... Я давно на неё перешёл из-за удобства. Ношу на флешке и в любом месте могу писать код. Просто вчера я попробовал установить. Видимо путь нужно устанавливать не С:\Program Files (WinXP), а какой-то другой может?
    Так как версия портируемая, то рядом с .exe-файлом есть папка "Microsoft Visual Basic 6.0 SP6\%ProgramFilesDir%". Попробовал туда установить. Но всё равно после загрузки IDE и перехода в меню "Add-Ins/Add-In Manager", не увидел нового пункта.:-(
    Может что ещё дополнительно нужно сделать?

    Вот внутренние папки портируемой версии:
    ===
    %AppData%
    %Local AppData%
    %Personal%
    %Program Files Common%
    %ProgramFilesDir%
    %SystemRoot%
    %SystemSystem%
    SKEL
    ===
    Запись от CharlyChaplin размещена 08.02.2017 в 04:03 CharlyChaplin вне форума
 
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru