طباعة هذه الصفحة
كتبه المجمع NASM 13363
الدرس 9: العنونة والمؤشرات الدرس 9: العنونة والمؤشرات
قيم الموضوع
(7 أصوات)
 
لعل محتويات هذا الدرس تعتبر من المفاهيم المزعجة في عالم البرمجة، لكننا سنحاول تسهيلها ما أمكن حتى تتمكن من البرمجة باحترافية باستعمال المجمع. نتطرق هنا إلى ما يسمى بالعنونة في ذاكرة الحاسوب وعقله الإلكتروني، وكذا إلى كيفية التعامل معهما من خلال ما يعرف بالمؤشرات.

1.المؤشرات

إن كنت ممن درس اللغة C فإنك تعرف إلى حد ما معنى كلمة المؤشر الذي يرمز له بـ  <variable>*.

إن كنت ممن درس اللغة Pascal فإنك تعرف إلى حد ما معنى كلمة المؤشر الذي يرمز له بـ  <variable>^.

إن كنت ممن درس اللغة Basic  فإنه لا يوجد فيه المؤشر.

بالنسبة لجميع المجمعات ومنها NASM توجد مؤشرات محدودة ومعرفة سابقا وهي عبارة عن خزانات متواجدة في عقل الحاسوب وهي كالتالي :

  الاسم 16 زوج 32 زوج
الخزانات المؤشرة مؤشر المرسل SI ESI
مؤشر المرسل إليه DI EDI
مؤشر المكدس SP ESP
مؤشر القاعدة BP EBP
مؤشر الأمر IP EIP

وسنتطرق إن شاء الله لشرحها واحدا تلو الآخر، لكن على حساب صيرورة الدرس.


2. العنونة

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

إذا تم تحديد التفاصيل الدقيقة فاذهب إلى :

العنونة : هي في الحقيقة جد مهمة، لأننا قبل التكلم عن الأوامر وكيفية استعمالها نتكلم أولا عن العنونة، فما هي العنونة؟

عقل الحاسوب أو المعالج كما يسميه البعض هو الذي يقوم بتحويل ومعالجة المعطيات. ونظام العنونة هو الذي يقوم بدور إيجاد هذه المعطيات في الذاكرة حتى يتسنى لعقل الحاسوب معالجتها والتحكم فيها.

وتوجد عدة أنواع للعنونة:

  1. العنونة المحايدة
  2. العنونة المباشرة
  3. عنونة الخزان
  4. العنونة النسبية
  5. عنونة الذاكرة 

2.1. العنونة المحايدة

وتحدث عندما لا تكون أي معالجة للمعطيات ، أي عند إعطاء الأمر لعقل الحاسوب كالتوقف أو الانتظار للحظة معينة.

مثال : الأمر NOP الذي يعني لا معالجة.

في NASM يمكن الانتظار لفترة معينة باستعمال هذا الأمر :

times  2500  NOP

2.2. العنونة المباشرة

في هذه الحالة نعطي قيمة مباشرة لأحد الخزانات، بحيث لا يتكلف عقل الحاسوب بالبحث عنها في خلايا الذاكرة.

مثال على ذلك :

mov ax,32h
mov bx,01001101b
mov cx,159
mov dx,
17

2.3. عنونة الخزان

في هذه الحالة يكون المعطى عبارة عن خزان ، بحيث لا يتكلف عقل الحاسوب بالبحث في خلايا الذاكرة بل يأخذ القيمة من خزان ويضعها في خزان آخر.

مثال على ذلك :

mov ax,bx
add bx,dx
sub cx,ax

xchg  bl,al

ملاحظة: الأمر xchg يقوم بإبدال قيمتي خزانين، فمثلا تصبح قيمة bl هي al و قيمة al هي bl.


2.4. العنونة النسبية والمؤشر IP

حسناً، لقد تطرقنا في الفقرة 7 (أدوات الشرط) إلى معنى العلامة، وهي التي نضعها في وسط الشفرة للقفز أو الذهاب إليها، كما أنها لا تعتبر أمر يجب تنفيذه.

مثال :

;1الأمر 

movah,0eh     

