x86

  • كيفية تمرير المعاملات في لغة التجميع x86

    In x86 assembly language, parameters are typically passed on the stack. However, in your example code, the parameter is not being passed correctly. Let’s correct the code to pass the parameter 0x08 to my_function using the stack:

    assembly
    section .text global _start ; Function to demonstrate passing parameters my_function: ; Retrieve the parameter from the stack pop eax ; Your function code here, using the parameter in eax ; For example, you can print the parameter value ; using the sys_write syscall mov ebx, eax ; Move the parameter to ebx for syscall mov eax, 4 ; sys_write syscall number mov ecx, esp ; The address of the string to write (if applicable) mov edx, 1 ; Length of the string (if applicable) int 0x80 ; Call kernel ret ; Return from function _start: ; Push the parameter onto the stack push dword 0x08 ; Call the function call my_function ; Exit the program mov eax, 1 ; sys_exit syscall number xor ebx, ebx ; Exit code 0 int 0x80 ; Call kernel

    In this corrected code, the push dword 0x08 instruction pushes the parameter onto the stack before calling my_function. Inside my_function, the pop eax instruction retrieves the parameter from the stack into the eax register for use in the function.

    المزيد من المعلومات

    في لغة التجميع x86، يمكن تمرير المعاملات إما عبر السجلات أو عبر الذاكرة المؤقتة (الستاك). في المثال الذي قدمته، كنت تحاول تمرير المعلمة عبر الستاك، ولكن كودك لم يكن صحيحًا. لتصحيح الكود وتمرير المعلمة بنجاح عبر الستاك، يجب عليك القيام بالخطوات التالية:

    1. استخدام تعليمة push لوضع قيمة المعلمة على الستاك قبل استدعاء الدالة.
    2. داخل الدالة، يمكنك استخدام تعليمة pop لاستخراج قيمة المعلمة من الستاك وتخزينها في السجل المناسب للاستخدام داخل الدالة.

    الكود المعدل يبدو كما يلي:

    assembly
    section .text global _start ; دالة لطباعة قيمة المعلمة my_function: ; استخراج المعلمة من الستاك pop eax ; استخدام قيمة المعلمة في عملية ما ; على سبيل المثال، يمكنك استخدام المعلمة في تحديد ما إذا كان العدد يقبل القسمة على 2 test eax, 1 ; اختبار عدم التماثل لتحديد ما إذا كان العدد فرديًا أو زوجيًا jz even ; قفز إلى even إذا كان العدد زوجيًا ; إذا كان العدد فرديًا، قم بطباعة رسالة mov ebx, 1 ; معلمة للطباعة عبر النظام mov eax, 4 ; رقم استدعاء النظام للطباعة mov ecx, msg_odd ; عنوان الرسالة للطباعة mov edx, len_msg_odd ; طول الرسالة int 0x80 ; استدعاء النظام jmp end_prog ; الانتقال إلى نهاية البرنامج even: ; إذا كان العدد زوجيًا، قم بطباعة رسالة mov ebx, 1 ; معلمة للطباعة عبر النظام mov eax, 4 ; رقم استدعاء النظام للطباعة mov ecx, msg_even ; عنوان الرسالة للطباعة mov edx, len_msg_even; طول الرسالة int 0x80 ; استدعاء النظام end_prog: ret _start: ; ضع قيمة المعلمة (على سبيل المثال، 5) على الستاك push 5 ; ادع الدالة لتحليل المعلمة وطباعة رسالة وفقًا للنتيجة call my_function ; اخرج من البرنامج mov eax, 1 ; رقم استدعاء النظام للخروج من البرنامج xor ebx, ebx ; كود خروج 0 int 0x80 ; استدعاء النظام

    في هذا المثال، يتم وضع المعلمة (العدد 5 في هذه الحالة) على الستاك باستخدام push قبل استدعاء الدالة. داخل الدالة my_function، يتم استخراج قيمة المعلمة من الستاك باستخدام pop وتخزينها في السجل eax للاستخدام في الدالة.

  • تحويل الشيفرة الثنائية إلى لغة التجميع: تحليل وفهم عميق لملفات ELF

    في عالم برمجة الحاسوب وتحليل البرامج، يعد تحويل التعليمات الثنائية أو الشيفرة الآلية إلى لغة التجميع أو الأوامر البشرية قائمة على مفتاح أساسي لفهم وتحليل التنفيذ البرمجي للبرنامج. في مشروعك لتطوير disassembler الخاص بك، تواجه التحدي الرئيسي في تحويل التعليمات الثنائية التي استخرجتها من ملف ELF بواسطة مترجم GCC إلى سلسلة من تعليمات التجميع أو mnemonics.

    أولاً وقبل أن تستمع في تحويل الشيفرة الثنائية إلى لغة التجميع، يجب أن تفهم بعناية بنية الملف ELF. يتيح لك ذلك فحص العناصر المختلفة مثل الهيدر (Header) والأقسام (Sections)، مما يساعدك في تحديد المكان الذي يحتوي على الشيفرة الثنائية المرغوبة، وهي عادة موجودة في قسم “.text”.

    بمجرد استخراج الشيفرة الثنائية، يمكنك البدء في تحويلها إلى mnemonics. هنا يدخل لغة التجميع والمجموعة الواسعة من التعليمات التي قد تشمل الحسابات الحسابية، النقل بين السجلات، والفروع الشرطية.

    عند تحليل الشيفرة الثنائية التي قدمتها، يبدو أنك تستخدم تعليمات x86 أو x86_64 بناءً على القيم المستخدمة. على سبيل المثال، تعليمة “55” تمثل “PUSH EBP” في لغة التجميع x86، وهكذا.

    لتحويل الشيفرة الثنائية إلى لغة التجميع، يمكنك الاعتماد على جداول الترميز (opcode tables) المتاحة لهياكل المعالج المختلفة. يتضمن ذلك فهم الترميز الثنائي لكل تعليمة والمتغيرات الممكنة لكل تعليمة. يُفضل أيضاً استخدام مكتبات أو أدوات مساعدة لتبسيط عملية التحويل.

    في ختام الأمر، تطوير disassembler يعد تحديًا شيقًا ومعقدًا يتطلب فهماً عميقاً لبنية الملفات ولغات التجميع. إذا كنت تسعى لاستمرار تطوير مشروعك، يُفضل البحث عن المصادر والأدوات المفيدة في مجتمعات المطورين لتبادل الخبرات والتعلم المستمر.

    المزيد من المعلومات

    لتحويل الشيفرة الثنائية إلى لغة التجميع، يمكنك استخدام الجداول المرجعية المعروفة باسم جداول الترميز (opcode tables). تلك الجداول تحتوي على معلومات حول كيفية ترميز كل تعليمة والمتغيرات الممكنة لكل تعليمة. في حالة x86 أو x86_64، يمكن العثور على هذه الجداول في مراجع مثل “Intel® 64 and IA-32 Architectures Software Developer’s Manual”، حيث تقدم Intel توثيقًا شاملاً لبنية تعليمات معالجاتها.

    على سبيل المثال، تحمل الشيفرة الثنائية “55” تعليمة “PUSH EBP” في تعليمات x86. الرقم “55” يمثل كود التشفير لهذه التعليمة. بإجراء تحليل مستفيض للشيفرة الثنائية التي قدمتها، يمكنك تحديد التعليمات المختلفة وترجمتها إلى لغة التجميع المناسبة.

    التحليل يتطلب فهمًا عميقًا لتنسيق التعليمات وبنية المعالج، ويشمل تحديد الأكواد التي تمثل التعليمات المختلفة ومتابعة سير التنفيذ المتوقعة. يمكن أيضًا استخدام أدوات البرمجيات مثل IDA Pro أو Ghidra التي تقوم بفك تشفير البرامج وتحويل الشيفرة الثنائية إلى تجميع لغة.

    من المهم أن تعرف أن هذا العمل يتطلب مهارات عالية في مجال هندسة البرمجيات وعلوم الحاسوب، ويمكن أن يكون تحليل التعليمات الثنائية معقدًا ومطلوبًا لفحص العديد من العناصر في ملف ELF بالإضافة إلى الفهم العميق للتعليمات المستخدمة في مجموعة التعليمات المعنية.

  • تفصيل أمر INC في لغة التجميع x86

    في عالم لغة التجميع x86، يُستخدم الأمر INC لزيادة قيمة المسجل (register) بواحد. عندما تقوم بتنفيذ “mov ecx, 0” ثم “inc ecx”، سيقوم المسجل ECX بالزيادة بمقدار واحد. الآن، دعونا نفحص الأمور بتفصيل أكثر.

    في المثال الأول الذي قدمته “mov ecx, 0” ثم “inc ecx”، يعني أنك بدأت بتعيين قيمة 0 للمسجل ECX، وباستخدام INC، تقوم بزيادة قيمته بمقدار واحد. في هذه الحالة، يتم زيادة المسجل ECX بمقدار بايت واحد.

    أما في المثال الثاني الذي ذكرته، “esi” يحمل عنوانا في الذاكرة. إذا قمت بتنفيذ INC على ESI، سيقوم المسجل بزيادة قيمة العنوان في الذاكرة بمقدار بايت واحد.

    إذا كان لديك قيمة مختلفة للمسجل ECX، مثل “mov ecx, 5” ثم “inc ecx”، ستكون قيمة ECX النهائية تساوي 6، وهكذا.

    للتأكيد، في حالة استخدام INC على مسجل يحمل قيمة عنوان في الذاكرة، سيتم زيادة العنوان بمقدار بايت واحد.

    لذا، نعم، أنت على صواب. في الحالة الأولى، زيادة المسجل تكون بمقدار بايت واحد، وفي الحالة الثانية، زيادة المسجل الذي يحمل قيمة عنوان في الذاكرة تكون أيضًا بمقدار بايت واحد.

    المزيد من المعلومات

    بالطبع، دعوني أوسع مدى المعلومات حول أمر INC في لغة التجميع x86. في عالم التجميع، يُستخدم الأمر INC لزيادة قيمة المسجل بمقدار واحد. يمكن تطبيق هذا الأمر على مجموعة متنوعة من المسجلات، بما في ذلك المسجلات العامة مثل ECX و EAX.

    لفهم أفضل حول كيفية عمل INC، دعونا نلقي نظرة أعمق على الأمور. يمكن استخدام INC مع المسجلات الثنائية (الثنائية) والثلاثية (الثلاثية). على سبيل المثال، يمكنك تنفيذ INC AX لزيادة قيمة المسجل AX، ويمكنك أيضًا استخدام INC BX لزيادة قيمة المسجل BX.

    إذا قمت بتنفيذ INC على مسجل يحمل قيمة ثنائية، مثل AX أو BX، سيتم زيادة هذا المسجل بمقدار واحد بشكل مباشر. وفي حالة المسجلات الثلاثية، مثل ECX، سيتم زيادة القيمة بمقدار واحد.

    الآن، يجب أن نعرف أن INC لا يؤثر فقط على المسجلات العامة، بل يمكن أيضًا استخدامه مع المسجلات الخاصة، مثل المسجلات المؤشرية مثل ESI و EDI.

    عند استخدام INC مع مسجل يحمل قيمة عنوان في الذاكرة، مثل ESI، سيؤدي الأمر إلى زيادة قيمة العنوان الذي يشير إليه المسجل بمقدار بايت واحد. هذا يعني أن المسجل سيتحرك إلى العنوان التالي في الذاكرة.

    لختم المعلومات، يمثل INC جزءًا أساسيًا من لغة التجميع x86 ويُستخدم بشكل شائع في برمجة منخفضة المستوى، خاصة عند التعامل مع الذاكرة والتحكم في التدفق في البرامج.

  • تفاصيل بادئات التعليمات في معالجات x86

    في عالم معالجات الحاسوب وتصميمها، يشكل مصطلح “instruction prefixes” (بادئات التعليمات) جزءًا أساسيًا من الهندسة الداخلية للمعالجات الحديثة، خاصةً في سياق معالجات x86. يمكننا أن نفهم هذه البادئات على أنها تعديلات صغيرة أو توسيعات تضاف إلى التعليمات الأساسية للمعالج لتعديل سلوكها أو إعطائها خصائص إضافية.

    عندما نتحدث عن “instruction prefixes” في سياق معالجات x86، فإننا نشير إلى تلك العناصر الإضافية التي يمكن أن ترافق التعليمات الأساسية وتؤثر على كيفية تفسيرها وتنفيذها من قبل المعالج. يمكن أن تشمل هذه البادئات مختلف العناصر مثل حجم العملية (operand size)، حجم العنوان (address size)، الإشارة (segment)، التكرار (repeat)، القفل (lock)، والبادئات الخاصة بتوسيع المعالجات الحديثة مثل بادئات REX و XOP.

    في الفقرة التي قدمتها من كتاب Agner Fog، يتم التركيز على الأثر السلبي لإضافة عدد كبير من هذه البادئات على سرعة تفسير التعليمات. عندما يحتوي التعليمة على أربع إلى سبع بادئات، يتم تحميلها بتكلفة إضافية تتراوح بين 14 و 15 دورة ساعة للفك ترميزها، وهكذا. وهذا يشير إلى أنه يفضل عدم استخدام عدد كبير من البادئات، خاصةً إذا كانت تلك البادئات لا تضيف قيمة كبيرة للتعليمة.

    التساؤل الأخير يتعلق بالسبب الذي قد يجعلك تضيف 14 بادئة أو أكثر إلى تعليمة بدلاً من تقسيمها. يمكن أن يكون السبب وراء ذلك هو تحسين أداء التعليمة أو تحقيق وظائف محددة تتعلق بمتطلبات البرنامج. عمومًا، يتم التحكم في استخدام البادئات بحذر لتحقيق توازن بين تعقيد التعليمة وسرعة تفسيرها، وذلك حسب احتياجات البرامج والتطبيقات المختلفة.

    المزيد من المعلومات

    بما أننا نتناول موضوع “instruction prefixes” في سياق معالجات x86، دعنا نعمق قليلا في الفهم الفني لهذه البادئات. يُعتبر استخدام البادئات جزءًا حيويًا في هندسة المعالجات الحديثة، حيث يتيح للمبرمجين ومطوري البرامج تحديد سلوك التعليمات وتخصيصها بشكل أفضل وفقًا لمتطلبات التطبيق.

    تشمل البادئات المستخدمة في معالجات x86 عدة أنواع، وسنستعرض بعضها:

    1. بادئة الحجم (Operand Size Prefix): تحدد حجم العمليات التي تقوم بها التعليمة. يمكن أن تكون هذه البادئة إما 16 بت أو 32 بت أو 64 بت.

    2. بادئة العنوان (Address Size Prefix): تحدد حجم العنوان المستخدم في التعليمة. يمكن أن يكون العنوان إما 16 بت أو 32 بت أو 64 بت.

    3. بادئة الإشارة (Segment Prefix): تحدد القاعدة (segment) المستخدمة للوصول إلى البيانات أو التعليمات.

    4. بادئة التكرار (Repeat Prefix): تستخدم لتكرار تنفيذ تعليمة معينة، مثل REP و REPE.

    5. بادئة القفل (Lock Prefix): تستخدم في العمليات التي تتعامل مع التزامن والتحكم في الوصول المشترك للمتغيرات (تستخدم في تعليمات الـAtomic Operations).

    6. بادئات REX و XOP: تستخدم في توسيع إمكانيات المعالجات الحديثة مثل دعم السجلات الإضافية والعمليات الأكثر تعقيدًا.

    استخدام عدة بادئات في تعليمة واحدة يمكن أن يسهم في تحسين أداء البرامج عن طريق تخصيص تعليمة معينة لتلبية متطلبات معينة. ومع ذلك، يجب أن يكون هناك توازن بين الفائدة المحتملة من إضافة بادئات وبين تأثيرها على سرعة تفسير التعليمة.

    في النهاية، يتطلب استخدام البادئات فهمًا دقيقًا للهندسة الداخلية للمعالج ومتطلبات التطبيقات المحددة، ويتيح هذا الفهم العميق تحسين أداء البرمجيات وتكاملها بشكل فعّال مع الأنظمة الحاسوبية المتقدمة.

  • تكامل مكتبات x86 و x64 في حزم NuGet: دليل شامل

    إن توجيه النمط الصحيح لمكتبتك وتعبئتها في حزمة NuGet يمثل تحدًّا فنيًّا هامًا، خاصة عندما يتعلق الأمر بتعيين الإعدادات الصحيحة للتوجيه بين مكتبات x86 و x64. يبدو أنك قد اتبعت أسلوبًا صحيحًا لتضمين مكتبات x86 و x64 في حزمتك، ولكن هناك بعض الأمور التي يمكن أن تحتاج إلى تصحيح لضمان عمل الحزمة بشكل صحيح.

    في البداية، يُفضل تحديث المحتوى داخل ملف .csproj ليشير إلى ملف .targets الخاص بك. يمكنك تحقيق ذلك عن طريق إضافة مقطع يشير إلى ملف .targets في الـ الخاص بالـBuild:

    xml
    <ItemGroup> <None Update="build\net45\MyLib.targets"> <CopyToOutputDirectory>PreserveNewestCopyToOutputDirectory> None> ItemGroup>

    هذا يضمن أن ملف .targets سيتم نسخه إلى مجلد الإخراج أثناء بناء المشروع.

    ثم، يُفضل أيضًا تحديث محتوى ملف .targets نفسه ليتحقق من وجود ملف الـDLL بالنمط الصحيح (x86 أو x64) ويقوم بإضافته إلى الإحداثيات. يمكنك تحديث الجزء ذي الصلة في ملف .targets كما يلي:

    xml
    <Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences"> <ItemGroup Condition="'$(Platform)' == 'x86' or '$(Platform)' == 'x64'"> <Reference Include="MyLib"> <HintPath>$(MSBuildThisFileDirectory)$(Platform)\MyLib.dllHintPath> <SpecificVersion>FalseSpecificVersion> <Private>TruePrivate> Reference> ItemGroup> Target>

    بعد تحديث ملف .targets، يجب أن يظهر اسم المكتبة في ملف .csproj كما يجب، مع إشارة واضحة إلى ملف .targets.

    تذكر أن تتأكد من تحديث الحزمة على NuGet بعد إجراء هذه التغييرات للتأكد من تحديث المشروعات التي تعتمد على هذه الحزمة. إذا استمرت المشكلة، فقد تكون هناك قضية أخرى يجب التحقق منها، مثل الإعدادات الإضافية في ملف .csproj أو مشكلات في نسخ الـDLL أو الإعدادات البيئية.

    المزيد من المعلومات

    في سياق تطوير حزم NuGet التي تحتوي على مكتبات متعددة النماذج (x86 و x64)، هناك بعض النقاط التي يجب مراعاتها لضمان نجاح العملية.

    1. هيكل الحزمة:

    يجب أن يكون هيكل الحزمة مرتبًا ومحددًا بشكل صحيح. النماذج المستهدفة يجب أن توضع في مجلدات فرعية تحمل اسماء المنصات المستهدفة.

    plaintext
    lib monodroid MyLib.dll xamarin.ios10 MyLib.dll net45 MyLib.dll (x86) build net45 x86 MyLib.dll (x86) x64 MyLib.dll (x64) MyLib.targets

    2. ملف .targets:

    يجب أن يتحقق ملف .targets من نوعية المنصة المستهدفة (x86 أو x64) ويقوم بتضمين المكتبة المناسبة.

    3. الملف .csproj:

    تأكد من وجود الإشارة الصحيحة في ملف .csproj إلى ملف .targets. يمكنك أيضًا استخدام لضمان نسخ ملف .targets إلى مجلد الإخراج.

    4. إصدارات المكتبة:

    تأكد من أن جميع إصدارات المكتبة (x86 و x64) تحمل نفس الرقم وتمتلك إشارة عمومية موحدة.

    5. المراجع في ملف .csproj:

    يجب أن تظهر المكتبة المرجعية في ملف .csproj بشكل صحيح، مع ذكر إصدارها والنموذج المستهدف.

    6. إصدار NuGet:

    تأكد من استخدام إصدار مناسب لأداة NuGet. في بعض الأحيان، قد تكون بعض المشكلات مرتبطة بإصدار محدد.

    7. تحديث حزمة NuGet:

    قد تحتاج إلى تحديث حزمة NuGet الخاصة بمشروعك بعد التعديلات للتأكد من تطبيق التغييرات.

    8. مشاكل التشغيل:

    في حالة استمرار مشكلة التشغيل عند تشغيل x64، يجب التحقق من البيئة التشغيلية والتأكد من توافر النموذج المناسب للنظام المستخدم.

    9. إعدادات الـDLL:

    تأكد من أن إعدادات الـDLL تتوافق مع النموذج المستهدف (x86 أو x64) وأن الإصدارات تتطابق.

    بمراعاة هذه النقاط، يمكنك تحسين فرص نجاح تكامل مكتبتك مع مشروعات NuGet المستهدفة بشكل فعّال.

  • x86 و x64 الفرق بين معالجات

    في البداية يجب ان تعرف ان  معالجات 64 بت تتفوق على معالجات 32 بت بأضعاف في سرعة نقل البيانات وسرعة خدمات الحاسوب وتوفير مزايا أفضل للمعالجات .

     أما المعالجات التي تحتوي على نواة ذات 32 بت فتعتبر معالجات قديمة، ونذكر منها: Pentuim 4 و Pentuim D و Core2duo.

    أما المعالجات التي تحتوي على نواة ذات 64 بت فهي معالجات حديثة من العصر الحديث، نذكر منها Intel Atom CPU N455 فما فوق و معالجات  Intel Core I3 I5 I7 I9 .

    ❗ يجب أن تعرف أن معالج 32 بت يُطلق عليه إسم آخر هو x86 ومعالج 64 بت يحتوي على إسم أخر أيضا إنه x64

    ➡️ 32bit = x86
    ➡️ 64bit = x64

    1- الرامات:

    معالج 64 بت يمكن أن يتعرف على 128 جيجا من الرام كأقصى حد، أما معالج 32 بت فأقصى حد سيتعرف عليه لن يتجاوز 3 جيجا في الرامات.

    2- متطلبات أنظمة التشغيل :

    لتنصيب نظام 32 بت على حاسوبك فغالبا أقل حجم للرام من أجل التنصيب هي 64 ميجا !!

    أما 64 بت يحتاج 2 جيجا كأقل حجم.

    3- البرامج والألعاب والتطبيقات :

    تقريبا جميع البرامج تحتوي على نواتين نواة لحواسيب 32 بت ونواة لحواسيب 64 بت، على سبيل المثال عند تحميل نظام تشغيل معين سواء لينكس أو الويندوز، نأخذ Windows 10 Pro x86 يتم تنصيبه على نواة 32 بت و 64 بت في نفس الوقت.

    أما Windows 10 Pro x64 فيثبت على معالج بنواة 64 بت فقط و إذا وجدت Windows 10 Pro x86 x64 في نفس الوقت، فاعلم أن النظام متوافق مع كلا المعالجين.

زر الذهاب إلى الأعلى
إغلاق

أنت تستخدم إضافة Adblock

يرجى تعطيل مانع الإعلانات حيث أن موقعنا غير مزعج ولا بأس من عرض الأعلانات لك فهي تعتبر كمصدر دخل لنا و دعم مقدم منك لنا لنستمر في تقديم المحتوى المناسب و المفيد لك فلا تبخل بدعمنا عزيزي الزائر