Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.25;
Скачать: CL | DM;

Вниз

Assembler - NOT с регистром   Найти похожие ветки 

 
cyborg ©   (2003-09-06 20:38) [0]

Подскажите пожалуйста, чего-то никак не найду выход :(
Нужно сделать подобие булёвского NOT.
Если регистр не ноль, то обнулить, если ноль, то регистр = 1;
Как это сделать быстро?


 
NightAngel ©   (2003-09-06 22:41) [1]

Так?

asm
test eax, eax // if eax!=0
jz @1
xor eax, eax // then eax==0
jmp @2
@1:
inc al // else eax==1
@2:
end;


 
cyborg ©   (2003-09-06 23:25) [2]

Заинтересовался ассамблером, ММХ смотрю, чего-то функция никак не получится у меня по расчёту столкновений прямоугольников:


Function Collision(Rect1,Rect2 : PRect) : LongBool; assembler;
{
Result := (2X2 > 1X1) and
(2Y2 > 1Y1) and
(1X2 > 2X1) and
(1Y2 > 2Y1);
}
asm
movq mm1,[edx]; //Rect1 X1Y1
movq mm2,[edx+$08]; //Rect1 X2Y2
movq mm3,[ecx]; //Rect2 X1Y1
movq mm4,[ecx+$08]; //Rect2 X2Y2

pcmpgtd mm4,mm1; //(2X2 > 1X1) and (2Y2 > 1Y1)
pcmpgtd mm3,mm2; //(1X2 > 2X1) and (1Y2 > 2Y1)

pxor mm5,mm5; //Обнуление регистра mm5
pand mm3,mm4; //Если выполнилось условие что больше, то mm3 будет не ноль.

pcmpeqd mm3,mm5 //Если ноль, то = 1, нет = 0
movd eax,mm3;
psrlq mm3,32;
movd edx,mm3;
or eax,edx;
emms;
end;


Чего-то криво работает :), толи формула неправильная столкновения прямоугольника, толи инструкции не так делаю, помогите пожалуйста.


 
cyborg ©   (2003-09-07 11:50) [3]

Странно, чего-то не то :)


function GetCPUTick: int64; assembler; //Получить значение счётчика тактов процессора
asm
db 0fh,31h; //rdtsc
end;

Function Collision(Rect1,Rect2 : PRect) : LongBool;
begin
{$B-}
Result := (Rect2.Right > Rect1.Left) and
(Rect2.Bottom > Rect1.Top) and
(Rect1.Right > Rect2.Left) and
(Rect1.Bottom > Rect2.Top);
end;
Function CollisionMMX(Rect1,Rect2 : PRect) : LongBool; assembler;
{
Result := (2X2 > 1X1) and
(2Y2 > 1Y1) and
(1X2 > 2X1) and
(1Y2 > 2Y1);
}
asm
movq mm1,[edx]; //Rect1 X1Y1
movq mm2,[edx+$08]; //Rect1 X2Y2
movq mm3,[eax]; //Rect2 X1Y1
movq mm4,[eax+$08]; //Rect2 X2Y2

pcmpgtd mm4,mm1; //(2X2 > 1X1) and (2Y2 > 1Y1)
pcmpgtd mm2,mm3; //(1X2 > 2X1) and (1Y2 > 2Y1)

pxor mm5,mm5; //Обнуление регистра mm5
pand mm2,mm4; //Если выполнилось условие, что больше, то mm2 будет не ноль.

pcmpeqd mm2,mm5 //Если ноль, то = 1, нет = 0

movd eax,mm2;
psrlq mm2,32;
movd edx,mm2;
emms;
or eax,edx;
end;
procedure TForm1.Button1Click(Sender: TObject);
Var
Time1,Time2 : Int64;
I : Integer;
B : LongBool;
PriorityClass, Priority: Integer;
begin
r1.Left:=SpinEdit1.Value;
r1.Top:=SpinEdit2.Value;
r1.Right:=SpinEdit3.Value;
r1.Bottom:=SpinEdit4.Value;

r2.Left:=SpinEdit5.Value;
r2.Top:=SpinEdit6.Value;
r2.Right:=SpinEdit7.Value;
r2.Bottom:=SpinEdit8.Value;
if CollisionMMX(@R1,@R2) then caption:="Есть столкновение!" else caption:="Нет столкновения!";

PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);

Time1:=GetCPUTick;
For I:=1 to 1000000 do B:=Collision(@R1,@R2);
Time2:=GetCPUTick;
показывает 11 тиков процессора на исполнение
Label5.Caption:=IntToStr((Time2-Time1) div 1000000);

Time1:=GetCPUTick;
For I:=1 to 1000000 do B:=CollisionMMX(@R1,@R2);
Time2:=GetCPUTick;
показывает 2 тика процессора на исполнение (???) странно, не может быть!
Label6.Caption:=IntToStr((Time2-Time1) div 1000000);

Time1:=GetCPUTick;
For I:=1 to 1000000 do
begin
B:=(R2.Right > R1.Left) and
(R2.Bottom > R1.Top) and
(R1.Right > R2.Left) and
(R1.Bottom > R2.Top);
end;
Time2:=GetCPUTick;
показывает 12 тиков процессора на исполнение, почему-то дольше, чем вызов функции!!!
Label7.Caption:=IntToStr((Time2-Time1) div 1000000);

SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);

end;


И всё равно неправильно определяет столкновение :(.


 
cyborg ©   (2003-09-07 12:25) [4]

Вроде сделал :), работает в 6 раз быстрее, чем паскалевская функция, на моём Дурике 800 функция выполняется 2 такта процессора :).

Function CollisionMMX(Rect1,Rect2 : PRect) : LongBool; assembler;
{ Result := (Rect2.Right > Rect1.Left) and
(Rect2.Bottom > Rect1.Top) and
(Rect1.Right > Rect2.Left) and
(Rect1.Bottom > Rect2.Top);}
asm
movq mm1,[edx]; //Rect1 X1Y1
movq mm2,[edx+$08]; //Rect1 X2Y2
movq mm3,[eax]; //Rect2 X1Y1
movq mm4,[eax+$08]; //Rect2 X2Y2

pcmpgtd mm4,mm1; //(2X2 > 1X1) and (2Y2 > 1Y1)
pcmpgtd mm2,mm3; //(1X2 > 2X1) and (1Y2 > 2Y1)

pand mm2,mm4; //Если выполнилось условие, что больше, то mm2 будет не ноль.
movd eax,mm2;
psrlq mm2,32;
movd edx,mm2;
emms;
or eax,edx;
end;


 
Anatoly Podgoretsky ©   (2003-09-07 12:28) [5]

ADD reg,-1
SBB reg,reg
inc reg


 
cyborg ©   (2003-09-07 12:43) [6]

Это куда? :)


 
cyborg ©   (2003-09-07 12:49) [7]

Ошибку нашёл
вместо or eax,edx;
нужно and eax,edx;


 
Anatoly Podgoretsky ©   (2003-09-07 12:56) [8]

Это сюда cyborg © (06.09.03 20:38)


 
cyborg ©   (2003-09-07 13:34) [9]

Понятно.
А со скоростью облом, я не туда смотрел :), наоборот ММХ самое долго выполняется :(, а 2 тика была обычное сравнение без функции.



Страницы: 1 вся ветка

Текущий архив: 2003.09.25;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.026 c
8-82339
dedushka
2003-06-01 21:00
2003.09.25
AVI


14-82447
Soft
2003-09-07 13:58
2003.09.25
Что такое ЗЛО?


3-82056
Рома
2003-09-02 20:09
2003.09.25
Подскажите чем можно интербес базу просмотреть?


14-82432
nick-from
2003-09-08 12:22
2003.09.25
Цифровой номер


1-82269
Sam Stone
2003-09-15 17:40
2003.09.25
FocusedNode