;2الأمر   jmp   fifi         ;fifi اذهب إلى
;3الأمر    didi :                ;عبارة عن علامة فقط  didi
;3الأمر   mov al,30
;4الأمر   sub  ah,al
;5الأمر   add  cx,16
;6الأمر   fifi :                ;عبارة عن علامة فقط  fifi
;6الأمر   xchg  ah,al
;7الأمر   add  dx,106
;8الأمر   jmp   didi         ;didi  اذهب إلى

ملاحظة 1:  يحتوي عقل الحاسوب أو المعالج على منطقة تسمى بالعداد الترتيبي (compteur ordinal) وقبل أن يبدأ المعالج أو عقل الحاسوب بتنفيذ المشروع، يتم أولا:

  •  تحميل المشروع كاملا في الذاكرة.

  • وبما أن المشروع يتكون من عدة أوامر (أنظر أعلاه)، فإن كل أمر يأخذ عنوانا محددا في الذاكرة.

  • بعد ذلك تحفظ غالبية عناوين الأوامر مرتبة  في العداد الترتيبي داخل عقل الحاسوب.

  • ومن تم يقوم المعالج بتنفيذ الأوامر الموجودة أصلا في الذاكرة من خلال قراءته لعناوينها الموجودة في العداد الترتيبي.

ملاحظة 2:  العداد الترتيبي يتحكم فيه الخزان المسمى مؤشر الأوامر IP، حيث من خلاله يتم أخد عنوان الأمر الذي يجب تنفيذه من الذاكرة.

العداد الترتيبي

 عنوان الأمر 1
 عنوان الأمر 2
 عنوان الأمر 3
 عنوان الأمر 4
 عنوان الأمر 5
 عنوان الأمر 6
 عنوان الأمر 7
 عنوان الأمر 8
IP يأخذ عنوان الأمر 1 ===> يتم تنفيذه
IP يأخذ عنوان الأمر 2 ===> يتم تنفيذه (اذهب إلى
عنوان الأمر6 )
  • في الواقع تمثل fifi المقدار الذي يبعد فيه الأمر6  عن الأمر2  في العداد الترتيبي، ولتحديد عنوان الأمر6  يقوم عقل الحاسوب بإضافة  fifi على عنوان الأمر2  فيحصل على عنوان الأمر6 : في هذه الحالة تكون قيمة fifi هي 4.

IP يأخذ عنوان الأمر 6 ===> يتم تنفيذه
IP يأخذ عنوان الأمر 7 ===> يتم تنفيذه
IP يأخذ عنوان الأمر 8 ===> يتم تنفيذه (اذهب إلى
عنوان الأمر3 )

  • تكون قيمة didi في هذه الحالة هي 5-

وهكذا...(هذا المثال لمشروع غير متوقف أبدا)

ملاحظة : عدد الخانات المسموح تجاوزها عند القفز محدود بين 128-  و 127 ، في حالة كانت القيمة أكبر أو أصغر من ذلك يقوم المجمع بإظهار رسالة تعبر عن الخطأ  كـ "القفز خارج عن الحدود المسموح بها"

2.5 عنونة الذاكرة

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

2.5.1 تقسيم الذاكرة

الذاكرة RAM مقسمة إلى عدة قطع ذاكرية متقايسة المساحة أو الحجم، مساحة كل واحدة منها تساوي  64ko (يعني 64 ألف ثمن).

وكل قطعة تحمل رقما يميزها عن القطع الأخرى، هذا الرقم يسمى غالبا بـالقطعة (segment).

مساحة كل قطعة هي 64ko أي 64*1024 ثمن يعني 65536 ثمن.

لاستعمال أو تحديد كل ثمن على حدة نميزه هو أيضا برقم آخر يمثل ترتيبه داخل القطعة المنتمي إليها، هذا الرقم يسمى غالبا بـالبعد (offset).

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

وبالتالي فكلمة العنوان تفيد بالتحديد رقم القطعة ورقم البعد، ومنه نكتب : (البعد : قطعة) = العنوان (adresse)

تذكرا جيدا بأن:

  • كل قطعة حجمها هو 64ko

  • وكل خلية في القطعة حجمها ثمن واحد فقط

  • العنوان = (البعد : قطعة)

  • مثلا  (1012:B800)  تعني عنوان خلية واحدة حجمها ثمن واحد فقط.

