Принадлежит ли POINT в DWORD RECT

Тема в разделе "WASM.A&O", создана пользователем The Svin, 11 апр 2006.

  1. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    subj.

    POINT в DWORD термин подразумевает такие типы которые возвращаются например в lParam от LBUTTONDBLCLK и подобных. Т.е. где младший WORD x старший - y.

    Посмотрите, пожалуйста, нет ли идей сделать покороче чем получилось у меня.

    (NOTE: нижняя правая пара по определению RECT - граничная невключённая)
    Код (Text):
    1.  
    2. IfDwPtBelongsToRect proc dwPt,ptrRECT
    3.     mov eax,dwPt
    4.     mov edx,eax
    5.     and eax,0FFFFh ;eax=POINT.x
    6.     shr edx,16      ;edx=POINT.y
    7.     mov ecx,ptrRECT
    8.     assume ecx:ptr RECT
    9.     sub eax,[ecx].left
    10.     sub edx,[ecx].top
    11.     cmp eax,[ecx].right
    12.     sbb eax,eax
    13.     cmp edx,[ecx].bottom
    14.     sbb edx,edx
    15.     and eax,edx
    16. ;-1 if yes, 0 - no 
    17.     ret
    18.  
    19. IfDwPtBelongsToRect endp
    20.  
     
  2. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Обнаружил глупую ошибку, исправляю :)
     
  3. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Правильно как-то так, но так длиновато:
    Код (Text):
    1.  
    2. IfDwPtBelongsToRect proc uses ebx dwPt,ptrRECT
    3.     mov eax,dwPt
    4.     mov edx,eax
    5.     movzx eax,ax ;eax=POINT.x
    6.     shr edx,16      ;edx=POINT.y
    7.     mov ecx,ptrRECT
    8.     assume ecx:ptr RECT
    9.     mov ebx,[ecx].left
    10.     sub eax,ebx
    11.     sub ebx,[ecx].right
    12.     neg ebx
    13.     cmp eax,ebx
    14.     sbb eax,eax
    15.     mov ebx,[ecx].top  
    16.     sub edx,ebx
    17.     sub ebx,[ecx].bottom
    18.     neg ebx
    19.     cmp edx,ebx
    20.     sbb edx,edx
    21.     and eax,edx
    22. assume ecx:nothing
    23. ;-1 if yes, 0 - no 
    24.     ret
    25.  
    26. IfDwPtBelongsToRect endp
    27.  


    Исправил на movzx eax,ax
     
  4. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Да забыл сказать - код должен быть без ветвления.
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    The Svin



    Оптимизировать по размеру?



    Ну, я бы сразу заменил and eax,0FFFFh на movzx eax,ax.
     
  6. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Quantum

    Согласен.
     
  7. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Ещё короче придумал! Вместо этого:
    Код (Text):
    1. mov eax,dwPt
    2. mov edx,eax
    3. movzx eax,ax ;eax=POINT.x
    4. shr edx,16   ;edx=POINT.y


    Ставим это:
    Код (Text):
    1. movzx eax,word ptr [dwPt]
    2. movzx edx,word ptr [dwPt + 2]


    На 3 байта меньше.
     
  8. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Ага. И даже побыстрее должно быть.
     
  9. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Допёр! И как только с первого раза не увидел :))

    Кольца и стрелы рулят!
    Код (Text):
    1.  
    2. IfDwPtBelongsToRect proc uses ebx dwPt,ptrRECT
    3.     movzx eax,word ptr [dwPt]
    4.     movzx edx,word ptr [dwPt + 2]
    5.     mov ecx,ptrRECT
    6.     assume ecx:ptr RECT
    7.     mov ebx,[ecx].left
    8.     sub eax,ebx
    9.     sub ebx,[ecx].right
    10.     add eax,ebx
    11.     sbb eax,eax
    12.     mov ebx,[ecx].top  
    13.     sub edx,ebx
    14.     sub ebx,[ecx].bottom
    15.     add edx,ebx
    16.     sbb edx,edx
    17.     or eax,edx
    18. assume ecx:nothing
    19. ;0 if yes, -1 - no 
    20.     ret
    21.  
    22. IfDwPtBelongsToRect endp
    23.  
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Классический XOR знаков рулит не хуже ;)
    Код (Text):
    1. IfDwPtBelongsToRect proc uses ebx dwPt,ptrRECT
    2.   movzx eax,word ptr [dwPt]
    3.   movzx edx,word ptr [dwPtr+2]  
    4.   mov ecx,ptrRECT
    5. assume ecx:ptr RECT
    6.   mov ebx,eax
    7.   sub eax,[ecx].left
    8.   sub ebx,[ecx].right
    9.   xor ebx,eax
    10.   mov eax,edx
    11.   sub edx,[ecx].top
    12.   sub eax,[ecx].bottom
    13.   xor eax,edx
    14.   and eax,ebx
    15.   sar eax,31   ;можно cdq + mov eax,edx
    16. assume ecx:nothing
    17.   ;0 if no, -1 - yes   
    18.   ret          ;в масме я не спец, но ret тут видимо не нужен,
    19.                ;иначе можно потерять ebx в стеке ?
    20. IfDwPtBelongsToRect endp
    PS: на P4 латентность SBB 8 тиков
     
  11. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Теперь представь, например, что left=0 right=1

    а в eax=0 -> ebx=1

    sub eax,[ecx].left (0-0) -> Sbit = 0

    sub ebx,[ecx].right (1-1) -> Sbit = 0

    xor eax,ebx (Sbit(0) xor Sbit(0)) -> Sbit = 0



    Дальше уже не зависимо от того что было в edx на

    and eax,ebx (Sbit(?) and Sbit(0)=Sbit(0))

    в eax будет 0 хотя координата 0 принадлежит прямоугольнику

    с left = 0 и right = 1 т.е. с диапазоном по x [0,1) если и y принадлежит.
     
  12. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Ага, теперь правильно. Хороший вариант.

    Можно даже последнюю инструкцию убать (т.е. предпоследюю - SAR).

    Типа SF или не SF.

    ret - потому как процедура :) т.е. call вызывать.
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    > "ret - потому как процедура :)"

    С этими макросами одна путанница - пойди догадайся, что внутри объявления процедуры - RET это вовсе и не инструкция x86, а макрос с epilogue. Прям HLL какой-то долбаный...
     
  14. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia


    Тоже его не любишь? :)

    Там можно опции выключать. Я обычно само мясо пишу с обычными для MASM прологами эпилогами. Если всё работает - оптимизирую вход и выход отключая опции.
     
  15. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    leo

    retn приведёт к потере ebx и вызовет исключение. Из-за обной буквы страшная лажа может произойти :)