[تمرين] : عمل محاكاة للدالة rgb
#21
شيئ آخر أخي ALmuhhnad الدالة MakeRGB .. تعمل على 32 بت فقط !!!
ان كنت تمتلك نظام 64 بت , فجرب أن تقوم بتحويلها .
الرد
#22
هههه .. عذراً على عدم تركيزي ... فانا ابرمج برنامج الآن P:

PHP كود :
function MakeRGB(R,G,B : Byte):Cardinal ;
begin
  Result 
:= B * $10000;
  
asm
    MOV EAX
,0
    MOV EAX
,Result
    MOV AH
,G
    MOV AL
,R
    MOV Result
,EAX
  end
;
end;

function 
GetRValue_T(RGB : Cardinal):Byte ;
begin
  asm
    MOV EAX
,RGB
    MOV Result
,AL
  end
;
end;

function 
GetGValue_T(RGB : Cardinal):Byte ;
begin
  asm
    MOV EAX
,RGB
    MOV Result
,AH
  end
;
end;

function 
GetBValue_T(RGB : Cardinal):Byte ;
begin
  Result 
:= RGB div $10000;
end; 

حل آخر لـ MakeRGB
PHP كود :
function MakeRGB(R,G,B : Byte):Cardinal ;
begin
  asm
    MOV EAX
,0
    MOV AL
,B
    MOV ECX
,$10000
    MUL EAX
,ECX
    MOV AL
,G
    MOV CX
,$100
    MUL AX
,CX
    MOV AL
,R
    MOV Result
,EAX
  end
;
end; 

أعتقدت ان هناك طريقة لتصغير كود الاسمبلي ... فانا لم اكتب دوال اسمبلي من قبل P:
لذلك لم اعرف ان البار متراات تتوجه إلى المسجلات تلقائياً ... او بعمنى اصح لا اعرف اي المسجل يحتوب R او G أو B

شكراً على التعديل Smile
------

إقتباس :شيئ آخر أخي ALmuhhnad الدالة MakeRGB .. تعمل على 32 بت فقط !!!
ان كنت تمتلك نظام 64 بت , فجرب أن تقوم بتحويلها .
لا للاسف لا املك ... اضن ذلك يرجع لإختلاف الاوامر او سعة المسجلات في 64
الرد
#23
إقتباس :أعتقدت ان هناك طريقة لتصغير كود الاسمبلي ... فانا لم اكتب دوال اسمبلي من قبل P:
لذلك لم اعرف ان البار متراات تتوجه إلى المسجلات تلقائياً ... او بعمنى اصح لا اعرف اي المسجل يحتوب R او G أو B
[COLOR="Navy"]السرعة غير مرتبطة بطول الكود .. ممكن تجد أن كود أطول لكنه أسرع من كود صغير
السرعة متعلقة بنوع التعليمات المستعملة
على سبيل المثال تعليمة div تعتبر من أبطئ التعليمات على الاطلاق و لا ينصح باستخدامها في Loop الكبيرة ..
هل تعلم أن الدالة :
PHP كود :
function GetBValueX(RGB:Cardinal):Byte;
begin
  result
:= RGB div $10000;
end; 
أبطئ بحوالي 15 مرة من الدالة العادية GetBValue الخاصة بدلفي !!!

تجربة على السريع :
PHP كود :
var
 
a,b:dword;
 
i:integer;
 
c,c2:TColor;
 
n:byte;
begin
 c
:=RGB(23,180,190);
 
a:= GetTickCount ;
 for 
I := 0 to 100000000 do
n:= GetBValueX(c);
// n:= GetBValue(c);
 
b:=GetTickCount - a;
 
Caption :=   IntToStr(b);

end; 
إقتباس :لذلك لم اعرف ان البار متراات تتوجه إلى المسجلات تلقائياً ... او بعمنى اصح لا اعرف اي المسجل يحتوب R او G أو B
لا , لا تدفع تلقائيا ... هذا على حسب ال calling convention المستعملة مع الدالة
ال calling convention الافتراضية لدلفي هي register و لهذا يتم تمرير البرامتر داخل eax ثم edx ثم ecx على التوالي ..
ألق نظرة على pascal calling convention (البرامتر يتم دفعها في المكدس و ليس الرجيستر)
PHP كود :
function MakeRGB(R,G,B : Byte):Cardinal ;pascal;
 
asm
     MOV CH
,AL  // AL <>  R
     
XOR EAX,EAX
     MOV  AL
,CL // CL <> B
     
IMUL EAX,$10000
     MOV AH
,DL // DL <> G
     
MOV AL,CH
 end
; 

[/COLOR]
الرد
#24
إقتباس : اضن ذلك يرجع لإختلاف الاوامر او سعة المسجلات في 64
التعليمات لا تختلف كثيرا ...
الاختلاف في سعة المسجلات و عددها + في ال calling convention الافتراضية ب 64 بت (fastcall)
ملاحظة : في بيئة 64 بت لا يمكن تغيير calling convention على غرار ال 32 بت
الرد
#25
معلومة جديدة حول التعليمة div ...

