Сам себе Iczelion

Тема в разделе "WASM.BEGINNERS", создана пользователем Mikl_, 11 май 2007.

Метки:
  1. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Mikl___
    Мне кажется что ”Шаг четвертый. Минимизируем WndProc (продолжение) Способ восьмой“ как раз один из самых неудачных. Потому что запись в таблицу адресов является довольно таки объёмным и медленным делом плюс, чем больше будет использовано сообщений, тем всё более неэффективным будет становиться этот способ из-за разрастания кода. Ведь вдобавок к большой таблице в памяти добавится большой код. Поэтому “Способ седьмой” будет, наверное, наиболее, эфиктивным. Тем более его можно чуть улучить?, правда смещение будет ограничено 16-тью битами:
    Код (Text):
    1. wmsg      dd ?  
    2. Max_MsgTable = 3
    3. MsgTable  dw defframeproc-defframeproc,wm_command-defframeproc,wm_close-defframeproc
    4. ;. . .
    5. mov eax,[wmsg]
    6. cmp ax,Max_MsgTable
    7. ja defframeproc;
    8. lea esi,[MsgTable+eax*2]
    9. lodsw
    10. add eax,defframeproc
    11. jmp eax;
    12. defframeproc:
    13. wm_command:
    14. wm_close:
    “hInstance dd 400000h ;Адрес нашей проги в памяти (Windows всегда её грузит по этому адресу)
    hIcon dd 10003h ;Иконка окна по умолчанию
    hCursor dd 10011h ;Курсор окна по умолчанию (здесь указан ID обычной стрелки)”

    А не является использование этих величин опасным ведь они недокументированны в MSDN и поэтому не гарантировано что их можно будет использовать после, какого ни будь патча?
     
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    hapr
    Собственно, способ седьмой и способ восьмой -- это одно и тоже, просто в описание восьмого способа более детализировано. О том что
    Я собственно и предупреждал
    Запись в таблицу адресов будет происходить лишь однократно в момент инициализации и далее для доступа к обработчику сообщения понадобится всего одно сравнение с Max_Msg. Спасибо за подсказку по уменьшению таблицы MsgTable в два раза, хотя наверное по аналогии можно уменьшить и до байта, если сообщения распреднлить по адресам кратным 2 или 4. Второе замечание о том что
    Проверялось для Win 95/98/2k/XP/Vista, наверное стало стандартом дефакто и врят ли изменится после, какого нибудь патча
     
  3. ltshck

    ltshck New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2007
    Сообщения:
    195
    Mikl___ , у тебя одного дома коллекйия твоих примеров и постов по этой теме.

    Можешь сделать chm архив и выкладывать его + дополнение?
    Совсем нехорошо пробегать по всей ветке темы вычесывая примеры.

    И, если можно, на какой-нить общедоступный свой блог / сайт / или сюда в раздел васма выкладывайте.

    спсибо.
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    ltshck
    Обрати внимание на сообщение #157 -- да и нет у меня дома коллекции примеров -- всё что приходит в голову выкладываю в этой ветке...
     
  5. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Mikl___
    Я подразумевал под разрастанием кода, что имеет смысл, чтоб таблица была заполнена изначально, так как при записи адресов в таблицу, хоть и только при инициализации мы ничего особо не выиграем. Например, если использовать dw, то получаем :
    MsgTable dw 4 dup(?); экономим 8 байт на размере файла, но ведь в оперативной памяти эта таблица всё равно займёт 8 байт.
    mov [MsgTable], WM_PAINT; 6*4=24 байта (Интересно, а как правильна, определять, сколько места занимает команда процессора, а то в Fasm она занимает 6, а OLLYDBG показывает, что 9 байт?)
    А так как я понимаю исполняемый код тоже держится в памяти то получаем хоть и некоторую экономию на самом файле но зато большие потери на оперативной памяти, которая как я понимаю, является более ценной, чем место на жёстком диске, причём это сомнительное преимущество будет стремиться к нулю при увеличении обрабатываемых сообщений и кучности этих сообщений. Вдобавок достаточно медленная инициализация программы из за цикла с stosd с медленной записью в память, а ведь если надо заполнить несколько таких таблиц. Поэтому из за этого загрузка приложения может значительно замедлится.
    Уменьшение до байта врядли имеет смысл, так как в случаи, например кратности 4 полученное смещение будет слишком малым чтоб туда можно было всунуть код обработки сообщений.
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    hapr
    Первое сообщение в этой ветке начинается с фразы
    Имелось в виду минимальный размер программы на диске, что собственно и является одним из преимуществ ассемблера над ЯВУ. При работе с gui-приложениями, особенно учебными, добится большой скорости наверное и нельзя, и нецелесообразно, хотя stosd, при желании, можно заменить на более скоростную комбинацию mov [edi],eax/add edi,4.
    так что больший размер, который код программы займет в оперативной памяти, с этой точки зрения, меня волнует меньше, чем размер исполнимого кода на винчестере, хотя даже если моя программа занимает 1 байт, то на диске она займет 4 кбайта, но здесь это не принципиально. Уменьшение размера приложения, как раз и позволяют использовать таблицу состоящую из байтов, здесь требуется подгонка под конкретное приложение.
    [offtop]Построение фраз наталкивает на мысль, что вы с Украины или Болгарии?[/offtop]
     
  7. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Mikl___
    Я просмотрел уроки по MDI на Fasm и Masm и у меня возникли некоторые замечания, вопросы?:
    В случае, когда после RegisterClass сразу следует CreateWindowEx то наверное, имеет смысл передавать вторым параметром “атом класса” который возвращает RegisterClass.
    А если вместо mov eax,[uMsg] так mov ax,word [uMsg] где [uMsg] – полученное сообщение.
    При получении WM_SIZE, зачем получать ширину и высоту рабочей области с помощью GetClientRect, если можно получить из lParam.
    [offtop] Честно говоря, я думал, что можно отличить по ”говору”, но, а так я с Белоруссии [/offtop]
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    hapr
    Учту...
     
  9. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    hapr
    Исправление в 32 уроке по MDI
    Код (Text):
    1. wmSIZE: mov edx,[lParam]
    2.     mov ax,dx; был eax равен 0
    3.     shr edx,16
    4.     invoke MoveWindow,[hClient],ebx,ebx,eax,edx,TRUE
    5. wmBYE:  leave
    6.     retn 10h
    Результат как и с GetClientRect, но код уменьшился -- здорово!
     
  10. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    Mikl___
    Так же, наверное, имеет смысл, например, при обработке сообщения WM_RBUTTONDOWN получать экранные координаты курсора не с помощью GetCursorPos, а из структуры MSG в которой находится позиция курсора, в экранных координатах, в момент, когда сообщение было помещено в очередь.
     
  11. xx7

    xx7 New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2009
    Сообщения:
    18
    хочу спросить, если можно.
    Взял из этого топика примеры под fasm, конкретно Tut_21:pipe
    Попробовал начать переделывать, с целью уменьшения размера исходного кода , и чтобы понять

    ничего почти не менял, добавил только зацикливание в том месте где читается из пайпа, и импрорт по другому оформил.
    Теперь запускается только если вставляю строку
    "section '.data' data readable writeable", и размер exe прибавляется на килобайт, секция с данными оказывается в начале

    Я так понял это выравниванием как-то называется ?
    как сделать чтобы и дальше работало без .data
    типа db 0,0,0,0,0 придётся вставить перед данными ?
    (прикрепил сорц на всякий случай)

    По форуму искал, находил, но ничего не понял, как сделать,
    только какието /align для компоновщиков
     
  12. xx7

    xx7 New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2009
    Сообщения:
    18
    оказалось что просто надо было добавить
    section '.code' code readable writeable executable

    и всётаки можно ещё уменьшить :) попробовал навставлять туда использование RICHEDIT вместо EDIT стало 2.5 килобайта
     
  13. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    hapr
    Экранные координаты можно получать и из самого WM_RBUTTONDOWN (+ ClientToScreen либо MapWindowPoints).
    Но думаю, вы и сами сможете составить забавную демку-контрпример, раздувающую для наглядности разницу во времени между поступлением сообщения в очередь и выводом его в оконную процедуру.
     
  14. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    xx7
    1) xchg ebx,eax это не просто перестановка содержимого регистров, а обнуление регистра ebx одним байтом (xor ebx,ebx - это два байта) здесь учитывается, что при старте приложения в WinXP eax=0
    2) mov esi,400000h ; [hInstance]
    shl esi,9 ; [hInstance]<<9 здесь после передачи значения hInstance, через esi передается значение CW_USEDEFAULT=80000000h=200h*400000h для установки X-, Y-координат и nWidth и nHeight окна
     
  15. hapr

    hapr Member

    Публикаций:
    0
    Регистрация:
    9 мар 2009
    Сообщения:
    59
    kero
    Конечно, можно, но если я не ошибаюсь, координаты помещаются в WM_RBUTTONDOWN в момент помещения сообщения в очередь соответственно, зачем преобразовать, если можно взять готовые.

    Но ведь не в каждой программе эта разница будет заметна, например: в “Блокноте”. В случае же более “серьёзных” программ можно использовать GetCursorPos но ведь если появляется разница во времени между поступлением сообщения и обработкой его, то соответственно на это время приложение перестанет отвечать на действия пользователя. Поэтому, наверное, имеет смысл в случаи длительных операций запускать их в отдельном потоке, что позволит использовать координаты из структуры MSG.
     
  16. Semiono

    Semiono Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2005
    Сообщения:
    785
    25,26 можно?
    Пожалуста "Простой битмэп" и "Сплэш-экран" зделайте? Здесь же для фасм тутры?
     
  17. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    для MASM, FASM, NASM, GoAsm
    Завтра сброшу "Простой битмэп" и "Сплэш-экран" на MASM
     
  18. Semiono

    Semiono Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2005
    Сообщения:
    785
    Mikl___, Спасибо!
    В дистрибутиве m32v10r.zip тоже есть подобные примеры
    masm32/examples/exampl02: showbmp, splash
    не знаю есть ли различие от Iczelion'а, просто может тоже быть полезным?

    PROTO - меня сразу же убило, что с ним делать я не осилю :)
    лучше подожду.
     
  19. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    Semiono Лови #26 на masm (сорц, ехе и картинка)
     
  20. Semiono

    Semiono Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2005
    Сообщения:
    785
    Mikl___, извини, но масм? Он же в туторах Zелона есть, хотя да у тебяж он оптимизированный наверно. Но fasm тоже жду.
    Сразу заодно спрошу... А GIF вообще не поддерживается в клиентскую область окна и вообще как ресурс? В том плане чтоб анимированный расунок подгрузить? Или это можно показом разных битмэпов изобразить средствами асма?