2.5.2 تقريب للفهم فقط

في هذه الحالة نعطي العنوان لعقل الحاسوب بكل بساطة . والعنوان ممثل بـ 16 زوج في النظام الحقيقي  و بـ 32 زوج في النظام الممتد، (سنتطرق لهذين فيما بعد).

توجد عدة أوجه لإعطاء العنوان أو تمثيله.وإن استعمالنا لعنوان في الذاكرة شبيه باستعمالنا خزانا. ومن أجل هذا نجد أحيانا الشكل التالي  r/m  (عند التطرق لشرح أوامر المجمع كـ add و...) الذي يعني أنه بالإمكان الدخول إلى الذاكرة أو خزان يحمل عنوانا.

مثال : الأمر mov

mov <r/m>,<r/m>   هذا الشكل يعتبر عاما (خزان أو ذاكرة نحو خزان أو ذاكرة).
 احذر (ذاكرة نحو خزان قطعة كـ CS أو DS ..) يعتبر خطأ.
mov <r/m>,<imm>   تحويل قيمة عددية نحو ذاكرة.
mov <reg>,<imm>   تحويل قيمة عددية نحو خزان.
mov <accu>,<mem>   accu أو الحاشد يمكن أن يكون AL أو AX أو EAX وهنا نضع ذاكرة في الحاشد.
mov <mem>,<accu>   عكس سابقتها.
mov <sreg>,<r/m>   sreg تعني خزان القطعة (CS أو SS ...) حيث نضع فيه خزان يحمل ذاكرة.
mov <r/m>,<sreg>   عكس سابقتها وهي قليلة الاستعمال.

2.5.3 أشكال عنونة الذاكرة

الشكل العام لعنوان في الذاكرة هو : [ثابتة + قاعدة + مؤشر * سلم : قطعة]   حيث : البعد هو ثابتة + قاعدة + مؤشر * سلم

يمكن لهذه الخمسة حدود أن تكون غائبة أي تعتبر كالصفر.

قطعة   في الحالة البدئية تكون هي DS فقط، وفي حالة استخدامنا لإحدى القواعد التالية :BP أو EBP أو ESP نستعمل SS . ويمكن الاستعمال أيضا CS أو ES أو FS أو GS
سلم   هو عدد يمثل قوى 2 ،مثلا 1 و 2 و 4 و 8 و 16 ...( انطلاقا من العقول 386 وما فوق)
مؤشر   SI و DI (بالنسبة للعقول 286). وانطلاقا من العقول 386 يمكن استعمال أيا من الخزانات ذات السعة 32 زوج (كـ EBX وECX ...).
قاعدة   BX و BP (بالنسبة للعقول 286). وانطلاقا من العقول 386 يمكن استعمال أيا من الخزانات ذات السعة 32 زوج (كـ EBX وECX ...).
ثابتة   هي قيمة عددية فقط.

2.5.4 حجم التحويل

غالبا لتمثيل محتوى عنوان الذاكرة للمجمعات كـ NASM نجعلها بين معقوفتين [ ].

مثال في المجمع nasm : 

mov  ax , [cs:si+1000]
mov  [es:si+1000] , bl

ملاحظة : لقد افترضنا مثلا بأن es تحمل رقم قطعة معينة، ويمكنك استعمال القطعة التي تريد كـ cs و ds و ss وfs وgs .

أما بالنسبة لحجم التحويل فلنعتبر الأمثلة التالية:

الحالة الأولى:  mov  [es:1000] , ax

هذا المثال يبين أننا نريد أن نضع ax في البعد  1000 (البعد يسمى offset بالإنجليزية) للقطعة es ، وكما قلنا في بداية الصفحة بأن حجم الخلية ذات العنوان (es:1000) هو ثمن واحد فقط، ونعلم أن حجم الخزان ax هو 16 زوج يعني ثمنين بحيث ينقسم إلى al و ah، إذن في هذه الحالة سيعمل المجمع على أن يضع  al  في الخانة ذات البعد 1000 و  ah  في الخانة ذات البعد 1001 للقطعة es.

