ماذا تعويض رمز التجميع 16 بت؟
سؤال
أنا ذاهب من خلال بعض الأمثلة رمز التجميع لوضع 16 بت الحقيقي.
لقد صادفت الخطوط:
mov bx, cs
mov ds, bx
mov si, OFFSET value1
pop es
mov di, OFFSET value2
ماذا يفعل هذا؟ ماذا تعاني من "الإزاحة" هناك؟
المحلول
كما يقول بعض الإجابات الأخرى، offset
تشير الكلمة الأساسية إلى الإزاحة من القطاع الذي يتم تعريفه فيه. ملاحظة، ومع ذلك، قد تتداخل هذه القطاعات ويمكن أن تكون الإزاحة في شريحة واحدة مختلفة في قطاع آخر. على سبيل المثال، افترض أن لديك الجزء التالي في الوضع الحقيقي
data SEGMENT USE16 ;# at segment 0200h, linear address 2000h
org 0100h
foo db 0
org 01100h
bar db 0
data ENDS
يعتبر المجمع ذلك foo
في أوفست 0100h
من قاعدة data SEGMENT
, ، لذلك أينما يرى offset foo
سوف يضع القيمة 0100h
, ، بغض النظر عن قيمة DS
في الموعد.
على سبيل المثال، إذا تغيرنا DS
لشيء آخر غير قاعدة data
الجزء يتنافس المجمع:
mov ax, 200h ; in some assemblers you can use @data for the seg base
mov ds, ax
mov bx, offset foo ; bx = 0100h
mov byte ptr [bx], 10 ; foo = 10
mov ax, 300h
mov ds, ax
mov bx, offset foo ; bx = 0100h
mov byte ptr [bx], 10 ; bar = 10, not foo, because DS doesn't match what we told the assembler
في المثال الثاني DS
هو 0300h
, ، وبالتالي فإن قاعدة القطعة أشار إليها DS
هو 03000h
. وبعد هذا يعني ذاك ds:[offset foo]
يشير إلى العنوان 03000h + 0100h
وهو نفسه 02000h + 01100h
, ، والذي يشير إلى bar
.
نصائح أخرى
هذا يعني فقط عنوان هذا الرمز. إنه مثل المشغل والشغل في ج، إذا كنت على دراية بذلك.
offset
يعني أن si
السجل سيكون مساويا إزاحة المتغير القيمة 1. (ليس لقيمته الفعلية). إزاحة هو العنوان من بداية قطاعي الذاكرة حيث يتم تخزين المتغير. الإزاحة عادة ما تكون بالنسبة ل ds
الجزء (في قضيتك ds
و cs
السجلات تشير إلى نفس القطاع).
من عند دليل مبرمج MASM 6.1 (Microsoft Macro Assembler)
ال عوض المشغل أو العامل
عنصر ثابت هو نوع خاص من المعامل الفوري الذي يتكون من قيمة إزاحة أو شريحة. يعرض مشغل الإزاحة إزاحة موقع الذاكرة، كما هو موضح هنا:
mov bx, OFFSET var ; Load offset address
للحصول على معلومات حول الاختلافات بين السلوك MASM 5.1 والسلوك MASM 6.1 المتعلقة بالإزاحة، انظر الملحق أ.
نظرا لأن البيانات في وحدات مختلفة قد تنتمي إلى شريحة واحدة، فإن المجمع لا يمكن أن يعرفه لكل وحدة النمطية الإزاحة الحقيقية داخل القطاع. وبالتالي، فإن إزاحة Var، على الرغم من أن القيمة الفورية، لا يتم تحديدها حتى وقت الارتباط.
إذا قرأت بعناية، يتم تحديد القيمة النهائية بعد "ربط" رمز الكائن الخاص بك لإنشاء DLL / EXE. قبل الارتباط، كل ما لديك قيمة فورية تمثل الإزاحة من العنوان الأساسي للجزء.
في وضع X86 16 بت، مساحة العنوان ليست مسطحة؛ بدلا من ذلك، تتكون العناوين من إزاحة و "قطعة". يشير "الجزء" إلى مساحة 64 ألفا، الإزاحة داخل هذه المساحة.
تعوض الأساس المسافة من نقطة القطاع (تسمى أيضا نقطة Datum). على سبيل المثال عنوان القطاع هو 0000 ويتم إزاحة العنوان أو العنوان المنطقي 0100 ثم يمكن حساب العنوان الفعلي عن طريق إضافة الأزواج. العنوان الفعلي = 0000 + 0100 = 0100 يعني أن موقعنا المطلوب هو عنوان 0100. وبالمثل إذا كان عنوان القطاع هو 1DDD وإزاحة هو 0100 ثم: العنوان الفعلي هو: 1DDD + 0100 = 1edd
يعني أن وجهتنا هي 1edd.