Первая программа на ассемблере.
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.223] |
|
|
Перед отправкой сообщения внимательно прочтите правила раздела!!!

| Страницы: (5) « Первая ... 2 3 [4] 5 все ( Перейти к последнему сообщению ) |
Первая программа на ассемблере.
|
Сообщ.
#46
,
|
|
|
|
А по-моему так они сохраняют совместимость ![]() Иначе на 386 программы рассчитаные на 16-bit PMode просто бы не работали... |
|
Сообщ.
#47
,
|
|
|
|
Цитата cppasm @ В том то и дело, что могли бы сделать по другому, если бы не жмотились А по-моему так они сохраняют совместимость ![]() |
|
Сообщ.
#48
,
|
|
|
|
Цитата AndNot @ Я уж не говорю про невозможность ариф. операций с адресами меток, про отсутствие Size(вот счастье то размеры структур самому высчитывать), да и много чего. Размеры структур высчитывать ни к чему - для этого есть оператор TYPE ![]() Ну а с адресами и метками действительно косяк. С глобальными указателями на функции и переменные - понятно, т.к. это лишние хлопоты при компиляции и линковке dcu. Но не позволять вычислять разность адресов локальных меток, да еще при этом выдавать дебильное сообщение о релоках, которые тут ни к селу ни к городу - это конечно чересчур тупо А встроенный асм это и есть полезная игрушка - поупражняться в оптимизации, хаке, доморощенной защите и т.п., что еще нужно ? |
|
Сообщ.
#49
,
|
|
|
|
Цитата BASM тянет на игрушку, не более тока для тех кто не играл в него по крупному Это вещь, причем посерьёзней чем TASM, а отсутствие некоторых фич - так ведь острой необходимости в этом нет, вместо $ вполне достаточно offset'ов на метки. Так же и с мракосами. Всегда их заменял на вызовы функций или, разворачивал. чтоб глаза не мозолили. Один фик, ЯВУ в них не загонишь. |
|
Сообщ.
#50
,
|
|
|
|
Цитата leo @ Смотря в какой оптимизации. Если по скорости, то тут будет больщой облом. Ты лучше меня знаешь, как важно, в таких случаях, выравнивание кода и данных. Только вот в ЯВУ этим управлять можно только косвенно, да и то - не везде и не во всех.А встроенный асм это и есть полезная игрушка - поупражняться в оптимизации Цитата n0p @ Увы, есть куча примеров, когда счетчик просто необходим. Его отсутствие ведет к вынужденным вычисления в теле программы, что не есть гуд.а отсутствие некоторых фич - так ведь острой необходимости в этом нет, вместо $ вполне достаточно offset'ов на метки Цитата n0p @ Это ты загнул Так же и с мракосами По мне запись:![]() ![]() invoke MessageBox, NULL, _T("Use macro string!"), _T("Helloy"), MB_OK ![]() ![]() push MB_OK push offset szTitle push offset szMessage call MessageBox Или взять такую задачу, как шифрование. Вот простой пример, когда я использовал эту фичу, от ламеров, которые любят править строки в программе:) : ![]() ![]() XORTEXT = 1 ; 0 - при отладке XORKEY equ 57h MACRO SETXORTEXT delaytime,msg ifnb <delaytime> if XORTEXTS db not(delaytime xor XORKEY) else db delay endif endif IRPC ASS,<msg> if XORTEXTS db not('&ASS' xor XORKEY) else db '&ASS' endif ENDM ENDM ; а затем просто объявляем текстовые данные SETXORTEXT 9,<SCREEN SAVER III> SETXORTEXT 11,<for> SETXORTEXT 9,<DOS Navigator> Подобным макаром реализуется и вычисление CRC имен функций, необходимое при кодинге без таблиц импорта. А на BASM тебе придется вычислять все отдельно. Лишняя трата времени, особенно при переделках. Или возьми такую больную тему, как появление новых команд процессора. Что прикажешь делать? Менять компилятор? А вот при наличии макросов это уже не проблема. Никто не мешает мне использовать SSE даже с 3-м тасмом. Цитата n0p @ Ошибаешься Один фик, ЯВУ в них не загонишь Посмотри на фасм, там все высокоуровневые средства реализованы в виде макросов.Да и на простом тасме макросы могут реализовать практически все. По крайней мере я реализовывал if/while/case и прочие. Причем вложенные |
|
Сообщ.
#51
,
|
|
|
|
Цитата Увы, есть куча примеров, когда счетчик просто необходим. Его отсутствие ведет к вынужденным вычисления в теле программы, что не есть гуд. Сойдемся на том что есть некая куча г-вна, как правило на 100пудофф абсолютно бесполезного ![]() Цитата Попробуй ка на BASM такое заделать Я лутше с BASMA перейду на ЯВУ, и спокойно все на нем сделаю, особо не задалбываясь |
|
Сообщ.
#52
,
|
|
|
|
Цитата AndNot @ Если по скорости, то тут будет больщой облом. Ты лучше меня знаешь, как важно, в таких случаях, выравнивание кода и данных. Я то как раз знаю, что требование выравнивания кода и данных это перестраховка из разряда "береженого бог бережет", которая в большинстве пратических задач никакой ощутимой роли не играет, за исключением редких, особых случаев ловли блох при супероптимизации тонких циклов. В NetBurst выравнивание кода вообще не важно, т.к. рулит Т-кэш (правда при ловле блох иногда может вылезать зависимость от выравнивания, но это непредсказуемые косяки, требующие особого подхода). В P6 и AMD невыравненные метки циклов могут в худшем случае приводить к дыркам в 1-3 микрооперации в конвеере, что, во-первых, не обязательно приводит к задержке (т.к. может сглаживаться очередью команд), во-вторых, для толстых циклов потеря одного такта особой роли не играет, а тонкие циклы по правилам следует разворачивать. О выравнивании данных и вообще говорить нечего - 4-байтные данные в дельфях всегда выравнены (если самому не накосячить с packed record), а для массива double потеря 1 такта в 4/64 = 1/16 случаях, да с учетом латентностей FPU и побочных факторов - это капля в море. Ну и во-вторых, оптимизация - штука относительная, поэтому при использовании встроенного асма можно не гнаться за сверхрекордами скорости, а достаточно лишь устранить косяки дельфийского компилятора, чтобы получить заметный выигрыш. Например, при FPU-вычислениях дельфи постоянно бестолково загружает\сохраняет промежуточные переменные вместо того, чтобы держать их в регистрах, да еще и wait пичкает не к месту, поэтому просто грамотная асм-реализация без всякого выравнивания может давать выигрыш в циклах в несколько раз. Ну а для сверхоптимизации с выравниванием и прочими прибамбасами можно и dll-ку на полноценном асме накатать |
|
Сообщ.
#53
,
|
|
|
|
leo, все верно, да не совсем. Для более старых моделей выравнивание более критично. Я уж не говорю про SSE, сам замерял, разбросы были ощутимые ;-)
|
|
Сообщ.
#54
,
|
|
|
|
AndNot SSE предназначен для массовых вычислений, следовательно над динамической памятью, поэтому выравнивание данных - это задача не BASM, а MM (Memory Manager), я так понимаю. Есть, например, FastMM для Delphi7, который, насколько я помню всё специально выделяет по границе 16 байт (используется в движке GLScrene). Хотя, конечно, лишней такая возможность не была бы...
|
|
Сообщ.
#55
,
|
|
|
|
Цитата ors_archangel @ AndNot SSE предназначен для массовых вычислений, следовательно над динамической памятью Ну статические массивы никто не отменял, другой вопрос что их компилятор HLL выравнивает... |
|
Сообщ.
#56
,
|
|
|
|
Цитата cppasm @ Однако!.. Я себе так представляю: SSE в аудио приложении, задача - обработка звука, звук - в статическом массиве? SSE в графическом приложении, задача - обработка геометрии, неужели и геом. модели - в статическом массиве... (кстати бывает - в демках, признаю) Мне кажется, что (всё-таки) 99% данных, которые поточно (т.е. массово) обрабатыватся через SSE, где он и имеет смысл - это динамическая память, соотв. от сюда и тезис о том, что задача выравнивания ложиться вследствие всего этого не на HLL-компилятор (или люой другой), а на менеджер памяти, используемый для выделения оной. Если есть контрпримеры, интересно было бы их услышать. Ну статические массивы никто не отменял |
|
Сообщ.
#57
,
|
|
|
|
Цитата ors_archangel @ Если есть контрпримеры, интересно было бы их услышать. Ну та же обрабокта звука. Скажем эквалайзер. Да, звук ты читаеш из файла скорее всего в динамически выделенную память (хотя можно и в статический массив). А вот коэффициенты для эквалайзера находятся в массиве. При обработке используются ведь не только исходные данные, но и матрицы коэффициентов различных - например размытие для видео и т.д. |
|
Сообщ.
#58
,
|
|
|
|
Цитата cppasm @ Другой вопрос - как? Ну статические массивы никто не отменял, другой вопрос что их компилятор HLL выравнивает... Цитата ors_archangel @ Зависит только от задачи. Когда я писал небольшую прогу по снятию и отображению сигнала со звуковой карты, то отдал предпочтение именно статическим массивам, так удобнее было, поскольку размеры массивов были ясны с самого начала. Мне кажется, что (всё-таки) 99% данных, которые поточно (т.е. массово) обрабатыватся через SSE, где он и имеет смысл - это динамическая память Цитата ors_archangel @ Хотелось бы еще узнать, как работает GetMem? Может кто рылся в ней? задача выравнивания ложиться вследствие всего этого не на HLL-компилятор (или люой другой), а на менеджер памяти, используемый для выделения оной |
|
Сообщ.
#59
,
|
|
|
|
Цитата AndNot @ Другой вопрос - как? Ну так это уже от компилятора зависит и в большинстве случаев управляемо... |
|
Сообщ.
#60
,
|
|
|
|
Цитата AndNot @ В Delphi 5-7 по крайней мере MM не плох, а начиная минимум с Delphi9 используется ещё значительно более оптимизированный вариант.GetMem Цитата getmem.inc cAlign = 4; Вот такое выравнивание использует стандартный MM Delphi 7. Вообще, MM различает два вида блоков - большие и маленькие :Цитата getmem.inc cSmallSize = 4*1024; Если size <= cSmallSize, то блок выдаётся из массива smallTab, иначе - выделяется динамически, но, что важно, что все блоки выравниваются только по cAlign, т.е. по dword, плюс перед большими блоками добавляют заголовок (8 байт как я когда-то смотрел, может уже путаю, раньше ещё может 4 было, в Delphi 5, точно не помню). В итоге, если блок больше страницы памяти 4k, то он будет выровнен по 8 байтам, иначе - по 4. При небольшом тестировании получилось, что из 1000 блоков размером от 4097 до 69633 адреса, кратные 16 байтам получили 410 блоков, а остальные 590 получили адреса, кратные только 8 байтам. Малые блоки же, при ещё более простой проверке выдали блоки с адресами, кратными вообще 4 байтам. Теперь берём RecyclerMM из glScene (аналогичный MM используется и BD3, TurboDelphi10 и в остальных Delphi8+ думаю тоже). Как и заявляет разработчик, к блокам не добавляется ни загловков, ни хвостов, и все они выровнены (включая блоки даже самого малого размера - 4 б) строго по 16 байтам, так что динамическую память для SSE в Delфi в принципе выровнять не составляет труда - в свежих версиях Delphi это bydefault, а более мудрые можно легко научить благодаря механизму замены MM. Конечно, статике это не поможет |