الحالة الثانية:  mov  [es:1000] , al

هذه الكتابة مقبولة   لأن  al  و  [es:1000]  لهما نفس الحجم الذي هو ثمن واحد فقط.

الحالة الثالثة:  mov  [es:1000] ,

في هذه الحالة يقوم المجمع بإظهار رسالة خطأ، لأنه لا يعرف هل التحويل سيكون بـ 8 أزواج (ثمن واحد) أو 16 زوج (ثمنين) أو 32 زوج (4 أثمان).

ولتفادي مثل هذا الخطأ، للمجمع NASM أدوات التي من خلالها يتعرف على نوع التحويل وهي كالتالي : byte و word  و dword .

 مثال : mov [fs:1256] , byte     التي تكافئ     mov byte [fs:1256] , 5


3. العنوان والمحتوى

ما الفرق بين العنوان والمحتوى في المجمع؟
العنوان: يتم تحديده بطريقتين : إما مباشرا كـ ( ds : 1598 ) أو عن طريق التسمية كـ :   color    db      16 المحتوى: وهو العنوان + المعقوفتين [ ] ، ومعناه الحقيقي هو ما تحتويه الخانة الموجودة في الذاكرة ذات العنوان X .مثال 1 : [ds:1598] هو محتوى العنوان ( ds : 1598 ).
مثال 2 : [color] هو محتوى العنوان color الذي هو 16 في هذه الحالة.
 
byte :تعني تحويل بثمن واحد فقط.  
word :تعني تحويل بثمنين  
dword :تعني تحويل بـ 4 أثمان
  

مثال عام: كتابة الحروف اللاتينية الكبيرة كلها باستعمال متغير.

كتابة خاطئة كتابة خاطئة كتابة صحيحة
[BITS 16]
[ORG 0x0100]

[SEGMENT .text]
mov cx,27
mov ah,0eh
Boucle:

 
mov al,car
 int 10h
 
inc car
Loop Boucle

mov ax,4c00h
int 21h

[SEGMENT .data]

car     db     'A'
[SEGMENT .bss]

[BITS 16]
[ORG 0x0100]

[SEGMENT .text]
mov cx,27
mov ah,0eh
Boucle:

 mov al,[car]
 
int 10h
 inc [car]
Loop Boucle

mov ax,4c00h
int 21h

[SEGMENT .data]

car     db     'A'
[SEGMENT .bss]

[BITS 16]
[ORG 0x0100]

[SEGMENT .text]
mov cx,27
mov ah,0eh
Boucle:

 mov al,byte[car]
 
int 10h
 inc  byte[car]
Loop Boucle

mov ax,4c00h
int 21h

[SEGMENT .data]

car     db     'A'
[SEGMENT .bss]


تمارين تطبيقية


التمرين 9.1 : أسئلة مباشرة في عنونة الذاكرة

أجب بنعم أو لا مع التعليل :

ملاحظة toto و titi و tata عبارة عن عناوين لمتغيرات أو علامات.

  1. هل نستطيع كتابة :  MOV [SI],AX  ؟
  2. هل نستطيع كتابة : MOV [BX],AX   ؟
  3. هل نستطيع كتابة : MOV [BL],AX   ؟
  4. هل نستطيع كتابة : MOV [AX],AX   ؟
  5. هل نستطيع كتابة : MOV [CX],AX    ؟
  6. هل نستطيع كتابة : MOV [EAX],AX   ؟
  7. هل نستطيع كتابة : MOV [BX+BP],AX   ؟
  8. هل نستطيع كتابة : MOV [BX+SI+3],AX   ؟
  9. هل نستطيع كتابة : MOV [EBX*2+ESI],AX  ؟
  10. هل نستطيع كتابة : MOV [6*EBX],AX  ؟
  11. هل نستطيع كتابة : MOV [8*SI],AX  ؟
  12. هل نستطيع كتابة : MOV [EAX*5],AX   ؟
  13. هل نستطيع كتابة : MOV [EAX*5],AX   ؟
  14. هل نستطيع كتابة : MOV [SP],AX  ؟
  15. هل نستطيع كتابة : MOV [ESP],AX   ؟
  16. هل نستطيع كتابة : MOV AL,0 ؟
  17. هل نستطيع كتابة : MOV AX,0  ؟
  18. هل نستطيع كتابة : MOV 0,CL  ؟
  19. هل نستطيع كتابة : MOV [TOTO],0  ؟
  20. هل نستطيع كتابة : MOV [TOTO],BYTE 0  ؟
  21. هل نستطيع كتابة : MOV TOTO,AX  ؟
  22. هل نستطيع كتابة : MOV [TOTO+TITI],AX   ؟
  23. هل نستطيع كتابة : MOV [TOTO+TITI-TATA],AX   ؟
  24. هل نستطيع كتابة : MOV [LONG],AX   ؟

