subj. POINT в DWORD термин подразумевает такие типы которые возвращаются например в lParam от LBUTTONDBLCLK и подобных. Т.е. где младший WORD x старший - y. Посмотрите, пожалуйста, нет ли идей сделать покороче чем получилось у меня. (NOTE: нижняя правая пара по определению RECT - граничная невключённая) Код (Text): IfDwPtBelongsToRect proc dwPt,ptrRECT mov eax,dwPt mov edx,eax and eax,0FFFFh ;eax=POINT.x shr edx,16 ;edx=POINT.y mov ecx,ptrRECT assume ecx:ptr RECT sub eax,[ecx].left sub edx,[ecx].top cmp eax,[ecx].right sbb eax,eax cmp edx,[ecx].bottom sbb edx,edx and eax,edx ;-1 if yes, 0 - no ret IfDwPtBelongsToRect endp
Правильно как-то так, но так длиновато: Код (Text): IfDwPtBelongsToRect proc uses ebx dwPt,ptrRECT mov eax,dwPt mov edx,eax movzx eax,ax ;eax=POINT.x shr edx,16 ;edx=POINT.y mov ecx,ptrRECT assume ecx:ptr RECT mov ebx,[ecx].left sub eax,ebx sub ebx,[ecx].right neg ebx cmp eax,ebx sbb eax,eax mov ebx,[ecx].top sub edx,ebx sub ebx,[ecx].bottom neg ebx cmp edx,ebx sbb edx,edx and eax,edx assume ecx:nothing ;-1 if yes, 0 - no ret IfDwPtBelongsToRect endp Исправил на movzx eax,ax
Ещё короче придумал! Вместо этого: Код (Text): mov eax,dwPt mov edx,eax movzx eax,ax ;eax=POINT.x shr edx,16 ;edx=POINT.y Ставим это: Код (Text): movzx eax,word ptr [dwPt] movzx edx,word ptr [dwPt + 2] На 3 байта меньше.
Допёр! И как только с первого раза не увидел ) Кольца и стрелы рулят! Код (Text): IfDwPtBelongsToRect proc uses ebx dwPt,ptrRECT movzx eax,word ptr [dwPt] movzx edx,word ptr [dwPt + 2] mov ecx,ptrRECT assume ecx:ptr RECT mov ebx,[ecx].left sub eax,ebx sub ebx,[ecx].right add eax,ebx sbb eax,eax mov ebx,[ecx].top sub edx,ebx sub ebx,[ecx].bottom add edx,ebx sbb edx,edx or eax,edx assume ecx:nothing ;0 if yes, -1 - no ret IfDwPtBelongsToRect endp
Классический XOR знаков рулит не хуже Код (Text): IfDwPtBelongsToRect proc uses ebx dwPt,ptrRECT movzx eax,word ptr [dwPt] movzx edx,word ptr [dwPtr+2] mov ecx,ptrRECT assume ecx:ptr RECT mov ebx,eax sub eax,[ecx].left sub ebx,[ecx].right xor ebx,eax mov eax,edx sub edx,[ecx].top sub eax,[ecx].bottom xor eax,edx and eax,ebx sar eax,31 ;можно cdq + mov eax,edx assume ecx:nothing ;0 if no, -1 - yes ret ;в масме я не спец, но ret тут видимо не нужен, ;иначе можно потерять ebx в стеке ? IfDwPtBelongsToRect endp PS: на P4 латентность SBB 8 тиков
Теперь представь, например, что 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 принадлежит.
Ага, теперь правильно. Хороший вариант. Можно даже последнюю инструкцию убать (т.е. предпоследюю - SAR). Типа SF или не SF. ret - потому как процедура т.е. call вызывать.
> "ret - потому как процедура " С этими макросами одна путанница - пойди догадайся, что внутри объявления процедуры - RET это вовсе и не инструкция x86, а макрос с epilogue. Прям HLL какой-то долбаный...
Тоже его не любишь? Там можно опции выключать. Я обычно само мясо пишу с обычными для MASM прологами эпилогами. Если всё работает - оптимизирую вход и выход отключая опции.