Вопрос по организации кода

Тема в разделе "WASM.ASSEMBLER", создана пользователем DuXeN0N, 12 ноя 2009.

  1. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    Делаю свой текстовый редактор и столкнулся с такой проблемой:

    Код (Text):
    1. proc WindowProc hwnd,wmsg,wparam,lparam
    2.   push ebx esi edi
    3.         cmp     [wmsg],WM_CREATE
    4.         je      .wmcreate
    5.         cmp     [wmsg],WM_SETFOCUS
    6.         je      .wmsetfocus
    7.         cmp     [wmsg],WM_COMMAND
    8.         je      .wmcommand
    9.         cmp     [wmsg],WM_CLOSE
    10.         je      .wmclose
    11.         cmp     [wmsg],WM_DESTROY
    12.         je      .wmdestroy
    13.   .defwndproc:
    14.         invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    15.         jmp     .finish
    16.   .wmcreate:
    17.         invoke GetClientRect,[hwnd],client
    18.         invoke CreateWindowEx,WS_EX_CLIENTEDGE,cEdit,0,WS_VISIBLE+WS_CHILD+ES_MULTILINE+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL,[client.left],[client.top],[client.right],[client.bottom],[hwnd],1000,[wc.hInstance],0
    19.         cmp eax,0
    20.         je .failed
    21.         mov [hEdit],eax
    22.         invoke SendMessage,[hEdit],EM_LIMITTEXT,MEMSIZE-1,0
    23.         invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,RUSSIAN_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,fontname
    24.         cmp eax,0
    25.         je .failed
    26.         invoke SendMessage,[hEdit],WM_SETFONT,eax,TRUE
    27.         xor eax,eax
    28.         jmp .finish
    29.         .failed:
    30.         mov eax,-1
    31.         jmp .finish
    32.   .wmsetfocus:
    33.         invoke SetFocus,[hEdit]
    34.         xor eax,eax
    35.         jmp .finish
    36.   .wmclose:
    37.         jmp .finish
    38.   .wmcommand:
    39.         mov     eax,[wparam]
    40.         cmp     ax,IDM_NEW
    41.         je      .NEW
    42.        ; Menu 'Edit'
    43.         cmp     ax,IDM_UNDO
    44.         je      .UNDO
    45.         cmp     ax,IDM_CUT
    46.         je      .CUT
    47.         cmp     ax,IDM_COPY
    48.         je      .COPY
    49.         cmp     ax,IDM_PASTE
    50.         je      .PASTE
    51.         jmp     .finish
    52.   .NEW:
    53.     invoke SendMessage,[hEdit],EM_GETMODIFY,0,0
    54.         cmp eax,0
    55.         je clear
    56.         invoke MessageBox,[hwnd],savefileq,qtitle,MB_YESNOCANCEL
    57.         cmp eax,IDYES
    58.         je save_file
    59.         cmp eax,IDNO
    60.         je close
    61.         cmp eax,IDCANCEL
    62.         je finish
    63.         clear:
    64.         invoke SendMessage,[hEdit],WM_SETTEXT,0,0
    65.  
    66.       save_file:
    67.          mov [ofn.Flags],OFN_EXPLORER+OFN_OVERWRITEPROMPT
    68.          invoke GetSaveFileName,ofn
    69.          cmp eax,0
    70.          je .finish
    71.          invoke CreateFile,filename,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
    72.          mov [hFile],eax
    73.          invoke GetProcessHeap
    74.          mov [hHeap],eax
    75.          invoke HeapAlloc,[hHeap],HEAP_ZERO_MEMORY,MEMSIZE
    76.          mov [pMem],eax
    77.          invoke SendMessage,[hEdit],WM_GETTEXT,MEMSIZE,[pMem]
    78.          invoke lstrlen,[pMem]
    79.          invoke WriteFile,[hFile],[pMem],eax,sBuf,0
    80.          mov [filesaved],1
    81.          invoke SendMessage,[hEdit],EM_SETMODIFY,0,0
    82.          invoke HeapFree,[hHeap],0,[pMem]
    83.          invoke CloseHandle,[hFile]
    84.  
    85.         close:
    86.         invoke ExitProcess,0
    87.  
    88.         finish:
    89.         ret
    90.  
    91.  
    92.         jmp .finish
    93.  
    94.  
    95.    .UNDO:
    96.         invoke SendMessage,[hEdit],EM_UNDO,0,0
    97.         jmp .finish
    98.   .CUT:
    99.         invoke SendMessage,[hEdit],WM_CUT,0,0
    100.         jmp .finish
    101.   .COPY:
    102.         invoke SendMessage,[hEdit],WM_COPY,0,0
    103.         jmp .finish
    104.   .PASTE:
    105.         invoke SendMessage,[hEdit],WM_PASTE,0,0
    106.         jmp .finish
    107.    .wmdestroy:
    108.         invoke  PostQuitMessage,0
    109.         xor     eax,eax
    110.   .finish:
    111.         pop     edi esi ebx
    112.         ret
    113. endp
    при компиляции выдает сообщение:

    undefined symbol в строках:

    cmp [wmsg],WM_DESTROY
    je .wmdestroy <-----вот тут

    Получается что он не видит .wmdestroy хотя он есть. как правильнее организовать код?
     
  2. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    может быть можно вынести save_file в отдельную процедуру, чтобы я потом мог
    cmp eax,0
    call save_file

    просто я не знаю пока точно как работать с cmp и как можно вызвать проуедуру после сравнения
     
  3. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.622
    Адрес:
    Russia
    начинать метку с точки или другого символа-разделителя верный путь получить грабли
    оставте точку для полей стуктур
     
  4. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    DuXeN0N
    1) Лучше cmp eax,0 заменить на test eax,eax и быстрее и байт меньше занимает
    2) процедура начинается с push ebx,esi,edi и заканчивается pop edi, esi, ebx хотя в самой процедуре edi, esi, ebx не используются
    3) invoke SendMessage,[hEdit],WM_SETFONT,eax,TRUE / xor eax,eax
    invoke SetFocus,[hEdit]/ xor eax,eax
    invoke PostQuitMessage,0 / xor eax,eax
    попробуйте закоментировать xor eax,eax программа от этого хуже работать не будет
    4) вместо invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] / jmp .finish
    поставте просто jmp DefWindowProc дело в том, что WindowProc имеет теже самые параметры что и DefWindowProc
    а про оптимизацию почитайте Сам себе Iczelion
     
  5. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    спасибо огромное!

    Mikl___:
    вот это заменил:

    Код (Text):
    1. invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    2. jmp     finish
    на jmp DefWindowProc и программа вылетает при запуске. убрал push ebx,esi,edi и pop. а почему в обычном шаблоне у FASM (называется Template) там есть

    proc WindowProc uses ebx esi edi hwnd,wmsg,wparam,lparam или что то вроде этого. и еще хотел спросить-чем отличается ret от retn?
     
  6. asmdev

    asmdev New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2006
    Сообщения:
    12
    Метки с точкои (.wmdestroy) принадлежат к меткам без точек(WindowProc).
    Тоесть ты можешь написать "je WindowProc.wmdestroy." Но у тебя в коде есть метка "save_file:" а потом и "finish:". Они перекрывают WindowProc и тебе надо писать "je finish.wmdestroy".

    Лучше разнести весь код по разным процедурам
     
  7. asmdev

    asmdev New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2006
    Сообщения:
    12
    ret - 1 байт, retn - 2 байта. retn рекомендуется использовать для увеличения скорости если процедура вызывается часто. Самое главное что у retn есть дополнительний операнд. Можно написат "retn 0" или "retn 16". Число будет добавлено к esp
     
  8. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    огромное спасибо. и еще 2 вопроса.

    в чем разница между call и stdcall

    и как после сравнения вызвать процедуру?
    например

    test eax,eax
    jz rprp

    proc rprp
    ///
    endp

    так? как ее можно вызвать? если например eax=0 то одна, если 1 то другая
     
  9. 00h

    00h New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    27
    call - инстукция вызова, stdcall - договореность и порядке передачи аргументов в процедуру
     
  10. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    DuXeN0N, в макросе proc фасма ret – это макрос, который убирает за собой мусор (восстанавливает регистры, стековый кадр и т. п., и в конце делает retn x, причём сколько x будет, вычисляет сам), retn же – обычная ассемблерная инструкция. Повторюсь, разница только внутри proc.
    Вне proc между retn и ret разницы нет. Двухбайтовый вариант генерируется с аргументом (retn 0x20 или ret 4, например), без аргумента (retn или ret) – однобайтовый.
     
  11. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Блин, трёхбайтовый, верните редактирование.
     
  12. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    DuXeN0N
    поставь leave / jmp DefWindowProc
     
  13. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    Что за бред? ret это макрос, результат которого подставит компилятор в зависимости от типа процедуры (near, far) и в зависимости от того, нужно или нет убирать параметры переданные процедуре
    код команды retn без параметров 0C3h - длина 1 байт
    код retn XX -- 0С2h XX - длина 3 байта
    код retf без параметров -- 0CBh - длина 1 байт
    код retf XX -- 0CAh XX - длина 3 байта
     
  14. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    Mikl___, поставил. также вылетает
     
  15. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    Mikl___,

    Код (Text):
    1. cmp eax,IDYES
    2. je save_file
    3. cmp eax,IDNO
    4. je close
    5. cmp eax,IDCANCEL
    6. je nothing
    это можно упростить как-нибудь?
     
  16. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    1) Написать макрос case или найти готовый.
    2) Не писать на ассемблере
     
  17. 00h

    00h New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    27
    если много сравнений - делать jump table
     
  18. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    напиши код в VC - он сам тебе соптимизирует и test eax, eax и все джампы. вообще писать гую на асме занятие неблагодарное. switch - case и работать будет быстрее чем cmp, je (в некоторых случаях), и код будет читаемей.
     
  19. DuXeN0N

    DuXeN0N New Member

    Публикаций:
    0
    Регистрация:
    2 май 2009
    Сообщения:
    46
    я уже упростил. убрал третье сравнение
    получилось так:

    Код (Text):
    1. cmp eax,IDNO
    2. je clear
    3. cmp eax,IDCANCEL
    4. je finish
    5. call SaveFile            
    6. jmp finish
     
  20. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    У меня профессиональный интерес -- во что, кроме cmp/je превращается switch - case в VC и за счет чего он будет быстрее работать? Приведите пример, пожалуйста, заодно сравните с вариантами switch - case в Сам себе Iczelion Просто очень интересно...