التمرين 9.2

علما أن الرقم ASCII للحرف 'a' هو 61h أي 97 بالنظام العشري.

أنجز شفرة تمكن من إظهار جميع الحروف الصغيرة اللاتينية على الشاشة.

  1. باستعمال الأداة Loop والمتغيرات.

  2. بدون استعمال الأداة Loop  والمتغيرات.


التمرين 9.3

علما أن الرقم ASCII للرقم العربي '0' هو 30h أي 48  بالنظام العشري.

أنجز شفرة تمكن من إظهار جميع الأرقام العربية على الشاشة.

  1. باستعمال الأداة Loop  والمتغيرات.

  2. بدون استعمال الأداة Loop  والمتغيرات.


التمرين 9.4

أنجز شفرة تمكن من إظهار جميع الحروف اللاتينية والأرقام العربية والرموز على الشاشة.

  1. باستعمال الأداة Loop  والمتغيرات.

  2. بدون استعمال الأداة Loop  والمتغيرات.


 

الحلول

القسم الأول: أسئلة مباشرة

نعلم أنه لدينا   [ ثابتة + قاعدة + مؤشر * سلم : قطعة].

  1. نعم لأن SI مؤشر

  2. نعم لأن BX قاعدة

  3. لا لأن BL لا يمثل البعد لأن هذا الأخير يمثل بـ 16 زوج إلى 32 زوج أما BL فهو ذو 8 أزواج فقط

  4. لا لأن AX ليس بقاعدة أو مؤشر

  5. لا لأن CX ليس بقاعدة أو مؤشر

  6. نعم لأن EAX  ذي 32 زوج يمثل قاعدة أو مؤشر

  7. لا لأن BP و BX هما معا عبارة عن قاعدة ولا يمكن استعمالهما معا

  8. نعم لأن  BX  و SI مؤشر و 3 ثابتة

  9. نعم تعتبر EBX عبارة عن مؤشر و ESI عبارة عن قاعدة (وذلك في النظام 32 زوج : النظام الممتد)

  10. لا لأن السلم 6 ليس من قوى 2 : 1 أو 2 أو 4 ....

  11. لا لأن SI مؤشر

  12. نعم أو لا (نعم بالنسبة لـ NASM ولا بالنسبة لـ MASM) حيث [EAX*4+EAX]

  13. نعم تعتبر EBX عبارة عن مؤشر و ESI عبارة عن قاعدة

  14. لا لأنه في النظام الحقيقي 16 زوج،  فقط BP و BX هما اللذان يعتبران القاعدة، SI و DI هما المؤشرات

  15. نعم يمكن لـ ESP أن تكون إما قاعدة أو مؤشرا وذلك في النظام 32 زوج.

  16. نعم، لا ينصح به، خير أن تكتب XOR AL,AL

  17. نعم، لا ينصح به، خير أن تكتب XOR AX,AX

  18. لا غير مقبول بتاتا لأن 0 عبارة عن ثابتة فقط

  19. لا لأن المجمع لا يعرف حجم التحويل

  20. نعم هنا قد حددنا حجم التحويل

  21. لا لأن TOTO تعتبر كعدد

  22. لا ،لا يجب جمع بُعْدَين

  23. نعم ، لأن TITI-TATA  تمثل الحاصل الذي هو الفرق بينهما، حيث يتم اعتباره كثابتة تضاف إلى TOTO

  24. لا لأن LONG هي من أدوات NASM وفي هذه الحالة يجب استعمال اسم آخر.