حاولت استعمال الضرب ( ثابت بـ مسجل مع التعليمة MUL ) ... ولم انجح لذلك اتخذت ذلك الشكل بالكود ...
ولم يطر على بالي التعليمة IMUL ... وذلك يرجع لعدم ممارستي اوامر التجميع ^^" ..إلخ

هذا حل آخر على MakeRGB
PHP كود :
function MakeRGB(R,G,B : Byte):Cardinal;
asm
  MOV BYTE PTR DS
:[Result],AL
  MOV BYTE PTR DS
:[Result+1],DL
  MOV BYTE PTR DS
:[Result+2],CL
end
; 

وتستتطيع تبيق هذه الطريقة على بقية الدوال GetRValue,GetBValue,GetGValue Smile
الرد
#26
ALmuhhnad كتب :هذا حل آخر على MakeRGB
[COLOR="Indigo"]عمل جد رائع ...
هذه أحسن دالة تم وضعها لحد الآن Smile
لكن انتبه حجم Cardinal /COLORREF= 4bytes [/COLOR]
PHP كود :
function MakeRGB(R,G,B : Byte):Cardinal;
asm
  MOV BYTE PTR DS
:[Result],AL
  MOV BYTE PTR DS
:[Result+1],DL
  MOV BYTE PTR DS
:[Result+2],CL
  MOV BYTE PTR DS
:[Result+3],$00
end
; 
الرد
#27
إقتباس :وتستتطيع تبيق هذه الطريقة على بقية الدوال GetRValue,GetBValue,GetGValue Smile
لم أنتبه لهذا..
لا , غير ممكن الا اذا أرسلت RGB كمؤشر Pointer , أو من خلال استخدام المكدس
الرد
#28
PHP كود :
function GetRValueX(RGB : Cardinal):Byte;
asm
  MOV BYTE PTR DS
:[Result],AL
end
;

function 
GetGValueX(RGB : Cardinal):Byte;
asm
  MOV BYTE PTR DS
:[Result],AH
end
;

function 
GetBValueX(RGB : Cardinal):Byte;
asm
  PUSH EAX
  MOV CL
,BYTE PTR DS:[ESP+2]
  
POP EAX
  MOV AL
,CL
end
; 

الخاصة بـ B هي التي تحتاج المكدس والمؤشرات Smile
الرد
#29
إقتباس :[COLOR="Red"]الخاصة بـ B هي التي تحتاج المكدس والمؤشرات Smile
[/COLOR]

[COLOR="Purple"]و هل الطريقتين متماثلتان ؟
طبعا لا .. الحالة الأولى : تعاملنا مع ال Result على أساس مصفوفة
أما الثانية : تعاملنا مع ال Result على أساس بايت
هل اتضحت الصورة ؟[/COLOR]

لماذا قمت بوضع قيمة AL في ال Result ؟
بعد أن تتم عملية ال link للدالة GetRValueX .. نحصل على :
كود :
MOV BYTE PTR DS:[Result],AL mov al,[ebp-$01]
لاحظ أنك أضفت تعليمة زائدة (يمكن الاستغناء عنها )

PHP كود :
function GetRValueX(RGB : Cardinal):Byte;
asm
 
{Do Nothing !!!}
end;
function 
GetGValueX(RGB : Cardinal):Byte;
asm
 MOV AL
,AH
end
; 

عند تعاملك مع الأسمبلي .. انسى كل قواعد الباسكال (قم بحذف مصطلح Result من الدالة )
بالنسبة للدالة :
كود :
function GetBValueX(RGB : Cardinal):Byte; asm PUSH EAX MOV CL,BYTE PTR DS:[ESP+2] POP EAX MOV AL,CL end;
يجب أن تقوم باسترجاع قيمة أي مسجل غير مستخدم في البرامتر للدالة .. حتى لا تحدث أي مشاكل
قم بحفظ قيمة المسجل ECX ثم في النهاية قم باسترجاعها ..
قد لا تظهر لك رسائل الخطأ في بعض الأحيان بسبب أن المسجل غير مستعمل من الكود الذي قبله أو الذي بعده .. لكن كن متيقنا أنك ستصادف رسائل خطأ بسبب عدم استرجاع قيمة المسجل المستخدم
الرد
#30
ما شاء الله.. معلم كما عدهتك اخي المبرمج SMP3 ...
وشكراً لك على النصائح والمعلومات القيمة ...
طريقة كتابة دالتين :
PHP كود :
function GetRValueX(RGB : Cardinal):Byte;
asm
 
{Do Nothing !!!}
end;
function 
GetGValueX(RGB : Cardinal):Byte;
asm
 MOV AL
,AH
end
; 

مبهرة بحق ... لم افكر بها ... ما شاء الله عليك

هذا تصحيح لما كتبت في GetBValueX
PHP كود :
function GetBValueX(RGB : Cardinal):Byte;
asm
  PUSH EAX
  PUSH ECX
  MOV CL
,BYTE PTR DS:[ESP+6]
  
MOV BYTE PTR DS:[ESP+4],CL
  POP ECX
  POP EAX
end
; 
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم