Я хотел бы придумать байтовый код на ассемблере (ассемблере?) для машин Windows, чтобы добавить две 32-битные длины и выбросить бит переноса. Я понимаю, что часть машин Windows немного расплывчата, но я предполагаю, что байты для ADD
практически одинаковы во всех современных наборах инструкций Intel.
Я просто пытаюсь немного злоупотребить VB и сделать некоторые вещи быстрее. Таким образом, в качестве примера запуска прямой сборки в VB шестнадцатеричная строка "8A4C240833C0F6C1E075068B442404D3E0C20800"
представляет собой ассемблерный код для SHL
, который может быть внедряется в программу VB6 для быстрой операции SHL
, ожидающей двух параметров Long (здесь мы игнорируем тот факт, что 32-битные long в VB6 подписаны, просто притворяемся, что они беззнаковые).
В том же духе, что представляет собой шестнадцатеричная строка байтов, представляющая инструкции ассемблера, которые сделают то же самое, чтобы вернуть сумму двух 32-битных целых чисел без знака?
Шестнадцатеричный код выше для SHL
, по словам автора:
mov eax, [esp+4]
mov cl, [esp+8]
shl eax, cl
ret 8
Я выплюнул эти байты в файл и попытался разобрать их в командной строке Windows, используя старую утилиту отладки, но я понял, что она не работает с более новым набором инструкций, потому что EAX
не понравилось, когда я попытался что-то собрать, но он был счастлив с AX
.
Из комментариев в исходном коде я знаю, что SHL EAX, CL
равно D3E0
, но у меня нет ссылки, чтобы узнать, какие байты нужны для инструкции ADD EAX, CL
, иначе я бы попробовал. (Хотя теперь я знаю, что операнды должны быть одного размера.)
Я попробовал плоский ассемблер и ничего не понял, как его использовать. Я использовал его для сборки исходного кода SHL
и получил совсем другой результат, не те же байты. Помощь?
lea eax, [ecx + edx]
/ret
, если мы говорим о __fastcall, иначеmov
load/memory sourceadd
/ret
. (флаг переноса не является частью возвращаемого значения). Вы полностью усложняете это, и IDK, почему вызов функции asm будет быстрее, чем использование+
в исходном коде VB. Кроме того,add eax, cl
невозможно закодировать, поскольку операнды имеют разные размеры. - person Peter Cordes   schedule 03.11.2020+
. Разве это не просто математическая обертка для целочисленного типа с фиксированной шириной? Двоичное сложение — это та же операция для дополнения до 2, что и для беззнакового, поэтому, если в VB6 нет беззнаковых типов, узнайте, как вы собираетесь вернуть результат этого ассемблирования обратно в VB полезным способом. Расширяет ли VB+
целые числа до расширенной точности вместо переноса, что делает их медленнее? Если это так, то да, вероятно, что asm будет быстрее, усекая результат. - person Peter Cordes   schedule 04.11.2020paddd xmm0, [edx]
для одновременного выполнения 4 операций добавления (SIMD) с нагрузкой 2/такт и дополнительной пропускной способностью. Если нет, то вызов функции для каждого добавления отстой, но все же может быть хуже, чем то, что вы можете заставить VB делать самостоятельно, IDK. Прошли годы с тех пор, как я когда-либо делал что-либо с VB. (Большинство из них заключалось в написании нативной функции на C, которую я мог вызывать из VB в Excel для подгонки данных примерно в 60 раз быстрее, чем нативный код VB, для летней студенческой работы 20 лет назад.) - person Peter Cordes   schedule 04.11.2020x += 1
сx = 0x7ffffffff
? Вы получаете-2147483648
(C INT_MIN)? Если это так, вы можете сделать обычный+
и передать результат функции, которая хочет unsigned long, и она будет просто работать, потому что она имеет битовый шаблон0x80000000
, такой же, как unsigned2147483648
. Вам нужно обойти оператор+
только в том случае, если он обнаруживает переполнение со знаком и выполняет что-то другое, кроме 32-битного переноса. - person Peter Cordes   schedule 04.11.2020