• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
نظام تشغيل اقرأ
 

نظام تشغيل اقرأ

on

  • 2,627 views

Eqra OS نظام تشغيل اقرأ

Eqra OS نظام تشغيل اقرأ

Statistics

Views

Total Views
2,627
Views on SlideShare
2,627
Embed Views
0

Actions

Likes
0
Downloads
49
Comments
1

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • OK
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    نظام تشغيل اقرأ نظام تشغيل اقرأ Document Transcript

    • ‫ﺑﺴﻢ ﺍﷲ ﺍﻟﺮﲪﻦ ﺍﻟﺮﺣﻴﻢ‬ ‫ﺟﺎﻣﻌﺔ ﺍﳋﺮﻃﻮﻡ - ﻛﻠﻴﺔ ﺍﻟﻌﻠﻮﻡ ﺍﻟﺮﻳﺎﺿﻴﺔ‬ ‫ﻗﺴﻢ ﺍﳊﺎﺳﻮﺏ‬‫ﲝﺚ ﻣﻘﺪﻡ ﻟﻨﻴﻞ ﺩﺭﺟﺔ ﺍﻟﺒﻜﺎﻟﻮﺭﻳﻮﺱ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﻮﺏ ﺑﻌﻨﻮﺍﻥ:‬ ‫ﺑ‪‬ﺮ‪‬ﻣ‪‬ﺠ‪‬ﺔ ﻭ‪ ‬ﺗ‪‬ﺼﻤ‪‬ﻴﻢْ ﻧﻈَﺎﻡ ﺗ‪‬ﺸ‪‬ﻐ‪‬ﻴﻞْ‬ ‫‪‬‬ ‫"ﻧﻈﺎﻡ ﺇﻗﺮﺃ"‬ ‫ﺇﻋﺪﺍﺩ ﺍﻟﺒﺎﺣﺚ : ﺃﲪﺪ ﻋﺼﺎﻡ ﻋﺒﺪ ﺍﻟﺮﺣﻴﻢ ﺃﲪﺪ‬ ‫ﺑﺈﺷﺮﺍﻑ : ﺩ.ﻣﺼﻄﻔﻰ ﺑﺎﺑﻜﺮ ﺻﺪﻳﻖ‬ ‫٣ ﻳﻮﻟﻴﻮ ٠١٠٢‬
    • ‫ﺟﺎﻣﻌﺔ ﺍﳋﺮﻃﻮﻡ.‬ ‫ﻛﻠﻴﺔ ﺍﻟﻌﻠﻮﻡ ﺍﻟﺮﻳﺎﺿﻴﺔ - ﻗﺴﻢ ﺍﳊﺎﺳﻮﺏ.‬ ‫ﰎ ﻛﺘﺎﺑﺔ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻧﻈﺎﻡ ‪.LTEX‬‬ ‫‪A‬‬ ‫‪c‬‬ ‫ﲨﻴﻊ ﺍﳊﻘﻮﻕ ﳏﻔﻮﻇﺔ ⃝ ٠١٠٢ ﺃﲪﺪ ﻋﺼﺎﻡ ﻋﺒﺪ ﺍﻟﺮﺣﻴﻢ ﺃﲪﺪ.‬‫ﻳﺴﻤﺢ ﺑﻨﺴﺦ، ﺗﻮﺯﻳﻊ ﻭ/ﺃﻭ ﺗﻌﺪﻳﻞ ﻫﺬﺍ ﺍﳌﺴﺘﻨﺪ ﺿﻤﻦ ﺷﺮﻭﻁ ﺇﺗﻔﺎﻗﻴﺔ ﺗﺮﺧﻴﺺ ﺍﳌﺴﺘﻨﺪﺍﺕ ﺍﳊﺮﺓ ﺟﻨﻮ ﺍﻹﺻﺪﺍﺭ ٢.١ ﺃﻭ ﺃﻱ ﺇﺻﺪﺍﺭﹴ ﻻﺣﻖﹴ‬ ‫ﰎ ﻧﺸﺮﻩ ﻣﻦ ﻗﺒﻞ ﻣﺆﺳﺴﺔ ﺍﻟﱪﳎﻴﺎﺕ ﺍﳊﺮﺓ، ﺩﻭﻥ ﺃﻳﺔ ﺃﻗﺴﺎﻡ ﺛﺎﺑﺘﺔ، ﻧﺼﻮﺹ ﻏﻼﻑ ﺃﻣﺎﻣﻲ ﻭﻧﺼﻮﺹ ﻏﻼﻑ ﺧﻠﻔﻲ. ﻟﻘﺪ ﲤﺖ ﺇﺿﺎﻓﺔ‬ ‫ﻧﺴﺨﺔ ﻣﻦ ﺇﺗﻔﺎﻗﻴﺔ ﺍﻟﺘﺮﺧﻴﺺ ﰲ ﺍﻟﻘﺴﻢ ﺍﳌﻌﻨﻮﻥ )ﺇﺗﻔﺎﻗﻴﺔ ﺗﺮﺧﻴﺺ ﺍﳌﺴﺘﻨﺪﺍﺕ ﺍﳊﺮﺓ ‪.(GNU‬‬
    • ‫ﺍﳌﺤﺘﻮﻳﺎﺕ‬‫١‬ ‫‪Basics‬‬ ‫ﺍﻷﺳﺎﺳﻴﺎﺕ‬ ‫‪.I‬‬‫٣‬ ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬‫٦‬ ‫١.١. ﻣﺎ ﻫﻮ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ . . . . . . . . . . . . . . . . . . . . . . . . . .‬‫٦‬ ‫١.١.١. ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻛﺠﻬﺎﺯ ﲣﻴﻠﻲ . . . . . . . . . . . . . . . . .‬‫٦‬ ‫١.١.٢. ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻛﻤﺪﻳﺮ ﻟﻠﻤﻮﺍﺭﺩ ﻭﺍﻟﻌﺘﺎﺩ . . . . . . . . . . . . . .‬‫٦‬ ‫١.٢. ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ . . . . . . . . . . . . . . . . . . . . . . . . .‬‫٧‬ ‫١.٢.١. ﺍﳉﻴﻞ ﺍﻟﺼﻔﺮﻱ )٤٢٦١-٥٤٩١(: ﺍﳊﻮﺍﺳﻴﺐ ﺍﳌﻴﻜﺎﻧﻴﻜﻴﺔ . . . . . .‬‫٠١‬ ‫١.٢.٢. ﺍﳉﻴﻞ ﺍﻷﻭﻝ )٥٤٩١-٥٥٩١(: ﺍﻟﺼﻤﺎﻣﺎﺕ ﺍﳌﻔﺮﻏﺔ ﻭ ﻟﻮﺣﺎﺕ ﺍﻟﺘﻮﺻﻴﻞ‬‫٥١‬ ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬‫٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.١. ﻣﻌﻤﺎﺭﻳﺔ ﺍﻟﻨﻈﺎﻡ . . . . . . . . . . . . .‬‫٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.١.١. ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ ‪. . . System Bus‬‬‫٨١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.١.٢. ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ . . . . . . .‬‫٨١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.١.٣. ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ . . .‬‫٩١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.٢. ﺍﳌﻌﺎﰿ . . . . . . . . . . . . . . . .‬‫٠٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.٢.١. ﺩﻭﺭﺓ ﺗﻨﻔﻴﺬ ﺍﻟﺘﻌﻠﻴﻤﺎﺕ . . . . .‬‫٠٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.٢.٢. ﺃﳕﺎﻁ ﻋﻤﻞ ﺍﳌﻌﺎﰿ ‪. CPU Modes‬‬‫٢٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.٢.٣. ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ‪. . Real Mode‬‬‫٣٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.٢.٤. ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ‪Protected Mode‬‬‫٥٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٢.٢.٥. ﻣﻌﻤﺎﺭﻳﺔ ﻣﻌﺎﳉﺎﺕ 68‪. . . . . x‬‬‫١٣‬ ‫‪Boo ng‬‬ ‫‪ .II‬ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ‬‫٣٣‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ‪Bootloader‬‬‫٣٣‬ ‫٣.١. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ . . . . . . . . . . . . . . . . . . . . . . . . . . . .‬‫٤٣‬ ‫٣.٢. ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ‪. . . . . . . . . . . . . . . . . . . . . . . Bootloader‬‬‫ﺝ‬
    • ‫ﺍﳌﺤﺘﻮﻳﺎﺕ‬‫٥٣‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٣. ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ . . . . . . . . . . . . . . . . . . . . . . .‬‫٦٣‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ . . . . . . . . . . . . . . . . . . . . .‬‫٧٣‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٤.١. ﻋﺮﺽ ﺭﺳﺎﻟﺔ ﺗﺮﺣﻴﺒﻴﺔ . . . . . . . . . . . . . . .‬‫٠٤‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٤.٢. ﻣﻌﻠﻮﻣﺎﺕ ﻗﻄﺎﻉ ﺍﻻﻗﻼﻉ . . . . . . . . . . . . . .‬‫٨٤‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٤.٣. ﲢﻤﻴﻞ ﻗﻄﺎﻉ ﻣﻦ ﺍﻟﻘﺮﺹ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺍﳌﻘﺎﻃﻌﺔ 31‪. int 0x‬‬‫٠٥‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ 21‪. . . . . . . . . . . . . . . . . . . FAT‬‬‫١٥‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٥.١. ﻗﻴﻮﺩ ﻧﻈﺎﻡ 21‪. . . . . . . . . . . . . . . . . FAT‬‬‫١٥‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٥.٢. ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ 21‪ FAT‬ﻋﻠﻰ ﺍﻟﻘﺮﺹ . . . . . . . . . . .‬‫٤٥‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٥.٣. ﻫﻴﻜﻠﺔ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ . . . . . . . . . . . . . . . .‬‫٥٥‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٣.٥.٤. ﺍﻟﻘﺮﺍءﺓ ﻭ ﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﻧﻈﺎﻡ 21‪. . . . . . . . . . FAT‬‬‫٧٦‬ ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫٧٦‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.١. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ . . . . . . . . . . . . . . . . . .‬‫٨٦‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.١.١. ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ‪. . . Global Descriptor Table‬‬‫٢٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.١.٢. ﺍﻟﻌﻨﻮﻧﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ‪. PMode Memory Addressing‬‬‫٢٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.١.٣. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ . . . . . . . . . . . . .‬‫٤٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٢. ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ 02‪. . . . . . . . . . . . . . . . . . . . . A‬‬‫٤٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٢.١. ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ 2408 ﻭﺍﻟﺒﻮﺍﺑﺔ 02‪. . . . . . . A‬‬‫٥٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٢.٢. ﻃﺮﻕ ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ 02‪. . . . . . . . . . . . . . A‬‬‫١٨‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ ‪. . . . . . . . . . . . . . . . . . . . . VGA‬‬‫٢٨‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٣.١. ﻋﻨﻮﻧﺔ ﺍﻟﺬﺍﻛﺮﺓ ﰲ ﻣﺘﺤﻜﻤﺎﺕ ‪. . . . . . . . . . VGA‬‬‫٣٨‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٣.٢. ﻃﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ . . . . . . . . . . . . .‬‫٧٨‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٣.٣. ﻃﺒﺎﻋﺔ ﺍﻟﺴﻼﺳﻞ ﺍﻟﻨﺼﻴﺔ ‪. . . . . . . . . . . strings‬‬‫٩٨‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٣.٤. ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ ‪. . . . . . . . . . Hardware Cursor‬‬‫٢٩‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٣.٥. ﺗﻨﻈﻴﻒ ﺍﻟﺸﺎﺷﺔ ‪. . . . . . . . . . . Clear Screen‬‬‫٣٩‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٤.٤. ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ . . . . . . . . . . . . . . . . . . . . . . . .‬‫١٠١‬ ‫‪Kernel‬‬ ‫‪ .III‬ﺍﻟﻨﻮﺍﺓ‬‫٣٠١‬ ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫٣٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.١. ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ . . . . .‬‫٤٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.١.١. ﻣﺴﺘﻮﻳﺎﺕ ﺍﻟﺘﺠﺮﻳﺪ‬‫٥٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٢. ﻭﻇﺎﺋﻒ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ . . . . .‬‫٥٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٢.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ . .‬‫٦٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٣. ﻫﻴﻜﻠﺔ ﻭﺗﺼﻤﻴﻢ ﺍﻟﻨﻮﺍﺓ . . . .‬‫٦٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٣.١. ﺍﻟﻨﻮﺍﺓ ﺍﻟﻀﺨﻤﺔ ‪Monolithic Kernel‬‬‫٧٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٣.٢. ﺍﻟﻨﻮﺍﺓ ﺍﳌﺼﻐﺮﺓ ‪. . . MicroKernel‬‬ ‫ﺩ‬
    • ‫ﺍﳌﺤﺘﻮﻳﺎﺕ‬‫٧٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٣.٣. ﺍﻟﻨﻮﺍﺓ ﺍﳍﺠﻴﻨﺔ ‪. Hybrid Kernel‬‬‫٧٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ . . . . . . . . . . .‬‫٨٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٤.١. ﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﻧﻮﺍﺓ ‪. . . . PE‬‬‫١١١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٤.٢. ﺗﻄﻮﻳﺮ ﺑﻴﺌﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻠﻐﺔ ﺳﻲ++‬‫٦١١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٤.٣. ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﻨﻮﺍﺓ . . . .‬‫٧١١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٥. ﻧﻈﺮﺓ ﻋﻠﻰ ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ . . . . . . .‬‫٨١١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٥.٦. ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﺍﻟﻘﻴﺎﺳﻴﺔ . . . . . . . . .‬‫٣٢١‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ ‪Interrupts‬‬‫٣٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ ‪. So ware Interrupts‬‬‫٣٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.١.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ .‬‫٥٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.١.٢. ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ .‬‫٧٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.١.٣. ﺃﺧﻄﺎء ﺍﳌﻌﺎﰿ . . . . . . .‬‫٩٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.١.٤. ﺇﻧﺸﺎء ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ‪GDT‬‬‫٣٣١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٢. ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ ‪Programmable Interrupt Controller‬‬‫٣٣١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٢.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ‪. . . . . . . . Hardware Interrupts‬‬‫٤٣١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٢.٢. ﺑﺮﳎﺔ ﻣﺘﺤﻜﻢ ‪. . . . . . . . . . . . . . . . . PIC‬‬‫١٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٣. ﺍﳌﺆﻗﺘﺔ ‪. . . . . . . . . . . . . Programmable Interval Timer‬‬‫٢٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٣.١. ﺑﺮﳎﺔ ﺍﳌﺆﻗﺘﺔ ‪. . . . . . . . . . . . . . . . . . PIT‬‬‫٥٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ ‪. . . . . . . . . . . . . . . . . . . . . . . HAL‬‬‫٥٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٤.١. ﺩﻋﻢ ‪. . . . . . . . . . . . . . . . . . . . . PIC‬‬‫٩٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٤.٢. ﺩﻋﻢ ‪. . . . . . . . . . . . . . . . . . . . . PIT‬‬‫٢٥١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٦.٤.٣. ﻭﺍﺟﻬﺔ ‪ HAL‬ﺍﳉﺪﻳﺪﺓ . . . . . . . . . . . . . . . .‬‫١٦١‬ ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬‫١٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫‪Physical Memory Management‬‬ ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬‫٢٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٧.١.١. ﺣﺴﺎﺏ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ . . . . . . . . .‬‫٤٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٧.١.٢. ﺧﺮﻳﻄﺔ ﺍﻟﺬﺍﻛﺮﺓ ‪. . . . . Memory Map‬‬‫٧٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٧.١.٣. ﻣﻮﺍﺻﻔﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ . . . . . . .‬‫١٧١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٧.١.٤. ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ . . . . . . . . .‬‫٧٧١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫٧.٢. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ ‪Virtual Memory Management‬‬‫٣٨١‬ ‫‪Device Driver‬‬ ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬‫. . . . . . . . . . . . . . . ٣٨١‬ ‫‪Keyboard Driver‬‬ ‫٨.١. ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬‫٥٩١‬ ‫ﺗﺮﲨﺔ ﻭﺗﺸﻐﻴﻞ ﺍﻟﱪﺍﻣﺞ‬ ‫ﺍ.‬‫ﺍ.١. ﻧﻈﺎﻡ ﻭﻳﻨﺪﻭﺯ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ٥٩١‬‫ﺍ.٢. ﻧﻈﺎﻡ ﻟﻴﻨﻮﻛﺲ . . . . . . . . . . . . . . . . . . . . . . . . . . . . ٥٩١‬‫ﻫ‬
    • ‫ﺍﳌﺤﺘﻮﻳﺎﺕ‬‫٧٩١‬ ‫ﺏ. ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ‬ ‫ﻭ‬
    • ‫ﺍﻷﻣﺜﻠﺔ ﺍﻟﺘﻮﺿﻴﺤﻴﺔ‬٤ . . . . . . . . . . . . . . . . . . . . . . . . . Assembly Language .١.١٣٧ . . . . . . . . . . . . . . . . . . . . . . . . Smallest Bootloader .٣.١٣٧ . . . . . . . . . . . . . . . . . . . . . . . . Welcom to OS World .٣.٢٤٠ . . . . . . . . . . . . . . . . . . . . . . . . Bios Parameter Block .٣.٣٤١ . . . . . . . . . . . . . . . . . . . . . . . . . . . . BPB example .٣.٤٤٤ . . . . . . . . . . . . . . . . . . . . . . . Hex value of bootloader .٣.٥٤٥ . . . . . . . . . . . . . . . . . . . . . . . . . Complete Example .٣.٦٤٨ . . . . . . . . . . . . . . . . . . . . . . . . . Reset Floppy Drive .٣.٧٤٩ . . . . . . . . . . . . . . . . . . . . . . Read Floppy Disk Sectors .٣.٨٥٥ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hello Stage2 .٣.٩٥٧ . . . . . . . . . . . . . . . . . . . . . . . . . Load Root directory .٣.١٠٥٨ . . . . . . . . . . . . . . . . . . . . . . . Find Stage2 Bootloader .٣.١١٥٩ . . . . . . . . . . . . . . . . . . . . . . . . . . . Load FAT Table .٣.١٢٦٠ . . . . . . . . . . . . . . . . . . . Convert Cluster number to LBA .٣.١٣٦٠ . . . . . . . . . . . . . . . . . . . . . . . . . Convert LBA to CHS .٣.١٤٦١ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Load Cluster .٣.١٥٦٢ . . . . . . . . . . . . . . . . . . . . . . . . Read Sectors Rou ne .٣.١٦٦٤ . . . . . . . . . . . . . . . . . . . . . . . . . . . Read FAT entry .٣.١٧٦٩ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GDT .٤.١٧١ . . . . . . . . . . . . . . . . . . . . . . . . Load GDT into GDTR .٤.٢٧٣ . . . . . . . . . . . . . . . . . . . . Switching to Protected Mode .٤.٣٧٥ . . . . . . . . . . . . . . . Enable A20 by System Control Port 0x92 .٤.٤٧٦ . . . . . . . . . . . . . . . . . . . . . Enable A20 by BIOS int 0x15 .٤.٥٧٧ . . . . . . . . . . . . . . . . . . . . . . . . . Wait Input/Output .٤.٦٧٨ . . . . . . . . . . . . . . . . . . . . . . Enable A20 by Send 0xdd .٤.٧٨٠ . . . . . . . Enable A20 by write to output port of Keyboard Controller .٤.٨٨٣ . . . . . . . . . . . . . . . . . . . . . Print A character on screen .٤.٩٨٥ . . . . . . . . . . . . . . . . . . . . . . . . . . putch32 rou ne .٤.١٠٨٧ . . . . . . . . . . . . . . . . . . . . . . . . . . . puts32 rou ne .٤.١١٩٠ . . . . . . . . . . . . . . . . . . . . . . . Move Hardware Cursor .٤.١٢٩٢ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Clear Screen .٤.١٣٩٣ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hello Kernel .٤.١٤‫ﺯ‬
    • ‫ﺍﻷﻣﺜﻠﺔ ﺍﻟﺘﻮﺿﻴﺤﻴﺔ‬٩٥ .............. Loading and Execu ng Kernel: Full Example .٤.١٥١٠٨ . . . . . . . . . . . . . . . . . . . . . Portable Executable Header .٥.١١١٠ . . . . . . . . . . . . . . . . . . . . . . . . Ge ng Kernel entry .٥.٢١١١ . . . . . . . . . . . . . . . . . . . . . Global new/delete operator .٥.٣١١٢ . . . . . . . . . . . . . . . . . . . Pure virtual func on call handler .٥.٤١١٢ . . . . . . . . . . . . . . . . . . . . . . . Floa ng Point Support .٥.٥١١٣ . . . . . . . . . . . . . . . . . . . . . . . . . . Object Ini alizer .٥.٦١١٤ . . . . . . . . . . . . . . . . . . . . . . . . . . . Delete Object .٥.٧١١٦ . . . . . . . . . . . . . . . . . . . . . . . . Kernel Entry rou ne .٥.٨١١٨ . . . . . . . . . . . . . . . . null.h:Defini on of NULL in C and C++ .٥.٩١١٩ . . . . . . . . . . . . . . . . . size t.h:Defini on of size t in C/C++ .٥.١٠١٢٠ . . . . . . . . . . . . . . . . . . . . . . stdint.h:typedef data type .٥.١١١٢٠ . . . . . . . . . . . . . . . . . . . . cstdint:C++ typedef data type .٥.١٢١٢١ . . . . . . . . . . . . . . . . . . ctype.h:determine character type .٥.١٣١٢٦ . . . . . . . . . . . . . . . . . . . Example of interrupt descriptor .٦.١١٢٦ . . . . . . . . . . . . . . . . . . . . . . . . Value to put in IDTR .٦.٢١٢٩ . . . . . . . . . . include/hal.h:Hardware Abstrac on Layer Interface .٦.٣١٣٠ . . . . . . . . . . . . . . . . . . . . . . . hal/gdt.cpp:Install GDT .٦.٤١٣٧ . . . . . . . . . . . . . . . . . . . . Ini aliza on Control Words 1 .٦.٥١٣٨ . . . . . . . . . . . . . . . . . . . . Ini aliza on Control Words 2 .٦.٦١٣٨ . . . . . . . . . . . . . . . . . . . . Ini aliza on Control Words 3 .٦.٧١٣٩ . . . . . . . . . . . . . . . . . . . . Ini aliza on Control Words 4 .٦.٨١٤٠ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Send EOI .٦.٩١٤٤ . . . . . . . . . . . . . . . . . . . . . . . . . . PIT programming .٦.١٠١٤٥ . . . . . . . . . . . . . . . . . . . . . . . hal/pic.h: PIC Interface .٦.١١١٤٧ . . . . . . . . . . . . . . . . . . . hal/pic.cpp: PIC Implementa on .٦.١٢١٤٩ . . . . . . . . . . . . . . . . . . . . . . . hal/pit.h: PIt Interface .٦.١٣١٥٠ . . . . . . . . . . . . . . . . . . . hal/pit.cpp: PIT Implementa on .٦.١٤١٥٢ . . . . . . . . . . . . . . . . . . . . . . . . . New HAL Interface .٦.١٥١٥٣ . . . . . . . . . . . . . . . . . . . . . . New HAL Impelmenta on .٦.١٦١٥٦ . . . . . . . . . . . . . . . . . . . . . . . . . . kernel/main.cpp .٦.١٧١٥٦ . . . . . . . . . . . . . . . . . . . . . . . . . kernel/excep on.h .٦.١٨١٥٨ . . . . . . . . . . . . . . . . . . . . . . . . kernel/excep on.cpp .٦.١٩١٥٨ . . . . . . . . . . . . . . . . . . . . . . . . . . kernel/panic.cpp .٦.٢٠١٦٢ . . . . . . . . . . . . . . . . . Using int 0x12 to get size of memory .٧.١١٦٣ . . . . . . . . . Using int 0x15 Func on 0xe801 to get size of memory .٧.٢١٦٥ . . . . . . . . . . . . . . . . . . . . Memory Map Entry Structure .٧.٣١٦٥ . . . . . . . . . . . . . . . . . . . . . . . . . Get Memory Map .٧.٤ ‫ﺡ‬
    • ‫ﺍﻷﻣﺜﻠﺔ ﺍﻟﺘﻮﺿﻴﺤﻴﺔ‬١٦٨ . . . . . . . . . . . . . . . . . . . Mul boot Inforam on Structure .٧.٥١٦٩ . . . . . . . . . . . . . . . . . . . snippet from stage2 bootloader .٧.٦١٧٠ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Kernel Entry .٧.٧١٧١ . . . . . . . . . . . . . . . . . Physical Memory Manager Interface .٧.٨١٧١ . . . . . . . . . . . . . . Physical Memory Manager Implemeta on .٧.٩١٧٧ . . . . . . . . . . . . . . . . . . Virtual Memory Manager Interface .٧.١٠١٧٨ . . . . . . . . . . . . . . . Virtual Memory Manager Implemeta on .٧.١١١٨٣ . . . . . . . . . . . . . . . . . . . . . . Keybaord Driver Interface .٨.١١٨٧ . . . . . . . . . . . . . . . . . . . Keybaord Driver Implemeta on .٨.٢‫ﻁ‬
    • ‫ﻗﺎﺋﻤﺔ ﺍﻷﺷﻜﺎﻝ‬‫٣‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﻟﺸﻜﻞ ﺍﻟﻌﺎﻡ ﻷﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ 68‪. . . . . . x‬‬ ‫١.١.‬‫٥‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﻃﺒﻘﺎﺕ ﺍﳊﺎﺳﺐ . . . . . . . . . . . .‬ ‫١.٢.‬‫٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺁﻟﺔ ﺑﺎﺳﻜﺎﻝ . . . . . . . . . . . . . .‬ ‫١.٣.‬‫٧‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺁﻟﺔ ‪ Step Reckoner‬ﰲ ﻣﺘﺤﻒ ﺑﺄﳌﺎﻧﻴﺎ . . .‬ ‫١.٤.‬‫٨‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﳏﺮﻙ ﺍﻟﻔﺮﻭﻕ ﺑﻌﺪ ﺃﻥ ﻗﺎﻡ ﺍﺑﻦ ﺑﺎﺑﺒﺎﺝ ﺑﺘﺠﻤﻴﻌﻪ .‬ ‫١.٥.‬‫٩‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳌﺤﺮﻙ ﺍﻟﺘﺤﻠﻴﻠﻲ ﲟﺘﺤﻒ ﰲ ﻟﻨﺪﻥ . . . . .‬ ‫١.٦.‬‫٩‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺣﺎﺳﺒﺔ 1‪ Z‬ﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺍﻧﺸﺎﺋﻬﺎ ﰲ ﻣﺘﺤﻒ ﺑﺄﳌﺎﻧﻴﺎ‬ ‫١.٧.‬‫٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺣﺎﺳﺒﺔ ‪ Atanasoff‬ﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺍﻧﺸﺎﺋﻬﺎ ﰲ ﺟﺎﻣﻌﺔ ‪Iowa State‬‬ ‫١.٨.‬‫٠١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺣﺎﺳﺒﺔ ‪. . . . . . . . . . . . . . . Harvard Mark I‬‬ ‫١.٩.‬‫١١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺁﻟﺔ ﺇﳒﻤﺎ ﺍﻷﳌﺎﻧﻴﺔ ﻟﺘﺸﻔﲑ ﺍﻟﺮﺳﺎﺋﻞ ﻭﻓﻜﻬﺎ . . . . . . . . .‬ ‫١.٠١.‬‫٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳊﺎﺳﺒﺔ ‪ colossus‬ﺍﻟﱵ ﻛﺴﺮﺕ ﺷﻔﺮﺓ ﺇﳒﻤﺎ . . . . . . .‬ ‫١.١١.‬‫٢١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳊﺎﺳﺒﺔ ‪. . . . . . . . . . . . . . . . . . ENIAC‬‬ ‫١.٢١.‬‫٣١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳊﺎﺳﺒﺔ ‪. . . . . . . . . . . . . . . . . . EDVAC‬‬ ‫١.٣١.‬‫٥١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ 68‪. . . . . . x‬‬ ‫٢.١.‬‫٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳌﺴﺎﺭﺍﺕ ﰲ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﺸﺨﺼﻴﺔ 68‪x‬‬ ‫٢.٢.‬‫٨١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ . . . . . . . . . .‬ ‫٢.٣.‬‫٤٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺗﺪﺍﺧﻞ ﺍﳌﻘﺎﻃﻊ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ . .‬ ‫٢.٤.‬‫٥٢‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺣﻠﻘﺎﺕ ﺍﳌﻌﺎﰿ . . . . . . . . . .‬ ‫٢.٥.‬‫٦٣‬ ‫٣.١. ﳐﻄﻂ ﳏﺘﻮﻳﺎﺕ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ . . . . . . . . . . . . . . . . . . . . .‬‫١٥‬ ‫٣.٢. ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ 21‪ FAT‬ﻋﻠﻰ ﺍﻟﻘﺮﺹ . . . . . . . . . . . . . . . . . . . . .‬‫٤.١. ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺃﺛﻨﺎء ﺍﻟﻌﻤﻞ . . . . . . . . . . . . . . . . . . . . . . . . ٠٠١‬‫٤.٢. ﺑﺪء ﺗﻨﻔﻴﺬ ﺍﻟﻨﻮﺍﺓ . . . . . . . . . . . . . . . . . . . . . . . . . . . ٠٠١‬‫٣٣١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫‪8259A‬‬ ‫ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫٦.١.‬‫٥٣١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﻣﺸﺎﺑﻚ ﻣﺘﺤﻜﻢ ‪. . . . . . PIC‬‬ ‫٦.٢.‬‫٢٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﳌﺆﻗﺘﺔ ﺍﻟﻘﺎﺑﻠﺔ ﻟﻠﱪﳎﺔ 3528 . . . .‬ ‫٦.٣.‬‫٢٤١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﻣﺸﺎﺑﻚ ﺍﳌﺆﻗﺘﺔ ‪. . . . . . . PIT‬‬ ‫٦.٤.‬‫٩٥١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﻭﺍﺟﻬﺔ ﺍﻟﻨﻈﺎﻡ ﺑﻌﺪ ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ ‪HAL‬‬ ‫٦.٥.‬‫٠٦١‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻹﻓﺘﺮﺍﺿﻴﺔ . .‬ ‫٦.٦.‬‫ﻳﺎ‬
    • ‫ﻗﺎﺋﻤﺔ ﺍﳉﺪﺍﻭﻝ‬‫٠٢‬ ‫..‬ ‫...........‬ ‫.‬ ‫.‬ ‫.‬ ‫ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ ﳊﻮﺍﺳﻴﺐ 68‪. . . . . . x‬‬ ‫٢.١.‬‫١٢‬ ‫..‬ ‫...........‬ ‫.‬ ‫.‬ ‫.‬ ‫ﻣﻨﺎﻓﺬ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﳊﻮﺍﺳﻴﺐ 68‪. x‬‬ ‫٢.٢.‬‫٦٢‬ ‫..‬ ‫...........‬ ‫.‬ ‫.‬ ‫.‬ ‫ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﺗﺘﻄﻠﺐ ﺻﻼﺣﻴﺔ ﺍﳊﻠﻘﺔ ﺻﻔﺮ .‬ ‫٢.٣.‬ ‫٤..٢‬ ‫‪ EFLAGS‬ﺍﻷﻋﻼﻡ ﻣﺴﺠﻞ‬ ‫.‬ ‫.‬ ‫.‬ ‫...................‬ ‫٩٢ . .‬ ‫١..٦‬ ‫. ‪Interrupt Vector Table‬‬‫٤٢١ . . . . . . . . . . . . . . . . . . . . . . .‬‫. . ٨٢١‬ ‫٦.٢. ‪. . . . . . . . . . . . . . . . . x86 Processor Excep ons Table‬‬‫. . ٤٣١‬ ‫٦.٣. ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩ ﳊﻮﺍﺳﻴﺐ 68‪. . . . . . . . . . . . . . . . . . . x‬‬‫. . ٦٣١‬ ‫٦.٤. ﻣﺴﺠﻞ ‪. . . . . . . . . . . . . . . . . . . . . . . IRR/ISR/IMR‬‬‫. . ٦٣١‬ ‫٦.٥. ﻋﻨﺎﻭﻳﻦ ﺍﳌﻨﺎﻓﺬ ﳌﺘﺤﻜﻢ ‪. . . . . . . . . . . . . . . . . . . . . PIC‬‬‫. . ٧٣١‬ ‫٦.٦. ﺍﻷﻣﺮ ﺍﻷﻭﻝ 1‪. . . . . . . . . . . . . . . . . . . . . . . . ICW‬‬ ‫٧..٦‬ ‫٨٣١ . . . . . . . . . . . ‪ ICW3 for Primary PIC‬ﺍﻟﺮﺋﻴﺴﻲ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻟﺚ ﺍﻷﻣﺮ‬ ‫٨..٦‬ ‫٨٣١ . . . . . . . . . . . . . ‪ ICW3 for Slave PIC‬ﺍﻟﺜﺎﻧﻮﻱ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻟﺚ ﺍﻷﻣﺮ‬ ‫٩..٦‬ ‫٩٣١ . . . . . . . . . . . . . . . . . . . . . . . . . . 4‪ ICW‬ﺍﻟﺮﺍﺑﻊ ﺍﻷﻣﺮ‬‫. . ٠٤١‬ ‫٦.٠١. ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ ﺍﻟﺜﺎﱐ 2‪. . . . . . . . . . . . . . . . . . . . . OCW‬‬‫. . ٠٤١‬ ‫٦.١١. ﺃﻣﺮ 2‪. . . . . . . . . . . . . . . . . . . . . . . . . . . OCW‬‬‫. . ٣٤١‬ ‫٦.٢١. ﻣﺴﺠﻼﺕ ﺍﳌﺆﻗﺘﺔ ‪. . . . . . . . . . . . . . . . . . . . 8253 PIT‬‬‫ﻳﺞ‬
    • ‫ﻣﻠﺨﺺ ﺍﻟﺒﺤﺚ‬‫ﻫﺪﻑ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﻫﻮ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ )ﻧﻈﺎﻡ ﺇﻗﺮﺃ( ﻟﻺﺳﺘﺨﺪﺍﻣﺎﺕ ﺍﻟﺘﻌﻠﻴﻤﻴﺔ ﻭﺍﻷﻛﺎﺩﳝﻴﺔ ﲝﻴﺚ ‪‬ﻤ ﱢﻦ ﺍﻟﻄﺎﻟﺐ‬ ‫ﻳﻜ‬‫ﻣﻦ ﺗﻄﺒﻴﻖ ﻣﺎ ﺗﻌﻠﻤﻪ ﻣﻦ ﻧﻈﺮﻳﺎﺕ ﺧﻼﻝ ﻓﺘﺮﺓ ﺍﻟﺪﺭﺍﺳﺔ ﻋﻠﻰ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﺣﻘﻴﻘﻲ ﳑﺎ ﻳﻜﺴﺒﻪ ﺧﱪﺓ ﻭﻳﺆﻫﻠﻪ ﻟﻠﻤﺸﺎﺭﻛﺔ‬‫ﰲ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺗﺸﻐﻴﻞ ﺿﺨﻤﺔ ﻣﺜﻞ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ. ﻛﺬﻟﻚ ﻳﻬﺪﻑ ﺍﱃ ﺗﻮﻓﲑ ﲝﺜﺎ ﺑﺎﻟﻠﻐﺔ ﺍﻟﻌﺮﺑﻴﺔ ﻳﺸﺮﺡ ﺍﻷﺳﺲ‬‫ﺍﻟﻌﻠﻤﻴﺔ ﻟﻜﻴﻔﻴﺔ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻣﻦ ﺍﻟﺼﻔﺮ ﺩﻭﻥ ﺍﻹﻋﺘﻤﺎﺩ ﻋﻠﻰ ﺃﻱ ﻣﻜﻮﻧﺎﺕ ﺧﺎﺭﺟﻴﺔ ﰲ ﺍﻟﻮﻗﺖ ﺍﻟﺬﻱ ﺗﻨﺪﺭ‬‫ﺗﻮﻓﺮ ﻣﺜﻞ ﻫﺬﻩ ﺍﻟﺒﺤﻮﺙ ﺍﳌﻔﻴﺪﺓ ﻟﻠﻄﺎﻟﺐ ﻭﺧﺎﺻﺔ ﰲ ﻫﺬﺍ ﺍﳌﺠﺎﻝ ﺍﻟﺬﻱ ﻳﻌﺘﱪ ﻣﻦ ﺃﻫﻢ ﺍﳌﺠﺎﻻﺕ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﻮﺏ.‬‫ﻭﺗﻨﺎﻭﻟﺖ ﻫﺬﻩ ﺍﻟﺪﺭﺍﺳﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺃﺳﺎﺳﻴﺎﺕ ﻭﻣﻔﺎﻫﻴﻢ ﻧﻈﻢ ﺍﻟﺘﺸﻐﻴﻞ ﺑﺪءﺍ ﻣﻦ ﻣﺮﺣﻠﺔ ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﺍﻹﻧﺘﻘﺎﻝ‬ ‫ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﺍﻧﺘﻬﺎءﺍ ﺑﱪﳎﺔ ﻣﺪﻳﺮﺍ ﻟﻠﺬﺍﻛﺮﺓ ﻭﺗﻌﺮﻳﻔﺎﺕ ﻟﺒﻌﺾ ﺍﻟﻌﺘﺎﺩ.‬‫ﻭ ﺭﺅﻳﺔ ﺍﻟﺒﺎﺣﺚ ﰲ ﻫﺬﻩ ﺍﻟﺪﺭﺍﺳﺔ ﻫﻲ ﺃﻥ ﺗﺴﺘﺨﺪﻡ ﻛﻤﻨﻬﺞ ﻟﺘﺪﺭﻳﺲ ﺍﻟﻄﻼﺏ ﰲ ﻣﺎﺩﺓ ﻧﻈﻢ ﺍﻟﺘﺸﻐﻴﻞ ﻭﺃﻥ ‪‬ﺪ ﱠﺱ‬ ‫ﺗﺭ‬‫ﺍﻟﺸﻔﺮﺓ ﺍﳌﺼﺪﺭﻳﺔ ﻟﻠﻨﻈﺎﻡ . ﻭﻻ ‪‬ﻘﺘﺼﺮ ﻋﻠﻰ ﺫﻟﻚ ﺑﻞ ﻳ‪‬ﺴﺘﻤﺮ ﺍﻟﺘﻄﻮﻳﺮ ﰲ ﺍﻟﻨﻈﺎﻡ ﻟﻴﻜﻮﻥ ﺃﺩﺍﺓ ﺗﻌﻠﻴﻤﻴﺔ )ﻣﻔﺘﻮﺣﺔ‬ ‫ﻳ‬ ‫ﺍﳌﺼﺪﺭ( ﻟﻠﻄﻼﺏ ﻭﺍﻟﺒﺎﺣﺜﲔ.‬‫ﻳﻪ‬
    • ‫ﻣﻘﺪﻣﺔ ﺍﻟﺒﺤﺚ‬‫ﺗﻠﻌﺐ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺩﻭﺭﴽ ﻣﻬﻤﺎ ﰲ ﺷﱴ ﳎﺎﻻﺕ ﺍﳊﻴﺎﺓ ﺣﻴﺚ ﺃﺻﺒﺤﺖ ﺃﺣﺪ ﺃﻫﻢ ﺍﻟﺮﻛﺎﺋﺰ ﺍﻷﺳﺎﺳﻴﺔ ﻟﺘﺸﻐﻴﻞ‬‫ﻭﺍﺩﺍﺭﺓ ﺃﻱ ﺟﻬﺎﺯ ﺃﻭ ﻋﺘﺎﺩ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺸﺮﺍﺋﺢ ﺍﻻﻟﺘﻜﺮﻭﻧﻴﺔ ﺍﳌﺘﻜﺎﻣﻠﺔ ، ﻓﺒﺪءﺍ ﻣﻦ ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ ﺍﻟﺸﺨﺼﻲ‬‫ﻭ ﺍﳉﻮﺍﻻﺕ ﻭ ﺍﻷﺟﻬﺰﺓ ﺍﻟﻜﻔﻴﺔ ﻭﺍﳌﻀﻤﻨﺔ )‪ (Embedded Device‬ﻭ ﺃﺟﻬﺰﺓ ﺍﻷﻟﻌﺎﺏ ﻭﺍﻟﺼﺮﺍﻓﺎﺕ ﺍﻵﻟﻴﺔ ﻭﺣﱴ‬‫ﺃﺟﻬﺰﺓ ﺍﻟﻔﻀﺎء ﻭﺍﻟﺪﻭﺭﺍﺕ )‪ (Orbiter‬ﻛﻠﻬﺎ ﺗﻌﻤﻞ ﺑﺄﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ. ﻭﻧﻈﺮﴽ ﻟﺬﻟﻚ ﻓﺎﻥ ﳎﺎﻝ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫ﻳﻌﺘﱪ ﻣﻦ ﺃﻫﻢ ﺍﳌﺠﺎﻻﺕ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﺐ ﺍﻟﱵ ﳚﺐ ﺃﻥ ﺗﺄﺧﺬ ﻧﺼﻴﺒﻬﺎ ﻣﻦ ﺍﻟﺒﺤﺚ ﺍﻟﻌﻠﻤﻲ ﻭﺍﻟﺘﻄﺒﻴﻖ ﺍﻟﱪﳎﻲ.‬‫ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﳘﻴﺔ ﻫﺬﺍ ﺍﳌﺠﺎﻝ ﺍﻻ ﺍﻧﻪ ﻳﻨﺪﺭ ﻭﺟﻮﺩ ﲝﻮﺛﺎ ﻓﻴﻪ ﻭﻳﻌﻮﺩ ﺫﻟﻚ ﻟﻌﺪﺓ ﺃﺳﺒﺎﺏ: ﺍﻷﻭﻝ ﻫﻮ ﺗﻨﻮﻉ‬‫ﺍﳌﺠﺎﻻﺕ ﺍﻟﱵ ﳚﺐ ﺩﺭﺍﺳﺘﻬﺎ ﻗﺒﻞ ﺍﳋﻮﺽ ﰲ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﺣﻴﺚ ﻻ ﺑﺪ ﻟﻠﻄﺎﻟﺐ ﺃﻭ ﺍﻟﺒﺎﺣﺚ ﺍﻹﳌﺎﻡ ﺑﻠﻐﺔ‬‫ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++ ﻭﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ )‪ (Assembly‬ﺑﺎﻹﺿﺎﻓﺔ ﺍﱃ ﺍﳌﻌﺮﻓﺔ ﺍﻟﺘﺎﻣﺔ ﲟﻌﻤﺎﺭﻳﺔ ﺍﳊﺎﺳﺐ ﻣﻦ ﻣﻌﺎﰿ ﻭﺫﺍﻛﺮﺓ‬‫ﻭﻭﺣﺪﺍﺕ ﺇﺩﺧﺎﻝ ﻭﺇﺧﺮﺍﺝ. ﺃﻣﺎ ﺍﻟﺴﺒﺐ ﺍﻟﺜﺎﱐ ﻓﻬﻮ ﻋﺪﻡ ﺗﻮﻓﺮ ﻣﺮﺍﺟﻊ ﻭﻛﺘﺒﺎ ﺑﺎﻟﻠﻐﺔ ﺍﻟﻌﺮﺑﻴﺔ ﺗﺸﺮﺡ ﺍﻷﺳﺲ ﺍﻟﻌﻠﻤﻴﺔ‬‫ﻟﱪﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ. ﻭﺍﻟﺴﺒﺐ ﺍﻟﺜﺎﻟﺚ ﻫﻮ ﺗﻮﻓﺮ ﻛﻤﻴﺔ ﻛﺒﲑﺓ ﻣﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﰲ ﺍﻟﻮﻗﺖ ﺍﳊﺎﱄ ﲡﻌﻞ ﺍﻟﻄﺎﻟﺐ‬‫ﻳﻌﺘﻘﺪ ﺑﻌﺪﻡ ﺍﳊﻮﺟﺔ ﻟﻠﺒﺤﺚ ﰲ ﻫﺬﺍ ﺍﳌﺠﺎﻝ ﻭﻫﺬﺍ ﻣﻔﻬﻮﻡ ﺧﺎﻃﺊ ﺣﻴﺚ ﺃﻥ ﻣﱪﻣﺞ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻴﺲ ﺑﺎﻟﻀﺮﻭﺭﺓ‬‫ﺃﻥ ﻳﱪﻣﺞ ﻧﻈﺎﻣﺎ ﻣﻦ ﺍﻟﺼﻔﺮ ﻭﺍﳕﺎ ﳝﻜﻦ ﺃﻥ ﻳﻘﻮﻡ ﺑﺎﻟﺘﻌﺪﻳﻞ ﻭﺍﻟﺘﻄﻮﻳﺮ ﰲ ﺃﺣﺪ ﺍﻷﻧﻈﻤﺔ ﺍﳌﻔﺘﻮﺣﺔ ﺍﳌﺼﺪﺭ ﻛﺬﻟﻚ ﺭﲟﺎ‬‫ﻳﻌﻤﻞ ﰲ ﺑﺮﳎﺔ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﱵ ﺗﺘﻄﻠﺐ ﺍﳌﺎﻣﺎ ﺗﺎﻣﺎ ﺑﻔﺎﻫﻴﻢ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻣﺜﻞ ﺑﺮﳎﺔ ﺑﺮﺍﻣﺞ ﺍﺻﻼﺡ ﺍﻟﻘﺎﻃﺎﻋﺎﺕ‬ ‫ﺍﻟﺘﺎﻟﻔﺔ )‪ (Bad Sectors‬ﻭﺍﺳﺘﺮﺟﺎﻉ ﺍﳌﻠﻔﺎﺕ ﺍﳌﻔﻘﻮﺩﺓ ﻭﻏﲑﻫﺎ ﻣﻦ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ.‬‫ﻭﻗﺪ ﻭﺿﻊ ﺍﻟﻜﺎﺗﺐ ﻧﺼﺐ ﻋﻴﻨﻴﻪ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺍﻟﺘﻄﺮﻕ ﻟﻸﻣﻮﺭ ﺍﻟﱪﳎﻴﺔ ﺑﺘﻔﺎﺻﻴﻠﻬﺎ ﻭﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﻛﻴﻔﻴﺔ ﻛﺘﺎﺑﺔ‬‫ﺍﻟﺸﻔﺮﺓ ﻟﻜﻞ ﺟﺰﺋﻴﺔ ﰲ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ . ﻭ ﱂ ﻳﺘﻢ ﺫﻛﺮ ﻛﻞ ﺍﳉﻮﺍﻧﺐ ﺍﻟﻨﻈﺮﻳﺔ ﰲ ﺍﳌﻮﺿﻮﻉ ﻭﻫﺬﺍ ﺑﺴﺒﺐ ﺃﻥ ﺍﻷﻣﻮﺭ‬‫ﺍﻟﻨﻈﺮﻳﺔ ﰲ ﺍﻟﻐﺎﻟﺐ ﺗﺄﺧﺬ ﺑﺎﻟﻄﺎﻟﺐ ﺑﻌﻴﺪﺍ ﻭﲢﺠﺐ ﺭﺅﻳﺘﻪ ﻋﻦ ﺣﻘﻴﻘﺔ ﻋﻤﻞ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ . ﻭﻗﺪ ﰎ ﺑﺮﳎﺔ ﺍﻟﻨﻈﺎﻡ‬‫ﻣﻦ ﺍﻟﺼﻔﺮ ﺩﻭﻥ ﺍﻹﻋﺘﻤﺎﺩ ﻋﻠﻰ ﺃﻱ ﻣﻜﻮﻧﺎﺕ ﺃﻭ ﺷﻔﺮﺍﺕ ﺟﺎﻫﺰﺓ )ﻣﻔﺘﻮﺣﺔ ﺍﳌﺼﺪﺭ( ﻭﻻ ﳝﻜﻦ ﺍﻋﺘﺒﺎﺭ ﻫﺬﺍ ﺇﻋﺎﺩﺓ‬‫ﺍﺧﺘﺮﺍﻉ ﻟﻠﻌﺠﻠﺔ ! ﺑﻞ ﻫﻮ ﺃﺳﺎﺱ ﳝﻜﻦ ﺍﻻﻋﺘﻤﺎﺩ ﻋﻠﻴﻪ ﻭﺗﻌﻠﻴﻢ ﺍﻟﻄﻼﺏ ﻋﻠﻴﻪ ﻭﻫﻜﺬﺍ ﻳﺘﻄﻮﺭ ﺍﳌﺸﺮﻭﻉ ﻭﻳﺘﻘﺪﻡ ﺍﱃ‬ ‫ﺍﻷﻣﺎﻡ ﻭﰲ ﻧﻔﺲ ﺍﻟﻮﻗﺖ ﺗﺰﺩﺍﺩ ﺧﱪﺓ ﺍﻟﻄﺎﻟﺐ ﺍﻟﻌﻤﻠﻴﺔ ﰲ ﺍﳌﺠﺎﻝ.‬‫ﻭ ﳚﺪﺭ ﺑﻨﺎ ﺍﻳﻀﺎﺡ ﺃﻥ ﻫﺪﻑ ﺍﻟﻨﻈﺎﻡ )ﻧﻈﺎﻡ ﺇﻗﺮﺃ( ﻫﻮ ﻟﻼﺳﺘﺨﺪﺍﻣﺎﺕ ﺍﻷﻛﺎﺩﳝﻴﺔ ﻭﺍﻟﺘﻌﻠﻴﻤﻴﺔ ﻭﻟﻴﺲ ﻟﻠﻤﺴﺘﺨﺪﻡ ﺍﻷﺧﲑ‬‫، ﺣﻴﺚ ﺃﻥ ﺍﳍﺪﻑ ﻫﻮ ﺗﻌﻠﻴﻢ ﺍﻟﻄﺎﻟﺐ ﻋﻠﻰ ﻫﺬﻩ ﺍﻷﺩﺍﺓ ﻭﺍﻋﺪﺍﺩﻩ ﻟﻠﻌﻤﻞ ﻋﻠﻰ ﺃﻧﻈﻤﺔ ﺿﺨﻤﺔ ﻣﺜﻞ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ.‬ ‫ﺃﲪﺪ ﻋﺼﺎﻡ ﻋﺒﺪ ﺍﻟﺮﺣﻴﻢ.‬ ‫٠١٠٢/٦/٩٢‬‫ﻳﺰ‬
    • ‫ﺍﻟﻘﺴﻢ ‪.I‬‬‫‪Basics‬‬ ‫ﺍﻷﺳﺎﺳﻴﺎﺕ‬
    • ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ ﻫﻮ ﳎﻤﻮﻋﺔ ﻣﻦ ﺍﻟﺸﺮﺍﺋﺢ ﺍﻹﻟﻜﺘﺮﻭﻧﻴﺔ ﻭﺍﻟﻌﺘﺎﺩﻳﺎﺕ ﻭﺍﳌﺘﺤﻜﻤﺎﺕ ﺍﳌﺮﺗﺒﻄﺔ ﻣﻊ ﺑﻌﻀﻬﺎ ﻟﺘﻮﻓﲑ ﻣﻨﺼﺔ‬‫ﺗﺸﻐﻴﻠﻴﺔ ﻟﻠﱪﺍﻣﺞ ﻭ ﺍﻟﱵ ﺑﺪﻭ‪‬ﺎ ﻟﻦ ﻳﻌﻤﻞ ﻫﺬﺍ ﺍﳉﻬﺎﺯ. ﻭﳝﻜﻦ ﺗﻘﺴﻴﻢ ﺍﻟﱪﺍﻣﺞ ﲝﺴﺐ ﻃﺒﻴﻌﺔ ﻋﻤﻠﻬﺎ ﻭﻭﻇﻴﻔﺘﻬﺎ ﺍﱃ‬‫ﻗﺴﻤﲔ ﳘﺎ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﻭﺍﻟﱵ ﺻﻤﻤﺖ ﺧﺼﻴﺼﴼ ﳊﻞ ﻣﺸﺎﻛﻞ ﺍﳌﺴﺘﺨﺪﻡ ﻭ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﻭﺍﻟﱵ ﺗﺘﺤﻜﻢ ﰲ‬‫ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ، ﻭﻳﻌﺘﱪ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻣﺜﺎﻻ ﻟﱪﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﺣﻴﺚ ﻳﺪﻳﺮ ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ﺑﺎﻹﺿﺎﻓﺔ‬ ‫ﺍﱃ ﻣﻴﺰﺓ ﻣﻬﻤﺔ ﻭﻫﻲ ﺗﻮﻓﺮ ﺑﻴﺌﺔ ﺗﺸﻐﻴﻞ ﻭﳘﻴﺔ )‪ (Virtual Machine‬ﻟﱪﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ.‬‫ﻭﻳﻮﺿﺢ ﺍﻟﺘﻌﺮﻳﻒ ﺍﻟﺴﺎﺑﻖ ﻋﺪﺩﴽ ﻣﻦ ﺍﳌﻔﺎﻫﻴﻢ ﺍﻟﱵ ﳚﺐ ﺍﻟﻮﻗﻮﻑ ﻋﻠﻴﻬﺎ ﻭﺗﻮﺿﺤﻴﻬﺎ ﺑﺸﻜﻞ ﻣﻔﺼﻞ. ﻓﺠﻬﺎﺯ‬‫ﺍﳊﺎﺳﺐ ﻫﻮ ﻣﻨﺼﺔ ﺗﺸﻐﻴﻠﻴﺔ ﺣﻘﻴﻘﻴﺔ ﻟﻸﻭﺍﻣﺮ ﻭﻳﺄﰐ ﺫﻟﻚ ﺑﺴﺒﺐ ﻭﺟﻮﺩ ﻣﺘﺤﻜﻢ ﺧﺎﺹ ﳌﻌﺎﳉﺔ ﺍﻷﻭﺍﻣﺮ ﻭﺗﻨﻔﻴﺬﻫﺎ‬‫، ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﻫﻮ ﺍﳌﻌﺎﰿ )‪ (Processor‬ﺣﻴﺚ ﻳﻌﻤﻞ ﻋﻠﻰ ﺗﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ )ﻣﻦ ﻋﻤﻠﻴﺎﺕ ﺣﺴﺎﺑﻴﺔ ﻭﻣﻨﻄﻘﻴﺔ( ﻭﺇﺭﺳﺎﻝ‬‫ﺍﻟﻨﺘﺎﺋﺞ ﺍﱃ ﺍﻷﻣﺎﻛﻦ ﺍﳌﻄﻠﻮﺑﺔ. ﻭﺗﺴﻤﻰ ﳎﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﻳﻨﻔﺬﻫﺎ ﺍﳌﻌﺎﰿ ﺑﺎﺳﻢ ﺍﻟﱪﺍﻣﺞ، ﻭﺑﺴﺒﺐ ﺗﻜﻠﻔﺔ ﺑﻨﺎء‬‫ﺍﳌﻌﺎﰿ ﻓﺎﻧﻪ ﻏﺎﻟﺒﴼ ﻣﺎ ﻳﺘﻌﺮﻑ ﻋﻠﻰ ﻋﺪﺩﴽ ﻣﻌﻴﻨﺎ ﻣﻦ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﱵ ﺗﻌﺮﻑ ﲟﺠﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ )‪.(Instruc on Set‬‬‫ﻟﺬﻟﻚ ﺣﱴ ﻳﺘﻢ ﺗﻨﻔﻴﺬ ﺃﻭﺍﻣﺮ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﻓﺎ‪‬ﺎ ﳚﺐ ﺃﻥ ‪‬ﻜﺘﺐ ﻭﻓﻘﺎ ﳌﺠﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﻳﺪﻋﻤﻬﺎ ﺍﳌﻌﺎﰿ ١.ﻭﺍﻟﺸﻜﻞ‬ ‫ﺗ‬‫١.١ ﻳﻮﺿﺢ ﳕﻮﺫﺟﴼ ﻋﺎﻣﺎ ﻟﺘﻌﻠﻴﻤﺎﺕ ﻭﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ ﺍﻟﱵ ﺗﺘﻜﻮﻥ ﻣﻨﻬﺎ ﺍﻟﱪﺍﻣﺞ. ﻭﺟﺰءﺍ ﻣﻨﻬﺎ ﻫﻲ ﺍﺧﺘﻴﺎﺭﻳﺔ ﻭﺳﻨﺮﻛﺰ‬ ‫ﻫﻨﺎ ﻋﻠﻰ ﺍﻝ ‪ OPCODE‬ﻭﺍﻟﱵ ﲤﺜﻞ ﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ.‬ ‫68‪x‬‬ ‫ﺷﻜﻞ ١.١.: ﺍﻟﺸﻜﻞ ﺍﻟﻌﺎﻡ ﻷﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ‬‫ﻭﺗﺸﻜﻞ ﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ ﻟﻐﺔ ﺑﺮﳎﻴﺔ ﻣﻦ ﺧﻼﳍﺎ ﳝﻜﻦ ﺑﺮﳎﺔ ﺍﳊﺎﺳﺐ ﻭﻛﺘﺎﺑﺔ ﺍﻟﱪﺍﻣﺞ ﳊﻞ ﻣﺸﺎﻛﻞ ﺍﳌﺴﺘﺨﺪﻡ ، ﻫﺬﻩ‬‫ﺍﻟﻠﻐﺔ ﺗﺴﻤﻰ ﺑﻠﻐﺔ ﺍﻵﻟﺔ )‪ . (Machine Language‬ﻭﺗﺘﻜﻮﻥ ﻫﺬﻩ ﺍﻟﻠﻐﺔ ﻣﻦ ﺍﻟﺮﻣﻮﺯ 0 ﻭ 1 ﺣﻴﺚ ﺃﻥ ﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ‬‫ﻣﺎ ﻫﻲ ﺍﻻ ﺳﻠﺴﻠﺔ ﻣﻌﻴﻨﺔ ﻣﻦ ﻫﺬﻩ ﺍﻟﺮﻣﻮﺯ. ﻓﻤﺜﻼ ﻟﺘﻌﻴﲔ ﺍﻟﻘﻴﻤﺔ 44713 ﻟﻠﻤﺴﺠﻞ ‪ ٢ AX‬ﳚﺐ ﺃﻥ ﳛﻮﻱ ﺍﻟﱪﻧﺎﻣﺞ‬‫ﻋﻠﻰ ﺍﻷﻣﺮ 111000000000001100011101. ﻭﺑﺎﻟﺘﺎﱄ ﺗﻜﻮﻥ ﻋﻤﻠﻴﺔ ﻛﺘﺎﺑﺔ ﺑﺮﻧﺎﻣﺞ ﻣﺘﻜﺎﻣﻞ ‪‬ﺬﻩ ﺍﻟﻠﻐﺔ ﺃﻣﺮﴽ‬ ‫١ﺳﻨﺘﺤﺪﺙ ﻋﻦ ﻣﻌﺎﳉﺎﺕ ﺍﻧﺘﻞ ٢٣ ﺑﺖ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﻧﻈﺮﴽ ﻷ‪‬ﺎ ﺍﻷﻛﺜﺮ ﺍﻧﺘﺸﺎﺭﴽ.‬ ‫٢ﺍﳌﺴﺠﻼﺕ ﻫﻲ ﺫﻭﺍﻛﺮ ﺑﺪﺍﺧﻞ ﺍﳌﻌﺎﰿ.‬‫٣‬
    • ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﰲ ﻏﺎﻳﺔ ﺍﻟﺼﻌﻮﺑﺔ ﻭﻛﺬﻟﻚ ﻣﻬﻤﺔ ﺗﻨﻘﻴﺢ ﺍﻟﱪﻧﺎﻣﺞ ﻭﺗﻄﻮﻳﺮﻩ ﰲ ﺍﳌﺴﺘﻘﺒﻞ ﻫﻲ ﻣﻌﻘﺪﺓ ﺃﻳﻀﺎ. ﻟﺬﻟﻚ ﻇﻬﺮﺕ ﻟﻐﺔ‬‫ﺍﻟﺘﺠﻤﻴﻊ ﳊﻞ ﻫﺬﻩ ﺍﳌﺸﻜﻠﺔ ﺣﻴﺚ ﺃﻥ ﺍﻟﻠﻐﺔ ﺗﺪﻋﻢ ﻣﺴﻤﻴﺎﺕ ﻭﳐﺘﺼﺮﺍﺕ ﻟﻠﻤﺴﺠﻼﺕ ﻭﻷﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ ، ﻓﻤﺜﻼ‬ ‫ﺍﻷﻣﺮ ﺍﻟﺴﺎﺑﻖ ﰲ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻳﻜﻮﻥ ﺑﺎﻟﺼﻮﺭﺓ ﺍﻟﺘﺎﻟﻴﺔ.‬‫‪Example‬‬ ‫‪١.١: Assembly Language‬‬‫١‬ ‫111000000000001100011101 ‪MOV AX,0x7C00 ; Instead of‬‬‫ﻭﺍﻟﺬﻱ ﳚﺐ ﲢﻮﻳﻠﻪ ﺍﱃ ﻟﻐﺔ ﺍﻵﻟﺔ ﺣﱴ ﻳﺘﻤﻜﻦ ﺍﳌﻌﺎﰿ ﻣﻦ ﺗﻨﻔﻴﺬﻩ ، ﻫﺬﺍ ﺍﳌﺤﻮﻝ ﻳﺴﻤﻰ ﺑﺎﳌﺠﻤﻊ ﻭﺍﻟﺬﻱ ﻳﻘﻮﻡ‬‫ﺑﺘﺤﻮﻳﻞ ﺃﻣﺮ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺍﱃ ﻣﺎ ﻳﻘﺎﺑﻠﻪ ﺑﻠﻐﺔ ﺍﻵﻟﺔ ٣. ﻭﱂ ﺗﻨﺠﺢ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﰲ ﺗﻮﻓﲑ ﻟﻐﺔ ﻋﺎﻟﻴﺔ ﺍﳌﺴﺘﻮﻯ ﺗﺒﺴﻂ‬‫ﻋﻤﻠﻴﺔ ﺑﺮﳎﺔ ﺍﻟﱪﺍﻣﺞ ﺑﺸﻜﻞ ﺃﻛﱪ ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃ‪‬ﺎ ﳐﺘﺼﺮﺍﺕ ﻟﻠﻐﺔ ﺍﻵﻟﺔ ﻟﺬﻟﻚ ﺳﺮﻋﺎﻥ ﻣﺎ ﰎ ﺗﻄﻮﻳﺮ ﻟﻐﺎﺕ ﻋﺎﻟﻴﺔ‬‫ﺍﳌﺴﺘﻮﻯ ﻣﺜﻞ ﻟﻐﺔ ﺍﻟﺴﻲ ٤ ﻭﺍﻟﺴﻲ++ ﲝﻴﺚ ﺗﻜﺘﺐ ﺍﻟﱪﺍﻣﺞ ﻓﻴﻬﺎ ﺑﺸﻜﻞ ﻣﺒﺴﻂ ﺑﻌﻴﺪﴽ ﻋﻦ ﺗﻌﻘﻴﺪﺍﺕ ﺍﻵﻟﺔ ﻭﺃﻭﺍﻣﺮﻫﺎ‬‫ﻭﻣﺴﺠﻼ‪‬ﺎ ﻭﺗﺪﻋﻢ ﻫﺬﻩ ﺍﻟﻠﻐﺎﺕ ﻋﺪﺩﺍ ﻣﻦ ﺍﻟﺘﺮﺍﻛﻴﺐ ﻭﲨﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻟﻌﺎﻟﻴﺔ ﺍﳌﺴﺘﻮﻯ. ﻭﻟﻜﻲ ﻳﻨﻔﺬ ﺍﳌﻌﺎﰿ ﺑﺮﺍﻣﺞ‬‫ﻫﺬﻩ ﺍﻟﻠﻐﺎﺕ ﻓﺎﻧﻪ ﳚﺐ ﺃﻭﻻ ﺗﺮﲨﺔ ﺍﻟﺸﻔﺮﺓ ﺍﳌﺼﺪﺭﻳﺔ ﺍﱃ ﻣﺎ ﻳﻘﺎﺑﻠﻬﺎ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺑﺮﻧﺎﻣﺞ‬‫ﻳﺴﻤﻰ ﺍﳌﺘﺮﺟﻢ )‪ (Compiler‬ﻭﺑﻌﺪﻫﺎ ﻳﻘﻮﻡ ﺍﳌﺠﻤﻊ ﺑﺘﺤﻮﻳﻞ ﺷﻔﺮﺓ ﺍﻟﺘﺠﻤﻴﻊ ﺍﱃ ﺑﺮﻧﺎﳎﴼ ﺑﻠﻐﺔ ﺍﻵﻟﺔ ﻭﺍﻟﺬﻱ ﻳﺴﺘﻄﻴﻊ‬ ‫ﺍﳌﻌﺎﰿ ﺗﻨﻔﻴﺬﻩ.‬ ‫ﲞﺼﻮﺹ ﲤﺜﻴﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﱪﺍﻣﺞ ﰲ ﺍﳊﺎﺳﺐ ﻓﺈ‪‬ﺎ ﲤﺜﻞ ﺑﻄﺮﻕ ﳐﺘﻠﻔﺔ ﲣﺘﻠﻒ ﻋﻠﻰ ﺣﺴﺐ ﻭﺣﺪﺓ‬ ‫ﺍﻟﺘﺨﺰﻳﻦ ﻭ ﻟﻜﻨﻬﺎ ﰲ ﺍﻵﺧﺮ ﺗﺴﺘﺨﺪﻡ ﺍﳌﻨﻄﻖ ﺍﻟﺜﻨﺎﺋﻲ ﻭﻫﻮ ﻭﺟﻮﺩ ﻃﺎﻗﺔ ﻛﻬﺮﺑﺎﺋﻴﺔ ﺃﻡ ﻻ ، ﻓﻤﺜﻼ ﺗﺘﻜﻮﻥ‬ ‫ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ‪ DRAM‬ﻣﻦ ﻣﻼﻳﲔ ﺍﳌﻜﺜﻔﺎﺕ )‪ (Capacitors‬ﻭﺍﻟﺘﺮﺍﻧﺰﺳﺘﻮﺭﺍﺕ )‪(Transistors‬‬ ‫ﻟﺘﻜﻮﻳﻦ ﺧﻼﻳﺎ ﺍﻟﺬﺍﻛﺮﺓ )‪ ، (Memory Cells‬ﻭ ﺗﺘﻜﻮﻥ ﻛﻞ ﺧﻠﻴﺔ )ﻭﺍﻟﱵ ﺗﺸﻜﻞ ﺑﺖ ﻭﺍﺣﺪ ﻣﻦ‬ ‫ﺍﻟﺬﺍﻛﺮﺓ( ﻣﻦ ﻣﻜﺜﻒ ﻭﺗﺮﺍﻧﺰﺳﺘﻮﺭ ﲝﻴﺚ ﳛﻔﻆ ﺍﳌﻜﺜﻒ ﻗﻴﻤﺔ ﺍﳋﻠﻴﺔ )ﺍﻟﺒﺖ( ﻭﺍﻟﱵ ﻫﻲ ﺇﻣﺎ ﻭﺟﻮﺩ‬ ‫ﺇﻟﻜﺘﺮﻭﻥ )ﻣﻨﻄﻘﻴﺎ ﺗﺴﺎﻭﻱ 1( ﻭﺇﻣﺎ ﻋﺪﻣﻬﺎ )ﻣﻨﻄﻘﻴﺎ ﺗﺴﺎﻭﻱ 0( ﻭﻳﻌﻤﻞ ﺍﻟﺘﺮﺍﻧﺰﺳﺘﻮﺭ ﻋﻠﻰ ﺗﻐﻴﲑ ﻗﻴﻤﺔ‬ ‫ﺍﳌﻜﺜﻒ . ﻭﻋﻠﻰ ﻫﺬﺍ ﺍﻟﺸﻜﻞ ﲢﻔﻆ ﲨﻴﻊ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﱪﺍﻣﺞ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﻳﺄﰐ ﺩﻭﺭ ﺍﳌﻌﺎﰿ‬ ‫ﻟﺘﻨﻔﻴﺬ ﻫﺬﻩ ﺍﻷﻭﺍﻣﺮ ﺣﻴﺚ ﻳﻘﻮﻡ ﺑﻘﺮﺍﺋﺘﻬﺎ ﻭﻓﻬﻢ ﻭﻇﻴﻔﺘﻬﺎ )‪ (Decode‬ﻭﺗﻨﻔﻴﺬﻫﺎ ﻭﻣﻦ ﰒ ﻳﻘﻮﻡ ﲝﻔﻆ‬ ‫ﺍﻟﻨﺘﺎﺋﺞ. ﻭﻟﻜﻲ ﻳﻨﻔﺬ ﺍﳌﻌﺎﰿ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﻓﺎﻥ ﺍﻟﱪﻧﺎﻣﺞ ﳚﺐ ﺃﻥ ﻳﺘﻮﺍﺟﺪ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﻟﻴﺲ‬ ‫ﻋﻠﻰ ﺃﺣﺪ ﺍﻟﺬﻭﺍﻛﺮ ﺍﻟﺜﺎﻧﻮﻳﺔ )ﻣﺜﻞ ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ(.‬‫ﺣﱴ ﺍﻻﻥ ﱂ ﻧﺬﻛﺮ ﻭﻇﻴﻔﺔ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻷﻥ ﺑﻴﺌﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺍﳊﻘﻴﻘﻴﺔ ﻫﻲ ﺍﳌﻌﺎﰿ ﻭﻟﻴﺴﺖ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺃﻭ ﻏﲑﻩ ﻣﻦ‬‫ﺍﻟﱪﺍﻣﺞ ﻭﻋﻠﻰ ﺍﳌﱪﻣﺞ ﺍﻹﳌﺎﻡ ﺑﻜﻴﻔﻴﺔ ﺑﺮﳎﺔ ﻋﺘﺎﺩ ﻭﻣﺘﺤﻜﻤﺎﺕ ﺍﳊﺎﺳﺐ ﻭﻛﻴﻔﻴﺔ ﻃﺒﺎﻋﺔ ﺍﳌﺨﺮﺟﺎﺕ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ‬‫ﻭﻗﺮﺍءﺓ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻣﻦ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﻻ ﻳﻘﺘﺼﺮ ﻋﻠﻰ ﺫﻟﻚ ﺑﻞ ﻋﻠﻰ ﺍﳌﱪﻣﺞ ﺗﻮﻓﲑ ﻃﺮﻗﺎ ﻭﺩﻭﺍﻻﹰ ﻹﺩﺍﺭﺓ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﻣﻦ ﺣﺠﺰ ﺍﳌﻘﺎﻃﻊ ﻭﲢﺮﻳﺮﻫﺎ ﻭﻛﺬﻟﻚ ﺇﺩﺍﺭﺓ ﲨﻴﻊ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ. ﻛﻞ ﺫﻟﻚ ﳚﻌﻞ ﻋﻤﻠﻴﺔ ﻛﺘﺎﺑﺔ ﺍﻟﱪﺍﻣﺞ‬‫ﻣﺴﺘﺤﻴﻠﺔ ﻭﻫﺬﺍ ﻣﺎ ﺃﺩﻯ ﺍﱃ ﻇﻬﻮﺭ ﻃﺒﻘﺔ ﺑﺮﳎﻴﺔ )‪ (Layer‬ﺗﺪﻳﺮ ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ﻭﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ ﻟﻠﻤﱪﻣﺞ‬ ‫٣ﻛﻞ ﺃﻣﺮ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻳﻘﺎﺑﻠﻪ ﺃﻣﺮﴽ ﻭﺍﺣﺪﴽ ﺑﻠﻐﺔ ﺍﻵﻟﺔ ﻟﺬﻟﻚ ﺣﻘﻴﻘﺔ ﻻ ﻳﻮﺟﺪ ﻓﺮﻗﴼ ﰲ ﺃﺩﺍء ﺍﻟﱪﺍﻣﺞ ﺍﳌﻜﺘﻮﺑﺔ ﺑﺄﻱ ﻣﻨﻬﻢ ﻭﻻ ﰲ ﺣﺠﻢ‬ ‫ﺍﳌﻠﻒ ﺍﻟﻨﺎﺗﺞ ، ﻭﺇﳕﺎ ﻳﻈﻬﺮ ﺍﻟﻔﺮﻕ ﰲ ﺳﻬﻮﻟﺔ ﺗﻄﻮﻳﺮ ﺍﻟﱪﺍﻣﺞ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻭﻟﻜﻦ ﻋﻠﻰ ﺣﺴﺎﺏ ﺃﻧﻪ ﳚﺐ ﲢﻮﻳﻠﻬﺎ ﻋﻦ ﻃﺮﻳﻖ ﺍﳌﺠﻤﻊ.‬ ‫٤ﰎ ﺗﻄﻮﻳﺮ ﻟﻐﺔ ﺍﻟﺴﻲ ‪‬ﺪﻑ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﻳﻮﻧﻴﻜﺲ ‪ Unix‬ﰲ ﻣﻌﺎﻣﻞ ﺑﻴﻞ.‬ ‫٤‬
    • ‫ﻟﻜﻲ ﻳﺘﻌﺎﻣﻞ ﻣﻊ ﻫﺬﻩ ﺍﳌﻮﺍﺭﺩ.ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﲰﻴﺖ ﺑﻨﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ )‪ .(Opera ng System‬ﺍﳍﺪﻑ ﺍﻟﺮﺋﻴﺴﻲ ﳍﺬﻩ‬‫ﺍﻟﻄﺒﻘﺔ ﻫﻲ ﻋﺰﻝ ﺍﳌﱪﻣﺞ ﻋﻦ ﺗﻌﻘﻴﺪﺍﺕ ﺍﻟﻌﺘﺎﺩ ﲝﻴﺚ ﺃﻥ ﺇﺩﺍﺭﺓ ﻫﺬﻩ ﺍﻟﻌﺘﺎﺩﻳﺎﺕ ﺃﺻﺒﺤﺖ ﻣﻦ ﻣﻬﻤﺔ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ‬‫ﻭﰲ ﻧﻔﺲ ﺍﻟﻮﻗﺖ ﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ )ﺃﻭ ﺟﻬﺎﺯ ﲣﻴﻠﻲ( ﻟﻺﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﻟﻌﺘﺎﺩﻳﺎﺕ. ﻭﺍﻟﺸﻜﻞ ١.٢ ﻳﻮﺿﺢ‬‫ﻣﻮﺿﻊ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ )ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ( ﰲ ﺣﺎﻟﺔ ﻗﺴﻤﻨﺎ ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ ﺍﱃ ﻋﺪﺓ ﻃﺒﻘﺎﺕ ]?[. ﻭﺃﺩﱏ ﻃﺒﻘﺔ ﻫﻲ‬ ‫ﺷﻜﻞ ١.٢.: ﻃﺒﻘﺎﺕ ﺍﳊﺎﺳﺐ‬‫ﻃﺒﻘﺔ ﺍﻟﻌﺘﺎﺩﻳﺎﺕ )‪ (Device Level‬ﺣﻴﺚ ﺗﺘﻜﻮﻥ ﻣﻦ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻭﻣﻦ ﺍﻟﺸﺮﺍﺋﺢ ﺍﳌﺘﻜﺎﻣﻠﺔ )‪(Integrated Circuit‬‬‫ﻭﺍﻷﺳﻼﻙ ﻭﻛﻞ ﻣﺎ ﻳﺘﻌﻠﻖ ﺑﺎﻷﺟﻬﺰﺓ ﺍﳌﺎﺩﻳﺔ.ﻳﻠﻲ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﻃﺒﻘﺔ ‪ Microarchitecure‬ﻭﻓﻴﻬﺎ ﺗﻈﻬﺮ ﺑﺮﳝﺠﺎﺕ‬‫)‪ (Mircoprogram‬ﺗﺘﺤﻜﻢ ﰲ ﻋﻤﻞ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻟﻜﻲ ﺗﺆﺩﻱ ﻭﻇﻴﻔﺘﻬﺎ ﻓﻤﺜﻼً ﺑﺮﳝﺞ ﺍﻝ ‪ data path‬ﺑﺪﺍﺧﻞ‬‫ﺍﳌﻌﺎﰿ ﻭﺍﻟﺬﻱ ﻳﻘﻮﻡ ﰲ ﻛﻞ ﺩﻭﺭﺓ ﻟﻠﺴﺎﻋﺔ )‪ (Clock Cycle‬ﲜﻠﺐ ﻗﻴﻤﺘﲔ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﺍﱃ ﻭﺣﺪﺓ ﺍﳊﺴﺎﺏ‬‫ﻭﺍﳌﻨﻄﻖ )‪ (Arithme c Logic Unit‬ﺍﻟﱵ ﲡﺮﻱ ﻋﻠﻴﻬﻢ ﻋﻤﻠﻴﺔ ﻣﺎ ﻭﻣﻦ ﰒ ﺗﻘﻮﻡ ﲝﻔﻆ ﺍﻟﻨﺘﻴﺠﺔ ﰲ ﺃﺣﺪ ﺍﳌﺴﺠﻼﺕ.‬‫ﻭﻇﻴﻔﺔ ‪ data path‬ﻫﻲ ﺗﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﺘﻌﻠﻴﻤﺎﺕ ﻭﺫﻟﻚ ﺑﺎﺭﺳﺎﳍﺎ ﺍﱃ ﻭﺣﺪﺓ ﺍﳊﺴﺎﺏ ﻭﺍﳌﻨﻄﻖ ، ﻭﺗﺸﻜﻞ‬‫ﳎﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺪﻋﻮﻣﺔ ﻭﻛﺬﻟﻚ ﺍﳌﺴﺠﻼﺕ ﺍﳌﺮﺋﻴﺔ ﳌﱪﻣﺞ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻃﺒﻘﺔ ﳎﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ )‪Instruc on‬‬‫‪ (Set Architecture‬ﻭﺗﺴﻤﻰ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﻃﺒﻘﺔ ﺍﻵﻟﺔ )‪ (Machine Language‬ﺣﻴﺚ ﲢﻮﻱ ﻋﻠﻰ ﻛﻞ ﺍﻷﻭﺍﻣﺮ‬‫ﺍﻟﱵ ﻳﺪﻋﻤﻬﺎ ﺍﳌﻌﺎﰿ ﲟﺎ ﻓﻴﻬﺎ ﺃﻭﺍﻣﺮ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﻣﺴﺠﻼﺕ ﻣﺘﺤﻜﻤﺎﺕ ﺍﻟﻌﺘﺎﺩ )‪. (Device Controller‬‬‫ﻭﻳﻠﻲ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﻃﺒﻘﺔ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻭﺍﻟﱵ ﺗﻔﺼﻞ ﻭﺗﻌﺰﻝ ﺍﻟﻌﺘﺎﺩ ﻋﻦ ﺍﳌﺴﺘﺨﺪﻡ ﻓﺒﺪﻻً ﻣﻦ ﺃﻥ ﻳﻘﻮﻡ ﺍﳌﱪﻣﺞ ﺑﱪﳎﺔ‬‫ﻣﺘﺤﻜﻢ ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ ﻭﻧﻈﺎﻡ ﻟﻠﻤﻠﻔﺎﺕ ﺣﱴ ﻳﺘﻤﻜﻦ ﻣﻦ ﻗﺮﺍءﺓ ﻣﻠﻒ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﻓﺎﻥ ﺍﻟﻨﻈﺎﻡ ﻳﻮﻓﺮ ﻭﺍﺟﻬﺔ‬‫ﻣﺒﺴﻄﺔ ﺑﺎﻟﺼﻮﺭﺓ )‪ .read(fd,buffer,size‬ﻭﺃﺧﲑﴽ ﺗﻮﺟﺪ ﻃﺒﻘﺔ ﺍﻟﱪﺍﻣﺞ )ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﻭﺍﳌﺴﺘﺨﺪﻡ(‬‫ﻭﻻ ﺗﺼﻨﻒ ﺍﻟﻜﺜﲑ ﻣﻦ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﺿﻤﻦ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺣﻴﺚ ﺃﻥ ﺍﻟﱪﺍﻣﺞ ﺍﻟﱵ ﺗﺘﺒﻊ ﻟﻨﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﳚﺐ ﺃﻥ‬ ‫ﺗﻌﻤﻞ ﰲ ﻣﺴﺘﻮﻯ ﺍﻟﻨﻮﺍﺓ )‪ (Kernel Mode‬ﻭﻟﻴﺲ ﰲ ﺍﳌﺴﺘﻮﻳﺎﺕ ﺍﻷﺧﺮﻯ ٥.‬ ‫٥ﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﱐ ﺑﺈﺫﻥ ﺍﷲ ﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﻣﺴﺘﻮﻳﺎﺕ ﺍﳊﻤﺎﻳﺔ ﰲ ﺍﳌﻌﺎﳉﺎﺕ.‬‫٥‬
    • ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫١.١. ﻣﺎ ﻫﻮ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﻣﻦ ﺍﻟﺼﻌﺐ ﺇﳚﺎﺩ ﺗﻌﺮﻳﻔﴼ ﻭﺍﺿﺤﴼ ﻷﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻓﻤﺎ ﻳﻌﺘﱪﻩ ﺍﻟﺒﻌﺾ ﺗﺎﺑﻌﴼ ﻟﻨﻈﺎﻡ ﻣﺎ ﻻ ﻳﻌﺘﱪﻩ ﺍﻵﺧﺮﻭﻥ ﻛﺬﻟﻚ.‬‫ﻟﻜﻦ ﻣﺎ ﰎ ﺍﻹﺗﻔﺎﻕ ﻋﻠﻴﻪ ﻫﻮ ﺃﻥ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻳﺪﻳﺮ ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ﻭﻳﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ )ﺟﻬﺎﺯ ﲣﻴﻠﻲ(‬ ‫ﻣﻦ ﺧﻼﳍﺎ ﳝﻜﻦ ﺍﻹﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﳌﻮﺍﺭﺩ.‬ ‫١.١.١. ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻛﺠﻬﺎﺯ ﲣﻴﻠﻲ‬‫ﳑﺎ ﺳﺒﻖ ﳒﺪ ﺃﻥ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﱵ ﺗﻘﺪﻣﻬﺎ ﻃﺒﻘﺔ ﺍﻵﻟﺔ )‪ (Machine Language Level‬ﻫﻲ ﺑﺪﺍﺋﻴﺔ ﻭﻳﺼﻌﺐ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ‬‫ﰲ ﻛﺘﺎﺑﺔ ﺍﻟﱪﺍﻣﺞ ، ﻓﻜﻤﺎ ﺫﻛﺮﻧﺎ ﻛﻤﺜﺎﻝ ﻟﻠﻘﺮﺍءﺓ ﻣﻦ ﻣﻠﻒ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﳚﺐ ﺃﻥ ﳛﻮﻱ ﺍﻟﱪﻧﺎﻣﺞ ﻋﻠﻰ ﺷﻔﺮﺓ ﻟﻨﻈﺎﻡ‬‫ﺍﳌﻠﻔﺎﺕ ﺣﱴ ﻧﻌﺮﻑ ﻋﻨﻮﺍﻥ ﺍﳌﻠﻒ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﻋﻠﻰ ﺍﻟﻘﺮﺹ، ﻭﻛﺬﻟﻚ ﳚﺐ ﺃﻥ ﳛﻮﻱ ﺍﻟﱪﻧﺎﻣﺞ ﻋﻠﻰ ﺷﻔﺮﺓ ﻟﻠﺘﻌﺎﻣﻞ‬‫ﻣﻊ ﻣﺘﺤﻜﻢ ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ ﻭﻫﻲ ﺷﻔﺮﺓ ﻟﻴﺴﺖ ﺑﺎﻟﻴﺴﲑﺓ ﺣﻴﺚ ﻟﻠﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻘﺮﺹ ﳚﺐ ﲢﺪﻳﺪ ﺭﻗﻢ ﺍﳌﻘﻄﻊ‬‫ﻭﺭﻗﻢ ﺍﻟﺮﺃﺱ ﻭﺭﻗﻢ ﺍﳌﺴﺎﺭ ﻭﲢﺪﻳﺪ ﺍﻟﺬﺍﻛﺮﺓ ﺍﳌﺆﻗﺘﺔ )‪ (Buffer‬ﺣﱴ ﻳﺘﻢ ﲢﻤﻴﻞ ﺍﳌﻘﺎﻃﻊ ﺍﻟﻴﻬﺎ.ﻛﻞ ﻫﺬﻩ ﺍﻷﻣﻮﺭ ﻟﻮ‬‫ﺍﺳﺘﻤﺮﺕ ‪‬ﺬﺍ ﺍﻟﺸﻜﻞ ﳌﺎ ﻭﺻﻠﺖ ﺍﻟﺘﻄﺒﻴﻘﺎﺕ ﳌﺎ ﻫﻲ ﻋﻠﻴﻬﺎ ﺍﻻﻥ، ﻟﺬﻟﻚ ﻛﺎﻥ ﺍﳊﻞ ﻫﻮ ﺑﺈﳚﺎﺩ ﻃﺒﻘﺔ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﻭﺍﻟﱵ ﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺃﻭ ﺃﻭﺍﻣﺮ ﻣﺒﺴﻄﺔ ﻭﳎﺮﺩﺓ ﻣﻦ ﺗﻔﺎﺻﻴﻞ ﻭﺗﻌﻘﻴﺪﺍﺕ ﺍﻟﻌﺘﺎﺩ ﻟﻜﻲ ﺗﺴﺘﺨﺪﻣﻬﺎ ﺍﻟﱪﺍﻣﺞ ﺑﺪﻻ ﻣﻦ‬ ‫ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﺗﻮﻓﺮﻫﺎ ﻃﺒﻘﺔ ﺍﻵﻟﺔ .‬ ‫١.١.٢. ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻛﻤﺪﻳﺮ ﻟﻠﻤﻮﺍﺭﺩ ﻭﺍﻟﻌﺘﺎﺩ‬‫ﺑﻌﺪ ﺃﻥ ﰎ ﻋﺰﻝ ﺍﳌﱪﻣﺞ ﺑﻮﺍﺳﻄﺔ ﻃﺒﻘﺔ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻓﺎﻥ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﺗﻘﺪﻡ ﲜﺎﻧﺐ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﱪﳎﻴﺔ ﺇﺩﺍﺭﺓ ﻟﻌﺘﺎﺩ‬‫ﺍﳊﺎﺳﺐ )ﺍﳌﻌﺎﰿ،ﺍﻟﺬﺍﻛﺮﺓ،ﺍﻷﻗﺮﺍﺹ ﺍﻟﺼﻠﺒﺔ ﻭﺍﳌﺮﻧﺔ،ﻛﺮﺕ ﺍﻟﺸﺒﻜﺔ،ﻭﻏﲑﻫﺎ ﻣﻦ ﺍﳌﺘﺤﻜﻤﺎﺕ( ، ﻭﻣﻬﻤﺔ ﺇﺩﺍﺭﺓ ﺍﻟﻌﺘﺎﺩ‬‫ﺗﺘﺮﻛﺰ ﰲ ﺣﺠﺰ ﺍﻟﻌﺘﺎﺩ ﻭﲢﺮﻳﺮﻩ ، ﻓﻤﺜﻼً ﻳﻘﻮﻡ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺑﺈﺩﺍﺭﺓ ﺍﳌﻌﺎﰿ ﻧﻔﺴﻪ ﻭﺫﻟﻚ ﺑﺄﻥ ﳛﺠﺰ ﺍﳌﻌﺎﰿ ﻟﱪﻧﺎﻣﺞ‬‫ﻣﺎ ﻭﻣﻦ ﰒ ﳛﺮﺭ ﺍﳌﻌﺎﰿ ﻭﳛﺠﺰﻩ ﻟﱪﻧﺎﻣﺞ ﺁﺧﺮ )ﺗﻌﺪﺩ ﺍﳌﻬﺎﻡ ‪ (Mul tasking‬ﻭﻛﺬﻟﻚ ﻳﺪﻳﺮ ﺍﻟﻨﻈﺎﻡ ﺃﻫﻢ ﻣﻮﺍﺭﺩ‬‫ﺍﳊﺎﺳﺐ ﻭﻫﻲ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺫﻟﻚ ﲝﺠﺰ ﻣﻘﺎﻃﻊ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ )‪ (Memory Blocks‬ﺑﻨﺎءﴽ ﻋﻠﻰ ﻃﻠﺐ ﺑﺮﺍﻣﺞ‬ ‫ﺍﳌﺴﺘﺨﺪﻡ ﻭﻛﺬﻟﻚ ﻋﻤﻠﻴﺔ ﲢﺮﻳﺮ ﺍﻟﺬﻭﺍﻛﺮ ﻭﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ ﻭﻣﻔﻬﻮﻡ ﺍﻟﺼﻔﺤﺎﺕ.‬ ‫١.٢. ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﺧﻼﻝ ﺳﻨﻮﺍﺕ ﻣﻀﺖ ﺗﻄﻮﺭﺕ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺗﻄﻮﺭﴽ ﻣﻠﺤﻮﻇﴼ ﻣﻦ ﺃﻧﻈﻤﺔ ﺗﺸﻐﻴﻞ ﻟﱪﻧﺎﳎﴼ ﻭﺍﺣﺪﺍ ﺍﱃ ﺃﻧﻈﻤﺔ‬‫ﻣﻮﺯﻋﺔ ﺗﺴﻤﺢ ﺑﺘﺸﻐﻴﻞ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﻋﻠﻰ ﻋﺪﺓ ﺣﻮﺍﺳﻴﺐ ﳐﺘﻠﻔﺔ. ﻫﺬﺍ ﺍﻟﺘﻄﻮﺭ ﺳﺒﺒﻪ ﺍﻟﺮﺋﻴﺴﻲ ﺗﻄﻮﺭ ﺍﳊﺎﺳﺒﺎﺕ‬‫ﻭﺍﳌﻌﺎﳉﺎﺕ ﻭﺍﺯﺩﻳﺎﺩ ﺣﺠﻢ ﺍﻟﺬﻭﺍﻛﺮ ﺑﺸﻜﻞ ﺭﻫﻴﺐ. ﻭﰲ ﻫﺬﺍ ﺍﳉﺰء ﺳﻨﻠﻘﻲ ﻧﻈﺮﺓ ﻋﻠﻰ ﺗﻄﻮﺭ ﺃﺟﻴﺎﻝ ﺍﳊﻮﺍﺳﻴﺐ‬ ‫ﻭﺑﻌﺾ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺍﻟﱵ ﺍﺳﺘﺨﺪﻣﺖ ﰲ ﺗﻠﻚ ﺍﻟﻔﺘﺮﺍﺕ.‬ ‫٦‬
    • ‫١.٢. ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫١.٢.١. ﺍﳉﻴﻞ ﺍﻟﺼﻔﺮﻱ )٤٢٦١-٥٤٩١(: ﺍﳊﻮﺍﺳﻴﺐ ﺍﳌﻴﻜﺎﻧﻴﻜﻴﺔ‬‫ﺃﻭﻝ ﳏﺎﻭﻟﺔ ﻟﺒﻨﺎء ﺁﻟﺔ ﺣﺴﺎﺑﻴﺔ ﻛﺎﻧﺖ ﻣﻦ ﻗﺒﻞ ﺍﻟﻌﺎﱂ ﺍﻟﻔﺮﻧﺴﻲ ﺑﻠﻴﺰ ﺑﺎﺳﻜﺎﻝ ٦ ﰲ ﻋﺎﻡ ٢٤٦١ ﻋﻨﺪﻣﺎ ﻛﺎﻥ ﻋﻤﺮﻩ ٩١‬‫ﻋﺎﻣﴼ ﻭﺫﻟﻚ ﳌﺴﺎﻋﺪﺓ ﻭﺍﻟﺪﻩ ﺍﻟﺬﻱ ﻛﺎﻥ ﻳﻌﻤﻞ ﳏﺼ ﹸ ﻟﻠﻀﺮﺍﺋﺐ ﳌﺼﻠﺤﺔ ﺍﳊﻜﻮﻣﺔ ﺍﻟﻔﺮﻧﺴﻴﺔ.ﻫﺬﻩ ﺍﻵﻟﺔ )ﻭﺗﻌﺮﻑ‬ ‫ﻼ‬ ‫ﺑﺎﻻﺳﻢ ‪ (Pascaline‬ﻫﻲ ﻣﻴﻜﺎﻧﻴﻜﻴﺔ ﺑﺎﻟﻜﺎﻣﻞ ﻭﺗﻮﻓﺮ ﻓﻘﻂ ﻋﻤﻠﻴﺔ ﺍﳉﻤﻊ ﻭﺍﻟﻄﺮﺡ )ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ١.٣(.‬ ‫ﺷﻜﻞ ١.٣.: ﺁﻟﺔ ﺑﺎﺳﻜﺎﻝ‬‫ﻭﺑﻌﺪ ﺣﻮﺍﱄ ٠٣ ﻋﺎﻣﴼ ﻗﺎﻡ ﺍﻟﻌﺎﱂ ﺍﻟﺮﻳﺎﺿﻲ ﺟﻮﺗﻔﺮﻳﺪ ﻟﻴﺒﱰ ‪ Go ried Wilhelm Leibniz‬ﺑﺒﻨﺎء ﺁﻟﺔ ﺣﺴﺎﺑﻴﺔ‬‫ﻣﻴﻜﺎﻧﻴﻜﻴﺔ ﺃﺧﺮﻯ )ﰎ ﺍﻹﻧﺘﻬﺎء ﻣﻨﻬﺎ ﰲ ﻋﺎﻡ ٤٩٦١ ﻭﲰﻴﺖ ﺑﺎﻻﺳﻢ ‪ (Step Reckoner‬ﻭﻟﻜﻦ ﻫﺬﻩ ﺍﳌﺮﺓ ﺃﺻﺒﺢ‬‫ﻣﻦ ﺍﳌﻤﻜﻦ ﺇﺟﺮﺍء ﺍﻟﻌﻤﻠﻴﺎﺕ ﺍﳊﺴﺎﺑﻴﺔ ﺍﻷﺭﺑﻌﺔ: ﺍﳉﻤﻊ ﻭﺍﻟﻄﺮﺡ ﻭ ﺍﻟﻀﺮﺏ ﻭﺍﻟﻘﺴﻤﺔ )ﺍﻟﺸﻜﻞ ١.٤(. ﻭﻣﻀﺖ‬ ‫ﺷﻜﻞ ١.٤.: ﺁﻟﺔ ‪ Step Reckoner‬ﰲ ﻣﺘﺤﻒ ﺑﺄﳌﺎﻧﻴﺎ‬‫ﺣﻮﺍﱄ ٠٥١ ﻋﺎﻣﴼ ﺑﺪﻭﻥ ﺃﻱ ﺷﻲء ﻳﺬﻛﺮ ﺣﱴ ﻗﺎﻡ ﺍﻟﱪﻭﻓﻴﺴﻮﺭ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺒﺎﺝ ‪ Charles Babbage‬ﺑﺘﺼﻤﻴﻢ ﺁﻟﺔ‬‫ﳏﺮﻙ ﺍﻟﻔﺮﻭﻕ ‪) Difference engine‬ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ١.٥( ، ﻭﻫﻲ ﺁﻟﺔ ﻣﻴﻜﺎﻧﻴﻜﻴﺔ ﺃﻳﻀﺎ ﺗﺸﺎﺑﻪ ﺁﻟﺔ ﺑﺎﺳﻜﺎﻝ ﰲ ﺃ‪‬ﺎ‬ ‫٦ﻭﺍﻟﺬﻱ ﰎ ﺗﺴﻤﻴﺔ ﻟﻐﺔ ﺍﻟﱪﳎﺔ ﺑﺎﺳﻜﺎﻝ ﺑﺎﲰﻪ ﺗﺸﺮﻳﻔﴼ ﻟﻪ.‬‫٧‬
    • ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﻻ ﺗﻮﻓﺮ ﺳﻮﻯ ﻋﻤﻠﻴﱵ ﺍﳉﻤﻊ ﻭﺍﻟﻄﺮﺡ ﻟﻜﻦ ﻫﺬﻩ ﺍﻵﻟﺔ ﰎ ﺗﺼﻤﻴﻤﻬﺎ ﻟﻐﺮﺽ ﺣﺴﺎﺏ ﻗﻴﻢ ﺩﻭﺍﻝ ﻛﺜﲑﺍﺕ ﺍﳊﺪﻭﺩ‬‫ﺑﺎﺳﺘﺨﺪﺍﻡ ﻃﺮﻕ ﺍﻟﺘﻘﺮﻳﺐ ﺍﳌﻨﺘﻬﻴﺔ )‪ . (Method of Finite Differences‬ﻭﻣﺎ ﻣﻴﺰ ﻫﺬﻩ ﺍﻵﻟﺔ ﻫﻲ ﻃﺮﻳﻘﺔ ﺇﺧﺮﺍﺝ‬ ‫ﺷﻜﻞ ١.٥.: ﳏﺮﻙ ﺍﻟﻔﺮﻭﻕ ﺑﻌﺪ ﺃﻥ ﻗﺎﻡ ﺍﺑﻦ ﺑﺎﺑﺒﺎﺝ ﺑﺘﺠﻤﻴﻌﻪ‬‫ﺍﻟﻨﺘﺎﺋﺞ ﺣﻴﺚ ﺗﻨﻘﺶ ﺍﻟﻨﺘﺎﺋﺞ ﻋﻠﻰ ﺃﻟﻮﺍﺡ ﳓﺎﺳﻴﺔ. ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻥ ﺁﻟﺔ ﺍﻟﻔﺮﻭﻕ ﻋﻤﻠﺖ ﺟﻴﺪﴽ ﺇﻻ ﺃﻥ ﺗﺼﻤﻴﻤﻬﺎ‬‫ﻛﺎﻥ ﻳﺴﻤﺢ ﲝﺴﺎﺏ ﺧﻮﺍﺭﺯﻣﻴﺔ ﻭﺍﺣﺪﺓ ﻓﻘﻂ ٧ ﻭﻫﺬﺍ ﻣﺎ ﺟﻌﻞ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺒﺎﺝ ﻳﻌﻴﺪ ﳏﺎﻭﻟﺘﻪ ﳎﺪﺩﴽ ﻭﻳﺴﺘﻬﻠﻚ‬‫ﺟﺰءﴽ ﺿﺨﻤﺎ ﻣﻦ ﻭﻗﺘﻪ ﻭﻣﻦ ﺛﺮﻭﺓ ﺣﻜﻮﻣﺘﻪ ﰲ ﺑﻨﺎء ﺁﻟﺔ ﺃﺧﺮﻯ ‪‬ﺮﻓﺖ ﺑﺎﳌﺤﺮﻙ ﺍﻟﺘﺤﻠﻴﻠﻲ ‪Analy cal Engine‬‬ ‫ﻋ‬‫)ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ١.٦(. ﻫﺬﺍ ﺍﳌﺤﺮﻙ )ﻭﻫﻮ ﺃﻳﻀﺎ ﺁﻟﺔ ﻣﻴﻜﺎﻧﻴﻜﻴﺔ ﺑﺎﻟﻜﺎﻣﻞ( ﺍﺣﺘﻮﻯ ﻋﻠﻰ ﺃﺭﺑﻊ ﻣﻜﻮﻧﺎﺕ: ﺍﳌﺨﺰﻥ‬‫)ﺍﻟﺬﺍﻛﺮﺓ ‪ ،(Memory‬ﺍﻟﻄﺎﺣﻨﺔ )ﻭﺣﺪﺓ ﺍﳊﺴﺎﺏ ‪ ، (Computa on Unit‬ﻭﺣﺪﺓ ﺍﻹﺩﺧﺎﻝ )ﻗﺎﺭﺉ ﺍﻟﺒﻄﺎﻗﺎﺕ‬‫ﺍﳌﺜﻘﺒﺔ ‪ (Punched Card Reader‬ﻭﻭﺣﺪﺓ ﺍﻹﺧﺮﺍﺝ )ﺍﻟﺒﻄﺎﻗﺎﺕ ﺍﳌﺜﻘﺒﺔ ﻭﺍﻟﻠﻮﺣﺎﺕ ﺍﳌﻄﺒﻮﻋﺔ(. ﻭﻳﺘﻜﻮﻥ ﺍﳌﺨﺰﻥ‬‫ﻣﻦ ٠٠٠١ ﻛﻠﻤﺔ )‪ (Word‬ﺑﻄﻮﻝ ٠٥ ﺭﻗﻢ ﺻﺤﻴﺢ ﻭﺗﺴﺘﺨﺪﻡ ﳊﻔﻆ ﺍﳌﺘﻐﲑﺍﺕ ﻭﺍﻟﻨﺘﺎﺋﺞ ، ﺃﻣﺎ ﺍﻟﻄﺎﺣﻨﺔ ﻓﺘﺴﺘﻘﺒﻞ‬‫ﺍﻟﻮﺳﺎﺋﻂ ﻣﻦ ﺍﳌﺨﺰﻥ ﻭﲡﺮﻱ ﻋﻠﻴﻬﻢ ﺃﻱ ﻣﻦ ﺍﻟﻌﻤﻠﻴﺎﺕ ﺍﻟﺮﻳﺎﺿﻴﺔ ﺍﻷﺭﺑﻌﺔ ﻭﻣﻦ ﰒ ﲢﻔﻆ ﺍﻟﻨﺘﺎﺋﺞ ﰲ ﺍﳌﺨﺰﻥ. ﺍﳌﻴﺰﺓ‬‫ﺍﻷﺳﺎﺳﻴﺔ ﻟﻠﻤﺤﺮﻙ ﺍﻟﺘﺤﻠﻴﻠﻲ ﻫﻮ ﻗﺪﺭﺗﻪ ﻋﻠﻰ ﺣﻞ ﻋﺪﺩ ﻛﺒﲑ ﻣﻦ ﺍﳌﺸﺎﻛﻞ )ﻋﻠﻰ ﻋﻜﺲ ﳏﺮﻙ ﺍﻟﻔﺮﻭﻕ( ﺣﻴﺚ‬‫ﺗﻜﺘﺐ ﺍﻟﱪﺍﻣﺞ ﰲ ﺑﻄﺎﻗﺎﺕ ﻣﺜﻘﺒﺔ ﻭﻳﺘﻢ ﻗﺮﺍﺋﺘﻬﺎ ﺍﱃ ﺍﳌﺤﺮﻙ ﺑﻮﺍﺳﻄﺔ ﻗﺎﺭﺋﴼ ﳍﺬﻩ ﺍﻟﺒﻄﺎﻗﺎﺕ. ﻭﲢﻮﻱ ﻫﺬﻩ ﺍﻟﺒﻄﺎﻗﺎﺕ‬‫ﻋﻠﻰ ﺃﻭﺍﻣﺮ ﻣﻮﺟﻪ ﺍﱃ ﺍﳌﺤﺮﻙ ﻟﻜﻲ ﻳﻘﻮﻡ ﺑﻘﺮﺍﺋﺔ ﻋﺪﺩﻳﻦ ﻣﻦ ﺍﳌﺨﺰﻥ ﻭﳚﺮﻱ ﻋﻤﻠﻴﺔ ﻣﺎ )ﲨﻊ ﻣﺜﻼ( ﻭﻣﻦ ﰒ ﳛﻔﻆ‬‫ﺍﻟﻨﺘﻴﺠﺔ ﰲ ﺍﳌﺨﺰﻥ ﺃﻳﻀﺎ ، ﻭﻛﺬﻟﻚ ﲢﻮﻱ ﺃﻭﺍﻣﺮ ﺃﺧﺮﻯ ﻣﺜﻞ ﺍﳌﻘﺎﺭﻧﺔ ﺑﲔ ﻋﺪﺩﻳﻦ ﻭﺍﻟﺘﻔﺮﻉ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ. ﻭﻷﻥ‬‫ﺍﳌﺤﺮﻙ ﻗﺎﺑﻞ ﻟﻠﱪﳎﺔ )ﺑﻠﻐﺔ ﺷﺒﻴﻬﺔ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ( ﻓﻘﺪ ﺍﺳﺘﻌﺎﻥ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺒﺎﺝ ﺑﺎﳌﱪﳎﺔ ﺁﺩﺍ ﻟﻮﻓﻼﺱ ‪Ada Lovelace‬‬‫ﻭﺍﻟﱵ ﺻﻨﻔﺖ ﻛﺄﻭﻝ ﻣﱪﻣﺞ ﰲ ﺍﻟﺘﺎﺭﻳﺦ. ﻭﻟﺴﻮء ﺍﳊﻆ ﱂ ﻳﻨﺠﺢ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺒﺎﺝ ﰲ ﺃﻥ ﻳﺰﻳﺪ ﻣﻦ ﺩﻗﺔ ﺍﳌﺤﺮﻙ ﺭﲟﺎ‬‫ﻷﻧﻪ ﳛﺘﺎﺝ ﺍﱃ ﺁﻻﻓﴼ ﻣﻦ ﺍﻟﺘﺮﻭﺱ ﻭﺍﻟﻌﺠﻼﺕ. ﻭﺑﺸﻜﻞ ﺃﻭ ﺑﺂﺧﺮ ﻳﻌﺘﱪ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺎﺝ ﺍﳉﺪ ﺍﻷﻭﻝ ﻟﻠﺤﻮﺍﺳﻴﺐ‬ ‫ﺍﳊﺎﻟﻴﺔ ﺣﻴﺚ ﺃﻥ ﻓﻜﺮﺓ ﻋﻤﻞ ﺍﳌﺤﺮﻙ ﺍﻟﺘﺤﻠﻴﻠﻲ ﻣﺸﺎ‪‬ﺔ ﻟﻠﺤﻮﺍﺳﻴﺐ ﺍﳊﺎﻟﻴﺔ.‬‫ﻭﰲ ﺃﻭﺍﺧﺮ ٠٣٩١ ﻗﺎﻡ ﺍﻟﻄﺎﻟﺐ ﺍﻷﳌﺎﱐ ﻛﻮﻧﺎﺭﺕ ﺗﺴﻮﺯﺍ ‪ Konrad Zuse‬ﺑﺒﻨﺎء ﺁﻟﺔ ﺣﺴﺎﺑﻴﺔ ﻭﻟﻜﻨﻬﺎ ﺗﻌﺘﻤﺪ ﻋﻠﻰ‬‫ﺍﻟﺮﻳﻼﻱ )‪ (Relay‬ﻭﲰﻴﺖ ﲜﻬﺎﺯ 1‪) Z‬ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ١.٧( ﻭﺗﻌﺘﱪ ﺃﻭﻝ ﺣﺎﺳﺒﺔ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺮﻳﻼﻱ ﻭﻋﻠﻰ ﺍﳌﻨﻄﻖ‬ ‫٧ﰲ ﻋﺎﻡ ١٩٩١ ﻗﺎﻡ ﻣﺘﺤﻒ ﺍﻟﻌﻠﻮﻡ ﺑﻠﻨﺪﻥ ﺑﺒﻨﺎء ﳕﻮﺫﺝ ﻣﻜﺘﻤﻞ ﳌﺤﺮﻙ ﺍﻟﻔﺮﻭﻕ.‬ ‫٨‬
    • ‫١.٢. ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫ﺷﻜﻞ ١.٦.: ﺍﳌﺤﺮﻙ ﺍﻟﺘﺤﻠﻴﻠﻲ ﲟﺘﺤﻒ ﰲ ﻟﻨﺪﻥ‬‫ﺍﻟﺜﻨﺎﺋﻲ ﰲ ﻋﻤﻠﻬﺎ. ﻭﻟﺴﻮء ﺍﳊﻆ ﰎ ﺗﺪﻣﲑ ﺍﳊﺎﺳﺒﺔ 1‪ Z‬ﰲ ﺍﻧﻔﺠﺎﺭ ﰲ ﺑﺮﻟﲔ ﺃﺛﻨﺎء ﺍﳊﺮﺏ ﺍﻟﻌﺎﳌﻴﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻋﺎﻡ ٣٤٩١.‬‫ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻥ ﺗﺼﻤﻴﻢ 1‪ Z‬ﱂ ﻳﺆﺛﺮ ﰲ ﺗﺼﺎﻣﻴﻢ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﱵ ﺗﻠﻴﻪ ﺑﺴﺒﺐ ﺗﺪﻣﲑﻩ ﻫﻮ ﻭﲨﻴﻊ ﺧﻄﻂ ﺑﻨﺎﺋﻪ‬‫ﺇﻻ ﺃﻧﻪ ﻳﻌﺘﱪ ﺃﺣﺪ ﺍﻟﺘﺼﺎﻣﻴﻢ ﺍﻟﱵ ﻛﺎﻥ ﳍﺎ ﺃﺛﺮﻫﺎ ﺫﺍﻙ ﺍﻟﻮﻗﺖ. ﻭﺑﻌﺪ ﺑﺮﻫﺔ ﻣﻦ ﺍﻟﺰﻣﻦ ﻗﺎﻡ ﺟﻮﻥ ﺃﺗﺎﻧﺎﺳﻮﻑ ‪John‬‬ ‫ﺷﻜﻞ ١.٧.: ﺣﺎﺳﺒﺔ 1‪ Z‬ﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺍﻧﺸﺎﺋﻬﺎ ﰲ ﻣﺘﺤﻒ ﺑﺄﳌﺎﻧﻴﺎ‬‫‪ Vincent Atanasoff‬ﺑﺘﺼﻤﻴﻢ ﺟﻬﺎﺯ ‪)Atanasoff‬ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ??( ﻭﺍﻟﺬﻱ ﻛﺎﻥ ﻣﺪﻫﺸﺎ ﰲ ﻭﻗﺘﻪ ﺣﻴﺚ ﻳﺴﺘﺨﺪﻡ‬‫ﺍﻟﺘﺤﺴﻴﺐ ﺍﻟﺜﻨﺎﺋﻲ )‪ (Binray Arithme c‬ﻭﳛﻮﻱ ﻣﻜﺜﻔﺎﺕ ﻟﻠﺬﺍﻛﺮﺓ ﻭﻟﻜﻦ ﺍﳉﻬﺎﺯ ﱂ ﻳﻜﻦ ﻋﻤﻠﻴﺎ. ﻭﰲ ﺑﺪﺍﻳﺎﺕ‬‫٠٤٩١ ﻗﺎﻡ ﻫﻮﺍﺭﺩ ﺍﻳﻜﲔ ‪ Howard Aiken‬ﺑﺘﺼﻤﻴﻢ ﺍﳊﺎﺳﺒﺔ ‪ - ASCC‬ﻭﺍﻟﱵ ﺃﻋﻴﺪ ﺗﺴﻤﻴﺘﻬﺎ ﺍﱃ ‪Harvard Mark‬‬‫‪ - I‬ﰲ ﺟﺎﻣﻌﺔ ﻫﺎﻓﺎﺭﺩ )ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ١.٩(.ﻭﻗﺪ ﺃﺗﺒﻊ ﻫﻮﺍﺭﺩ ﻧﻔﺲ ﻣﻨﻬﺞ ﺑﺎﺑﺒﺎﺝ ﻭﻗﺮﺭ ﺃﻥ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺮﻳﻼﻱ‬‫ﻭﺃﻥ ﻳﺼﻤﻢ ﺣﺎﺳﺒﺔ ﻟﻸﻏﺮﺍﺽ ﺍﻟﻌﺎﻣﺔ ﻭﺍﻟﱵ ﻓﺸﻞ ‪‬ﺎ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺒﺎﺝ.ﻭﰲ ﻋﺎﻡ ٤٤٩١ ﰎ ﺍﻹﻧﺘﻬﺎء ﻣﻦ ﺗﺼﻤﻴﻤﻬﺎ ﻭﰎ‬‫ﺗﺼﻤﻴﻢ ﻧﺴﺨﺔ ﳏﺴﻨﺔ ﺃﻳﻀﺎ ﲰﻴﺖ ﺏ ‪.Harvard Mark II‬ﻭﻣﻊ ﻫﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﺍﻧﺘﻬﻰ ﻋﺼﺮ ﺍﳊﺎﺳﺒﺎﺕ ﺍﳌﻴﻜﺎﻧﻴﻜﻴﺔ‬‫٩‬
    • ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫‪Iowa State‬‬ ‫ﺷﻜﻞ ١.٨.: ﺣﺎﺳﺒﺔ ‪ Atanasoff‬ﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺍﻧﺸﺎﺋﻬﺎ ﰲ ﺟﺎﻣﻌﺔ‬ ‫)ﺏ( ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻭﺍﻟﺘﺤﻜﻢ‬ ‫‪Mark I‬‬ ‫)ﺍ( ﺍﳉﺰء ﺍﻷﻳﺴﺮ ﻣﻦ ﺣﺎﺳﺒﺔ‬ ‫‪Harvard Mark I‬‬ ‫ﺷﻜﻞ ١.٩.: ﺣﺎﺳﺒﺔ‬ ‫ﻭﺍﻟﺮﻳﻼﻱ ﻭﺑﺪﺃ ﻋﺼﺮ ﺟﺪﻳﺪ.‬ ‫١.٢.٢. ﺍﳉﻴﻞ ﺍﻷﻭﻝ )٥٤٩١-٥٥٩١(: ﺍﻟﺼﻤﺎﻣﺎﺕ ﺍﳌﻔﺮﻏﺔ ﻭ ﻟﻮﺣﺎﺕ ﺍﻟﺘﻮﺻﻴﻞ‬‫ﰲ ﺑﺪﺍﻳﺎﺕ ﺍﳊﺮﺏ ﺍﻟﻌﺎﳌﻴﺔ ﺍﻟﺜﺎﻧﻴﺔ ، ﻛﺎﻥ ﺃﻣﲑ ﺍﻟﺒﺤﺮﻳﺔ ﰲ ﺑﺮﻟﲔ ﻳﺮﺳﻞ ﺭﺳﺎﺋﻞ ﺍﱃ ﺍﻟﻐﻮﺍﺻﺎﺕ ﺍﻷﳌﺎﻧﻴﺔ ﻋﱪ ﻣﻮﺟﺎﺕ‬‫ﺍﻟﺮﺍﺩﻳﻮ ﻭﺍﻟﱵ ﺍﺳﺘﻄﺎﻉ ﺣﻠﻔﺎﺅﻫﺎ ﺍﻟﱪﻳﻄﺎﻧﻴﲔ ﺍﻟﺘﻘﺎﻃﻬﺎ ، ﻭﻟﺴﻮء ﺣﻈﻬﻢ ﻛﺎﻧﺖ ﺍﻟﺮﺳﺎﺋﻞ ﺗﺮﺳﻞ ﻣﺸﻔﺮﺓ ﻭﺫﻟﻚ ﻋﻦ‬‫ﻃﺮﻳﻖ ﺷﻔﺮﺓ ﺧﺎﺻﺔ ﺗﻨﺘﺞ ﻣﻦ ﻗﺒﻞ ﺟﻬﺎﺯ ﻳﺴﻤﻰ ﲜﻬﺎﺯ ﺇﳒﻤﺎ )‪ Enigma Machine‬ﻭﺍﻟﺬﻱ ﰎ ﺗﺼﻨﻴﻌﻪ ﻟﺘﺸﻔﲑ‬‫ﺍﻟﺮﺳﺎﺋﻞ ﻭﻓﻚ ﺗﺸﻔﲑﻫﺎ . ﻭﻗﺪ ﲤﻜﻨﺖ ﺍﻹﺳﺘﺨﺒﺎﺭﺍﺕ ﺍﻟﱪﻳﻄﺎﻧﻴﺔ ﻣﻦ ﺍﳊﺼﻮﻝ ﻋﻠﻰ ﺃﺣﺪ ﻫﺬﻩ ﺍﻷﺟﻬﺰﺓ ﻭﺫﻟﻚ‬‫ﺑﻌﺪ ﺍﻹﺗﻔﺎﻕ ﻣﻊ ﺍﻹﺳﺘﺨﺒﺎﺭﺍﺕ ﺍﻟﺒﻮﻟﻨﺪﻳﺔ ﻭﺍﻟﱵ ﻛﺎﻧﺖ ﻗﺪ ﺳﺮﻗﺖ ﺟﻬﺎﺯﴽ ﻣﻦ ﺍﻷﳌﺎﻥ. ﻭﺣﱴ ﻳﺘﻤﻜﻦ ﺍﻟﱪﻳﻄﺎﻧﻴﲔ‬‫ﻣﻦ ﻓﻚ ﺷﻔﺮﺓ ﺍﻟﺮﺳﺎﺋﻞ ﻓﺎﻥ ﻫﺬﺍ ﻳﺘﻄﻠﺐ ﻭﻗﺘﴼ ﻭﻋﻤﻠﻴﺎﺕ ﺣﺴﺎﺑﻴﺔ ﻃﻮﻳﻠﺔ ، ﻟﺬﻟﻚ ﺳﺮﻋﺎﻥ ﻣﺎ ﺃﺳﺴﺖ ﻣﻌﻤﻼ‬ ‫٠١‬
    • ‫١.٢. ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫ﺷﻜﻞ ١.٠١.: ﺁﻟﺔ ﺇﳒﻤﺎ ﺍﻷﳌﺎﻧﻴﺔ ﻟﺘﺸﻔﲑ ﺍﻟﺮﺳﺎﺋﻞ ﻭﻓﻜﻬﺎ‬‫ﺳﺮﻳﺎ ﳛﻮﻱ ﻋﻠﻰ ﺣﺎﺳﺒﺔ ﺍﻟﻜﺘﺮﻭﻧﻴﺔ ﻋﺮﻓﺖ ﺑﺎﻻﺳﻢ ‪ .Colossus‬ﻫﺬﻩ ﺍﳊﺎﺳﺒﺔ ﰎ ﺗﺼﻤﻴﻤﻬﺎ ﻣﻦ ﻗﺒﻞ ﻋﺪﺓ ﺃﺷﺨﺎﺹ‬‫ﻭﺷﺎﺭﻙ ﻓﻴﻬﺎ ﺍﻟﻌﺎﱂ ﺁﻻﻥ ﺗﻮﺭﻧﺞ ﻭﺃﺻﺒﺤﺖ ﺟﺎﻫﺰﺓ ﻟﻠﻌﻤﻞ ﰲ ﻋﺎﻡ ٣٤٩١. ﻭﺑﺴﺒﺐ ﻛﻮﻥ ﺍﳌﺸﺮﻭﻉ ﺳﺮﻳﺎ ﻭﰎ‬‫ﺍﻟﺘﻜﺘﻢ ﻋﻠﻴﻪ ﳌﺎ ﻳﻘﺎﺭﺏ ٠٣ ﻋﺎﻣﺎ ﻓﺎﻥ ﻫﺬﺍ ﺍﻟﻨﻮﻉ ﻣﻦ ﺍﳊﻮﺍﺳﻴﺐ ﱂ ﻳﺆﺛﺮ ﻋﻠﻰ ﺗﺼﺎﻣﻴﻢ ﺍﳊﻮﺍﺳﻴﺐ ﺍﳊﺪﻳﺜﺔ ﻭﻟﻜﻦ‬‫ﳚﺪﺭ ﺑﺎﻟﺬﻛﺮ ﺃﻥ ﻫﺬﻩ ﺍﳊﺎﺳﺒﺔ ﺗﻌﺘﱪ ﺃﻭﻝ ﺣﺎﺳﺒﺔ ﺇﻟﻜﺘﺮﻭﻧﻴﺔ ﻗﺎﺑﻠﺔ ﻟﻠﱪﳎﺔ ﺗﺴﺘﺨﺪﻡ ﺍﻟﺼﻤﺎﻣﺎﺕ ﺍﳍﻮﺍﺋﻴﺔ ﰲ ﺣﺴﺎﺑﺎ‪‬ﺎ.‬‫ﻭﰲ ﻋﺎﻡ ٣٤٩١ ﻗﺪﻡ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ‪ John Mauchley‬ﻣﻘﺘﺮﺣﴼ ﺍﱃ ﺍﳉﻴﺶ ﺍﻷﻣﺮﻳﻜﻲ ﻃﺎﻟﺒﴼ ﲤﻮﻳﻠﻪ ﺑﺎﳌﺎﻝ ﻟﻠﺒﺪء‬‫ﺑﺘﺼﻤﻴﻢ ﺣﺎﺳﺒﺔ ﺇﻟﻜﺘﺮﻭﻧﻴﺔ ﳊﺴﺎﺏ ﺟﺪﺍﻭﻝ ﺇﻃﻼﻕ ﺍﳌﺪﻓﻌﻴﺎﺕ ﺑﺪﻻﹰ ﻣﻦ ﺣﺴﺎ‪‬ﺎ ﻳﺪﻭﻳﺎ ﻭﺫﻟﻚ ﻟﺘﻘﻠﻴﻞ ﺍﻷﺧﻄﺎء‬‫ﻭﻛﺴﺐ ﺍﻟﻮﻗﺖ، ﻭﻗﺪ ﲤﺖ ﺍﳌﻮﺍﻓﻘﺔ ﻋﻠﻰ ﺍﳌﺸﺮﻭﻉ ﻭﺑﺪﺃ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ﻭﻃﺎﻟﺒﻪ ﺍﳋﺮﻳﺞ ﺇﻳﻜﺮﻳﺖ ﺑﺒﻨﺎء ﺣﺎﺳﺒﺔ‬‫ﰎ ﺗﺴﻤﻴﺘﻬﺎ ﺑﺎﻻﺳﻢ ﺇﻳﻨﺎﻙ ‪ ENIAC‬ﺍﺧﺘﺼﺎﺭﺍ ﻟﻠﺠﻤﻠﺔ ‪.Electronic Numerical Integrator And Computer‬‬‫ﻭﺗﺘﻜﻮﻥ ﻣﻦ ٠٠٠٨١ ﺻﻤﺎﻣﺎ ﻣﻔﺮﻏﺎ )‪ (Vacuum Tubes‬ﻭ ٠٠٥١ ﺣﺎﻛﻤﺔ )‪ ، (Relays‬ﻭﺗﺰﻥ ﺍﳊﺎﺳﺒﺔ ٠٣‬‫ﻃﻦ ﻭﺗﺴﺘﻬﻠﻚ ٠٤١ ﻛﻴﻠﻮ ﻭﺍﻁ ﻣﻦ ﺍﻟﻄﺎﻗﺔ. ﻭﺩﺍﺧﻠﻴﺎ ﲢﺘﻮﻱ ﺍﳊﺎﺳﺒﺔ ﻋﻠﻰ ٠٢ ﻣﺴﺠﻞ ﻛﻞ ﻣﻨﻬﻢ ﻳﺴﻊ ﻋﺪﺩﺍ‬ ‫ﺻﺤﻴﺤﺎ ﺑﻄﻮﻝ ٠١ ﺧﺎﻧﺎﺕ. ﻭﺗﺘﻢ ﺑﺮﳎﺔ ﺇﻳﻨﺎﻙ ﻋﻦ ﻃﺮﻳﻖ ٠٠٠٦ ﻣﻔﺘﺎﺡ ‪.Switch‬‬‫ﻭﻗﺪ ﰎ ﺍﻹﻧﺘﻬﺎء ﻣﻦ ﺗﺼﻤﻴﻢ ﺇﻳﻨﺎﻙ ﻋﺎﻡ ٦٤٩١ ، ﺍﻟﻮﻗﺖ ﺍﻟﺬﻱ ﻛﺎﻧﺖ ﺍﳊﺮﺏ ﻗﺪ ﺍﻧﺘﻬﺖ ﻭﱂ ﺗﺴﺘﺨﺪﻡ ﺍﳊﺎﺳﺒﺔ‬‫ﳍﺪﻓﻬﺎ ﺍﻟﺮﺋﻴﺴﻲ. ﻭﺑﻌﺪ ﺫﻟﻚ ﻧﻈﻢ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ﻭﻃﺎﻟﺒﻪ ﺇﻳﻜﺮﻳﺖ ﻣﺪﺭﺳﺔ ﺻﻴﻔﻴﺔ ﻟﻮﺻﻒ ﻣﺸﺮﻭﻋﻬﻢ ﻟﻠﺒﺎﺣﺜﲔ‬‫ﻭﺍﳌﻬﺘﻤﲔ. ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﺃﺳﻔﺮ ﻋﻦ ﻇﻬﻮﺭ ﻋﺪﺩ ﻛﺒﲑ ﻣﻦ ﺍﳊﺎﺳﺒﺎﺕ ﺍﻟﻀﺨﻤﺔ . ﻭﺃﻭﻝ ﺣﺎﺳﺒﺔ ﺑﻌﺪﻫﺎ ﻛﺎﻧﺖ‬‫١١‬
    • ‫١. ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫ﺷﻜﻞ ١.١١.: ﺍﳊﺎﺳﺒﺔ ‪ colossus‬ﺍﻟﱵ ﻛﺴﺮﺕ ﺷﻔﺮﺓ ﺇﳒﻤﺎ‬ ‫‪ENIAC‬‬ ‫ﺷﻜﻞ ١.٢١.: ﺍﳊﺎﺳﺒﺔ‬‫‪ILLIAC‬‬‫‪ EDSAC‬ﰲ ﻋﺎﻡ ٩٤٩١ ﺑﻮﺍﺳﻄﺔ ﻭﻳﻠﻜﺲ ﰲ ﺟﺎﻣﻌﺔ ﻛﺎﻣﱪﺩﺝ. ﻛﺬﻟﻚ ﺗﻠﺘﻪ ﺍﳊﺎﺳﺒﺎﺕ ‪ JOHNIAC‬ﻭ‬‫ﻭﻏﲑﻫﻢ.ﺑﻌﺪ ﺫﻟﻚ ﺑﺪﺃ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ﻭﺇﻳﻜﺮﻳﺖ ﺑﺎﻟﻌﻤﻞ ﻋﻠﻰ ﺣﺎﺳﺒﺔ ﺃﺧﺮﻯ ﲰﻴﺖ ﺑﺎﻻﺳﻢ ‪ EDVAC‬ﺍﺧﺘﺼﺎﺭﺍ‬‫ﻟﻠﺠﻤﻠﺔ ‪ Electronic Discrete Variable Automa c Computer‬ﻭﺍﻟﱵ ﻛﺎﻧﺖ ﺗﻌﻤﻞ ﺑﺎﻷﺭﻗﺎﻡ ﺍﻟﺜﻨﺎﺋﻴﺔ ﺑﺪﻻ ﻣﻦ‬ ‫ﺍﻟﻌﺸﺮﻳﺔ )ﻛﻤﺎ ﰲ ﺇﻳﻨﺎﻙ(.ﺑﻌﺪ ﺫﻟﻚ ﺗﻮﻗﻒ ﺍﳌﺸﺮﻭﻉ ﺑﺴﺒﺐ ﺃﻥ ﺟﻮﻥ ﻭﺇﻳﻜﺮﻳﺖ ﻗﺪ ﺃﻧﺸﺌﺎ ﺷﺮﻛﺘﻬﻢ ﺍﳋﺎﺻﺔ.‬ ‫٢١‬
    • ‫١.٢. ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫‪EDVAC‬‬ ‫ﺷﻜﻞ ١.٣١.: ﺍﳊﺎﺳﺒﺔ‬‫٣١‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬‫ﺣﻮﺍﺳﻴﺐ ﻋﺎﺋﻠﺔ 68‪ x‬ﺗﺘﺒﻊ ﳌﻌﻤﺎﺭﻳﺔ ﺍﻟﻌﺎﱂ ﺟﻮﻥ ﻓﻮﻥ ﻧﻴﻮﻣﺎﻥ )‪ (John von Neumann architecture‬ﻭﺍﻟﱵ ﺗﻨﺺ‬ ‫ﻋﻠﻰ ﺃﻥ ﺃﻱ ﺗﺼﻤﻴﻢ ﳉﻬﺎﺯ ﺣﺎﺳﺐ ﳚﺐ ﺃﻥ ﻳﺘﻜﻮﻥ ﻣﻦ ﺍﻟﺜﻼﺙ ﻭﺣﺪﺍﺕ ﺍﻟﺘﺎﻟﻴﺔ :‬ ‫١. ﻣﻌﺎﰿ ﺃﻭ ﻭﺣﺪﺓ ﻣﻌﺎﳉﺔ ﻣﺮﻛﺰﻳﺔ )‪.(Central Processing Unit‬‬ ‫٢. ﺫﺍﻛﺮﺓ )‪.(Memory‬‬ ‫٣. ﺃﺟﻬﺰﺓ ﺇﺩﺧﺎﻝ ﻭﺇﺧﺮﺍﺝ )‪.(I/O Devices‬‬ ‫ﺍﻟﻮﺣﺪﺓ ﺍﻻﻭﱃ ﻫﻲ ﻭﺣﺪﺓ ﺍﳌﻌﺎﳉﺔ ﻭﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﻌﻤﻠﻴﺎﺕ ﺍﳊﺴﺎﺑﻴﺔ ، ﺃﻣﺎ ﺍﻟﻮﺣﺪﺓ ﺍﻟﺜﺎﻧﻴﺔ ﻓﻬﻲ‬ ‫ﲢﻮﻱ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﺘﻌﻠﻴﻤﺎﺕ ﻭﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﳚﺐ ﻋﻠﻰ ﻭﺣﺪﺓ ﺍﳌﻌﺎﳉﺔ ﺃﻥ ﺗﻨﻔﺬﻫﺎ ، ﻭﺃﺧﲑﴽ ﻭﺣﺪﺍﺕ ﺍﻹﺩﺧﺎﻝ‬‫ﻭﺍﻹﺧﺮﺍﺝ ﻭﻫﻲ ﺍﻻﺟﻬﺰﺓ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﰲ ﺍﺩﺧﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﺧﺮﺍﺟﻬﺎ.)ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ٢.١ ﺣﻴﺚ ﻳﻮﺿﺢ ﻣﺜﺎﻻً‬ ‫ﳍﺬﻩ ﺍﳌﻌﻤﺎﺭﻳﺔ( ﻭﻳﺮﺑﻂ ﺑﲔ ﻛﻞ ﻫﺬﻩ ﺍﻷﺟﺰﺍء ﻫﻮ ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ )‪ (System Bus‬ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺳﻨﺴﺘﻌﺮﺽ ﻭﻇﻴﻔﺔ‬ ‫ﻛﻞ ﺟﺰء ﻋﻠﻰ ﺣﺪﺓ.‬ ‫68‪x‬‬ ‫ﺷﻜﻞ ٢.١.: ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬‫٥١‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬ ‫٢.١. ﻣﻌﻤﺎﺭﻳﺔ ﺍﻟﻨﻈﺎﻡ‬ ‫‪System Bus‬‬ ‫٢.١.١. ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ‬‫ﻳﺮﺑﻂ ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ ١ )‪ (System Bus‬ﻭﺣﺪﺓ ﺍﳌﻌﺎﳉﺔ ﺍﳌﺮﻛﺰﻳﺔ )‪ (CPU‬ﻣﻊ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ . ﻭ ﻭﻇﻴﻔﺔ‬‫ﻫﺬﻩ ﺍﳌﺴﺎﺭﺍﺕ ﻫﻲ ﻧﻘﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﲔ ﺃﺟﺰﺍء ﺍﳊﺎﺳﺐ ﺍﳌﺨﺘﻠﻔﺔ. ﻭﺍﻟﺸﻜﻞ ٢.٢ ﻳﻮﺿﺢ ﺍﻟﺼﻮﺭﺓ ﺍﻟﻌﺎﻣﺔ ﻟﻠﻤﺴﺎﺭﺍﺕ‬‫ﰲ ﺃﺟﻬﺰﺓ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﺸﺨﺼﻴﺔ )‪ .(Personal Computers‬ﻭﻳﺘﺄﻟﻒ ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ ﻣﻦ ﺛﻼﺙ ﻣﺴﺎﺭﺍﺕ: ﻣﺴﺎﺭ‬ ‫ﺍﻟﺒﻴﺎﻧﺎﺕ )‪ (Data Bus‬ﻭﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ )‪ (Address Bus‬ﻭﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ )‪.(Control Bus‬‬ ‫68‪x‬‬ ‫ﺷﻜﻞ ٢.٢.: ﺍﳌﺴﺎﺭﺍﺕ ﰲ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﺸﺨﺼﻴﺔ‬ ‫١ﻭﻳﺴﻤﻰ ﺃﻳﻀﺎ ‪.Front-side Bus‬‬ ‫٦١‬
    • ‫٢.١. ﻣﻌﻤﺎﺭﻳﺔ ﺍﻟﻨﻈﺎﻡ‬ ‫‪Data Bus‬‬ ‫ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ‬‫ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻫﻮ ﻋﺒﺎﺭﺓ ﻋﻦ ﺧﻄﻮﻁ )‪ (Lines‬ﻛﻞ ﺧﻂ ﳝﺜﻞ ﺑﺖ ﻭﺍﺣﺪ. ﻭﻏﺎﻟﺒﺎ ﻣﺎ ﻳﻜﻮﻥ ﻫﻨﺎﻙ ٢٣ ﺧﻂ‬‫)ﺃﻱ ﺃﻥ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﻄﻮﻝ ٢٣ ﺑﺖ( ﻭﻳﺴﺘﺨﺪﻡ ﻫﺬﺍ ﺍﳌﺴﺎﺭ ﰲ ﻧﻘﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ )‪ (Data‬ﻣﻦ ﺍﳌﻌﺎﰿ )ﻭﲢﺪﻳﺪﴽ‬‫ﻣﻦ ﻭﺣﺪﺓ ﺍﻟﺘﺤﻜﻢ ‪ (Control Unit‬ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﻟﺬﻱ ﻳﺘﻮﺍﺟﺪ ﺑﺪﺍﺧﻞ ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ ‪.NorthBridge‬‬‫ﻭﺑﺴﺒﺐ ﺃﻥ ﺣﺠﻢ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻫﻮ ﺣﺠﻢ ﺛﺎﺑﺖ ﻓﺎﻥ ﻫﺬﺍ ﻳﺘﻄﻠﺐ ﻣﻌﺎﳉﺔ ﺧﺎﺻﺔ ﻋﻨﺪ ﺍﺭﺳﺎﻝ ﺑﻴﺎﻧﺎﺕ ﺑﻄﻮﻝ‬‫ﺃﻗﻞ ﻣﻦ ﻃﻮﻝ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ، ﻓﻐﺎﻟﺒﺎ ﻣﺎ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ ﺑﺎﺿﺎﻓﺔ ﺃﺻﻔﺎﺭ ﰲ ﺍﳋﻄﻮﻁ ﺍﻟﻐﲑ ﻣﺴﺘﺨﺪﻣﺔ )‪.(Padding‬‬‫ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﺇﺭﺳﺎﻝ ﺑﻴﺎﻧﺎﺕ ﺑﻄﻮﻝ ﺃﻛﱪ ﻓﺎﻥ ﻋﻤﻠﻴﺔ ﻧﻘﻠﻬﺎ ﺗﺘﻢ ﻋﻠﻰ ﻋﺪﺓ ﻣﺮﺍﺣﻞ ﻭﰲ ﻛﻞ ﻣﺮﺣﻠﺔ ﺗﺮﺳﻞ ٢٣ ﺑﺖ‬ ‫ﻣﻦ ﺍﻟﺒﻴﺎﻧﺎﺕ .‬ ‫‪Address Bus‬‬ ‫ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ‬‫ﻳﺴﺘﺨﺪﻡ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﰲ ﻧﻘﻞ ﻋﻨﻮﺍﻥ ﺍﻟﺬﺍﻛﺮﺓ ﺍﳌﺮﺍﺩ ﺍﺳﺘﺨﺪﺍﻣﻪ ﺳﻮﺍءﴽ ﻟﻠﻘﺮﺍءﺓ ﻣﻨﻪ ﺃﻭ ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻴﻪ ، ﻭﳛﺪﺩ‬‫ﺣﺠﻢ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺃﻛﱪ ﻋﻨﻮﺍﻥ ﳝﻜﻦ ﺍﻟﻮﺻﻞ ﺍﻟﻴﻪ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺑﺎﻟﺘﺎﱄ ﳛﺪﺩ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﱵ ﻳﺴﺘﻄﻴﻊ‬‫ﺍﳊﺎﺳﺐ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ . ﻭﰲ ﺍﻷﺟﻬﺰﺓ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﻣﻌﺎﳉﺎﺕ ﺍﻧﺘﻞ 6808 ﻛﺎﻥ ﺣﺠﻢ ﻫﺬﺍ ﺍﳌﺴﺎﺭ ﻫﻮ ٠٢ ﺑﺖ‬‫ﻭﺑﺎﻟﺘﺎﱄ ﻓﺎﻥ ﺃﻗﺼﻰ ﺫﺍﻛﺮﺓ ﻳﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﻫﺬﺍ ﺍﳌﻌﺎﰿ ﻫﻲ ١ ﻣﻴﺠﺎ ٢ ﺃﻣﺎ ﰲ ﻣﻌﺎﳉﺎﺕ 68308/68208 ﻓﺎﻥ ﺣﺠﻢ‬‫ﻫﺬﺍ ﻣﺴﺎﺭ ﻫﻮ ٤٢ ﺑﺖ ﻭﰲ ﺍﳌﻌﺎﳉﺎﺕ ﺍﻟﱵ ﺗﻠﻴﻬﺎ ﰎ ﺯﻳﺎﺩﺓ ﻫﺬﺍ ﺍﳊﺠﻢ ﺍﱃ ٢٣ ﺑﺖ ﻭﺑﺎﻟﺘﺎﱄ ﳝﻜﻦ ﺗﻨﺼﻴﺐ ﺫﺍﻛﺮﺓ‬‫ﲝﺠﻢ ٤ ﺟﻴﺠﺎ ، ﻭﰲ ﺍﳌﻌﺎﳉﺎﺕ ﺍﳊﺪﻳﺜﺔ ﰎ ﺯﻳﺎﺩﺓ ﻫﺬﺍ ﺍﳊﺠﻢ ، ﻭﻟﻜﻨﻨﺎ ﺳﻨﻘﺘﺼﺮ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﻋﻠﻰ ﺍﳌﻌﺎﳉﺎﺕ‬‫ﺍﻟﱵ ﺗﺪﻋﻢ ﻣﺴﺎﺭ ﻋﻨﺎﻭﻳﻦ ﺑﻄﻮﻝ ٢٣ ﺑﺖ ﺑﺴﺒﺐ ﺍﻧﺘﺸﺎﺭﻫﺎ ﻭﺳﻴﻄﺮ‪‬ﺎ ﳌﺪﺓ ﻣﻦ ﺍﻟﺰﻣﻦ ﻋﻠﻰ ﺃﺟﻬﺰﺓ ﺍﳊﻮﺍﺳﻴﺐ‬ ‫ﺍﻟﺸﺨﺼﻴﺔ.‬ ‫‪Control Bus‬‬ ‫ﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ‬‫ﻳﺴﺘﺨﺪﻡ ﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ ﰲ ﺍﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ﻣﺜﻞ ﺃﻣﺮ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻮﺟﻮﺩ ﻋﻠﻰ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺃﻭ ﺃﻣﺮ‬‫ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻰ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻮﺏ . ﻭﻳﺘﺄﻟﻒ ﻫﺬﺍ ﺍﳌﺴﺎﺭ ﻣﻦ ﻋﺪﺩ ﻣﻦ ﺍﳋﻄﻮﻁ ﻭﻛﻞ ﺧﻂ )ﺑﺖ( ﻳﺆﺩﻱ ﻭﻇﻴﻔﺔ‬‫ﳏﺪﺩﺓ. ﺃﺣﺪ ﻫﺬﻩ ﺍﳋﻄﻮﻁ ﻫﻮ ﺧﻂ ﺍﻟﻜﺘﺎﺑﺔ ‪ WRITE‬ﻭﺍﻟﺬﻱ ﻳﻌﲏ ﺃﻥ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻮﺟﻮﺩ ﻋﻠﻰ ﺧﻂ ﺍﻟﻌﻨﺎﻭﻳﻦ ﳚﺐ‬‫ﺃﻥ ‪‬ﻌﱠﻦ ﻟﻪ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ . ﺍﳋﻂ ﺍﻵﺧﺮ ﻫﻮ ﺧﻂ ﺍﻟﻘﺮﺍءﺓ ‪ READ‬ﻭﺍﻟﺬﻱ ﻳﺪﻝ ﻋﻠﻰ ﺃﻥ‬‫ﺗﻴ‬‫ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻮﺟﻮﺩ ﰲ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﳚﺐ ﺃﻥ ‪‬ﻘﺮﺃ ﻗﻴﻤﺘﻪ ﺍﱃ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ . ﺁﺧﺮ ﺧﻂ ﻳﻬﻤﻨﺎ ﻫﻮ ﺧﻂ ﺍﻟﻮﻟﻮﺝ‬ ‫ﺗ‬‫‪ ACCESS‬ﻭﺍﻟﺬﻱ ﳛﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻮﺟ ٌ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺃﻡ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ‬ ‫ﻪ‬‫ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﻫﺬﺍ ﺍﳋﻂ ﻫﻲ ﺍﻟﻘﻴﻤﺔ ١ ﻓﺎﻥ ﻫﺬﺍ ﻳﻌﲏ ﺃﻥ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻮﺟ ُ ﺍﱃ ﻣﺘﺤﻜﻢ ﺃﺟﻬﺰﺓ ﺍﻹﺩﺧﺎﻝ‬ ‫ﻪ‬‫ﻭﺍﻹﺧﺮﺍﺝ ﻭﺑﺎﻟﺘﺎﱄ ﺳﻴﺘﻢ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﺃﻭ ﺍﻟﻜﺘﺎﺑﺔ ﺍﻟﻴﻪ ﻭﺫﻟﻚ ﲝﺴﺐ ﻗﻴﻤﺔ ﺍﳋﻄﲔ ‪READ and‬‬ ‫‪.WRITE‬‬ ‫٢ﻧﺎﲡﺔ ﻣﻦ ﺣﺴﺎﺏ ٢ ﻣﺮﻓﻮﻉ ﻟﻠﻘﻮﺓ ٠٢.‬‫٧١‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬ ‫٢.١.٢. ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﻗﺒﻞ ﺫﻛﺮ ﻭﻇﻴﻔﺔ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﳚﺐ ﺇﻋﻄﺎء ﻧﺒﺬﺓ ﻋﻦ ﻣﺎﻫﻴﺔ ﺍﳌﺘﺤﻜﻤﺎﺕ )‪ (Controllers‬ﰲ ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ.‬‫ﻭُﻌ ﱠﻑ ﺍﳌﺘﺤﻜﻢ ﺑﺄﻧﻪ ﺷﺮﳛﺔ ﺗﺘﺤﻜﻢ ﺑﻌﺘﺎﺩ ﻣﺎ ﲢﻮﻱ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﺍﻟﺪﺍﺧﻠﻴﺔ ﻭﻇﻴﻔﺘﻬﺎ ﻫﻲ ﺍﺳﺘﻘﺒﺎﻝ‬ ‫ﻳﺮ‬‫ﺍﻷﻭﺍﻣﺮ ﻭﺗﻨﻔﻴﺬﻫﺎ ﻋﻠﻰ ﺍﻟﻌﺘﺎﺩ. ﻭﳝﻜﻦ ﺗﻌﺮﻳﻔﻬﺎ ﻛﺬﻟﻚ ﺑﺄ‪‬ﺎ ﺷﺮﳛﺔ ﻟﻠﺮﺑﻂ ﻣﺎ ﺑﲔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱪﳎﻴﺔ ﺍﱃ ﺃﻭﺍﻣﺮ ﺗﻨﻔﺬ‬‫ﻋﻠﻰ ﻋﺘﺎﺩ ﻣﺎ. ﻭﺃﻱ ﻣﺘﺤﻜﻢ ﳛﻮﻱ ﻏﺎﻟﺒﺎ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﺳﻮﺍءﺍ ﻛﺎﻧﺖ ﻹﺭﺳﺎﻝ ﻭﺍﺳﺘﻘﺒﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺃﻭ‬‫ﻟﻸﻭﺍﻣﺮ ، ﻭﺃﻱ ﻣﺴﺠﻞ ﳚﺐ ﺃﻥ ﻳﺄﺧﺬ ﺭﻗﻢ ﻓﺮﻳﺪ ﳝﻴﺰﻩ ﻋﻦ ﺑﻘﻴﺔ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﺃﻭ ﰲ‬‫ﺃﻱ ﻣﺘﺤﻜﻢ ﺁﺧﺮ ﻭﺫﻟﻚ ﺣﱴ ﳝﻜﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ ﺑﺮﳎﻴﴼ ، ﻫﺬﺍ ﺍﻟﺮﻗﻢ ﻳﻌﺮﻑ ﺑﺎﺳﻢ ﺍﳌﻨﻔﺬ )‪ (Port‬ﻭﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ‬‫ﻋﻨﻪ ﻻﺣﻘﴼ. ﻭﻋﻤﻞ ﺍﳌﺘﺤﻜﻢ ﻳﺒﺪﺃ ﻋﻨﺪﻣﺎ ‪‬ﺮﺳﻞ ﺃﻣﺮ ﺍﻟﻴﻪ ﺣﻴﺚ ﻳﺒﺪﺃ ﺍﳌﺘﺤﻜﻢ ﰲ ﺗﻨﻔﻴﺬ ﻫﺬﺍ ﺍﻷﻣﺮ ﻭﻣﻦ ﰒ ﻳﻀﻊ‬ ‫ﻳ‬ ‫ﺍﻟﻨﺘﻴﺠﺔ ﰲ ﺃﺣﺪ ﻣﺴﺠﻼﺗﻪ ﻭﻳﺮﺳﻞ ﺇﺷﺎﺭﺓ )‪ (Interrupt‬ﺍﱃ ﺍﳌﻌﺎﰿ ﻟﻜﻲ ﻳﻘﻮﻡ ﺑﻘﺮﺍﺋﺔ ﺍﻟﻘﻴﻤﺔ.‬‫ﻭﻋﻮﺩﺓ ﺑﺎﳊﺪﻳﺚ ﻋﻦ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺍﻟﺬﻱ ﻳﺘﻮﺍﺟﺪ ﻏﺎﻟﺒﺎ ﻋﻠﻰ ﻣﺘﺤﻜﻢ ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ )‪(NorthBridge‬‬‫ﺇﻧﻈﺮ ﺍﻟﺸﻜﻞ ٢.٣ .ﺣﻴﺚ ﺗﻜﻤﻦ ﻭﻇﻴﻔﺘﻪ ﺍﻷﺳﺎﺳﻴﺔ ﰲ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺗﻨﻔﻴﺬﻫﺎ ، ﻭﻳﻘﻮﻡ‬‫ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﺑﺘﻮﺟﻴﻪ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﺃﻱ ﻣﻦ ﺷﺮﺍﺋﺢ ﺍﻟﺬﺍﻛﺮﺓ ﻛﺬﻟﻚ ﻳﻘﻮﻡ ﺑﺈﻋﺎﺩﺓ ﺗﻨﻌﻴﺶ )‪ (Refresh‬ﻫﺬﻩ‬ ‫ﺍﻟﺬﺍﻛﺮﺓ ﻃﻴﻠﺔ ﻋﻤﻞ ﺍﳊﺎﺳﺐ ﺣﱴ ﻻ ﺗﻔﻘﺪ ﺍﻟﺬﺍﻛﺮﺓ ﳏﺘﻮﻳﺎ‪‬ﺎ.‬ ‫ﺷﻜﻞ ٢.٣.: ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ‬‫ﻳﻌﺘﱪ ﻫﺬﺍ ﺍﳉﺴﺮ ﺣﻠﻘﺔ ﺍﻟﻮﺻﻞ ﻣﺎ ﺑﲔ ﺍﳌﻌﺎﰿ ﻭﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺍﻟﺒﺎﻳﻮﺱ ﻭﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﻭﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ‬ ‫ﻭﺍﻹﺧﺮﺍﺝ ﺣﻴﺚ ﻳﺴﺘﻘﺒﻞ ﺍﻷﻭﺍﻣﺮ ﻭﻳﻘﻮﻡ ﺑﺘﻮﺟﻴﻬﻬﺎ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﳌﻄﻠﻮﺏ.‬ ‫٢.١.٣. ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ‬‫ﻳﺴﺘﺨﺪﻡ ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ )ﻭﻳﺴﻤﻰ ﺃﻳﻀﺎ ﺍﳉﺴﺮ ﺍﳉﻨﻮﰊ ‪ (SouthBridge‬ﰲ ﺭﺑﻂ ﻣﺘﺤﻜﻤﺎﺕ ﺃﺟﻬﺰﺓ‬‫ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻣﻊ ﺍﳌﻌﺎﰿ ﻭﻫﺬﺍ ﻳﺘﻀﺢ ﻣﻦ ﺍﻟﺸﻜﻞ ٢.٢. ﺣﻴﺚ ﻳﻈﻬﺮ ﺃﻥ ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ ﻳﺮﺗﺒﻂ ﻣﺒﺎﺷﺮﺓ ﻣﻊ‬‫ﺍﳌﻌﺎﰿ ﺑﻴﻨﻤﺎ ﺍﳉﺴﺮ ﺍﳉﻨﻮﰊ ﻳﺮﺗﺒﻂ ﻣﻊ ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ ﻭﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻳﺮﺑﻂ ﻣﺘﺤﻜﻤﺎﺕ ﻋﺘﺎﺩ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ‬‫ﰲ ﺍﳊﺎﺳﺐ. ﻭﻛﻞ ﺟﻬﺎﺯ ﻳﺮﺗﺒﻂ ﺑﺎﳊﺎﺳﺐ )ﻣﺜﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﺃﻭ ﺍﻟﻔﺄﺭﺓ ﺃﻭ ﺍﻟﻄﺎﺑﻌﺔ ...ﺍﱁ( ﻟﺪﻳﻪ ﻣﺘﺤﻜﻢ ﺑﺪﺍﺧﻠﻪ‬‫ﻭﻣﺘﺤﻜﻢ ﺁﺧﺮ ﺑﺪﺍﺧﻞ ﺍﳊﺎﺳﺐ ، ﺣﻴﺚ ﻳﺮﺳﻞ ﺍﳌﺘﺤﻜﻢ ﺍﳌﻮﺟﻮﺩ ﺑﺪﺍﺧﻞ ﺍﳊﺎﺳﺐ ﺍﻷﻭﺍﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﳌﻮﺟﻮﺩ‬‫ﺑﺪﺍﺧﻞ ﺍﻟﻌﺘﺎﺩ . ﻭﻟﱪﳎﺔ ﺃﻱ ﺟﻬﺎﺯ ﻓﺎﻧﻪ ﳚﺐ ﺑﺮﳎﺔ ﺍﳌﺘﺤﻜﻢ ﺍﳌﻮﺟﻮﺩ ﰲ ﺍﳊﺎﺳﺐ ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﻣﻌﺮﻓﺔ‬‫ﺍﳌﺴﺠﻼﺕ )‪ (Registers‬ﺍﳌﻮﺟﻮﺩﺓ ﺑﻪ ﻭﻭﻇﻴﻔﺔ ﻛﻞ ﻣﺴﺠﻞ ﻓﻴﻪ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺇﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﻟﺼﺤﻴﺤﺔ ﺍﻟﻴﻪ.‬ ‫٨١‬
    • ‫٢.٢. ﺍﳌﻌﺎﰿ‬‫‪ (So‬ﲝﻴﺚ ﲤﻴﺰ ﻫﺬﻩ ﺍﻷﺭﻗﺎﻡ ﺍﳌﺴﺠﻼﺕ‬ ‫)‪ware Ports‬‬ ‫ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﺗﺄﺧﺬ ﺃﺭﻗﺎﻣﺎ ﻣﻌﻴﻨﺔ ﺗﺴﻤﻰ ﻣﻨﺎﻓﺬ ﺑﺮﳎﻴﺔ‬ ‫ﻣﻦ ﺑﻌﻀﻬﺎ ﺍﻟﺒﻌﺾ ٣.‬ ‫‪Ports‬‬ ‫ﺍﳌﻨﺎﻓﺬ‬‫ﻳﺴﺘﺨﺪﻡ ﻣﻔﻬﻮﻡ ﺍﳌﻨﺎﻓﺬ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﺐ ﻟﻠﺪﻻﻟﺔ ﻋﻠﻰ ﻋﺪﺓ ﺃﺷﻴﺎء ﻓﻤﺜﻼ ﰲ ﳎﺎﻝ ﺑﺮﳎﺔ ﺍﻟﺸﺒﻜﺎﺕ ﺗﻜﻮﻥ ﺑﺮﺍﻣﺞ‬‫ﺍﳋﺎﺩﻡ ﳍﺎ ﺭﻗﻢ ﻣﻨﻔﺬ ﻣﻌﲔ ﺣﱴ ﺗﺴﻤﺢ ﻟﱪﺍﻣﺞ ﺍﻟﻌﻤﻴﻞ ﺑﺎﻻﺗﺼﺎﻝ ﻣﻌﻬﺎ، ﻛﺬﻟﻚ ﺭﲟﺎ ﻳﻘﺼﺪ ﺑﺎﳌﻔﻬﻮﻡ ﺍﳌﻨﺎﻓﺬ ﺍﳌﻮﺟﻮﺩﺓ‬‫ﰲ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ ﻟﻮﺻﻞ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ‪‬ﺎ ، ﺃﻳﻀﺎ ﻗﺪ ﻳﺪﻝ ﺍﳌﻔﻬﻮﻡ ﻋﻠﻰ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻋﻠﻰ‬‫ﺍﳉﻬﺎﺯ ﻭﻫﺬﺍ ﻣﺎ ﺳﻨﻘﺼﺪﻩ ﰲ ﺣﺪﻳﺜﻨﺎ ﻋﻦ ﺍﳌﻨﺎﻓﺬ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ. ﻭ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﳌﻨﺎﻓﺬ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻭﺍﻟﱵ‬‫ﺗﻌﺮﻑ ﺏ ‪ I/O ports‬ﺑﺎﺳﺘﺨﺪﺍﻡ ﺗﻌﻠﻴﻤﺔ ﺍﳌﻌﺎﰿ ‪ in port address‬ﻭﺍﻟﺘﻌﻠﻴﻤﺔ ‪out port address‬‬‫ﺣﻴﺚ ﺗﺴﺘﺨﺪﻡ ﺍﻷﻭﱃ ﻟﻘﺮﺍءﺓ ﻗﻴﻤﺔ ﻣﻦ ﻣﺴﺠﻞ ﰲ ﻣﺘﺤﻜﻢ ﻭﻭﺿﻌﻬﺎ ﰲ ﺃﺣﺪ ﻣﺴﺠﻼﺕ ﺍﳌﻌﺎﰿ ﺃﻣﺎ ﺍﻟﺘﻌﻠﻴﻤﺔ‬‫ﺍﻟﺜﺎﻧﻴﺔ ﺗﺴﺘﺨﺪﻡ ﻟﻜﺘﺎﺑﺔ ﻗﻴﻤﺔ ﰲ ﻣﺴﺠﻞ ﻟﻠﻤﻌﺎﰿ ﺍﱃ ﻣﺴﺠﻞ ﰲ ﺍﳌﺘﺤﻜﻢ . ﻭﻋﻨﺪ ﺍﺳﺘﺨﺪﺍﻡ ﺃﺣﺪ ﻫﺬﻳﻦ ﺍﻷﻣﺮﻳﻦ‬‫ﻓﺎﻥ ﺫﻟﻚ ﻳﻌﲏ ﺃﻥ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻮﺟﻪ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻭﻟﻴﺲ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ‬‫ﺑﺘﻌﲔ ﻗﻴﻤﺔ ﺍﳋﻂ ‪ ACCESS‬ﺍﳌﻮﺟﻮﺩ ﰲ ﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ )‪ (Control Bus‬ﻭﺑﺎﻟﺘﺎﱄ ﻳﺴﺘﺠﻴﺐ ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ‬‫ﻭﺍﻹﺧﺮﺍﺝ ﻭﻳﻘﺮﺃ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻭﻳﻘﻮﻡ ﺑﺘﻮﺟﻴﻬﻪ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﳌﻄﻠﻮﺏ . ﻭﻫﻨﺎﻙ ﺑﻌﺾ ﺍﻷﺟﻬﺰﺓ ﺗﺴﺘﺨﺪﻡ ﻋﻨﻮﺍﻳﻦ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﻟﻠﻮﺻﻮﻝ ﻟﻠﻤﺘﺤﻜﻢ ﺍﳋﺎﺹ ‪‬ﺎ ﻭﻫﻮ ﻣﺎ ﻳﻌﺮﻑ ﺏ ‪ Memory Mapped I/O‬ﺣﻴﺚ ﻋﻨﺪ ﻛﺘﺎﺑﺔ ﺃﻱ ﺑﻴﺎﻧﺎﺕ‬‫ﻋﻠﻰ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻓﺎﻥ ﺫﻟﻚ ﻳﻌﲏ ﻛﺘﺎﺑﺔ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻋﻠﻰ ﻣﺘﺤﻜﻤﺎﺕ ﻟﻸﺟﻬﺰﺓ ﻭﻟﻴﺲ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ.‬‫ﻓﻤﺜﻼً ﻋﻨﺪ ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺍﻟﺬﺍﻛﺮﺓ 0‪ 0xa000:0x‬ﻓﺎﻥ ﻫﺬﺍ ﻳﺆﺩﻱ ﺍﱃ ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻰ ﺷﺎﺷﺔ ﺍﳊﺎﺳﺐ ﻧﻈﺮﴽ‬‫ﻻﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ ﻣﻮﺟﻪ )‪ (Memory Mapped‬ﻣﻊ ﻣﺘﺤﻜﻢ ﺷﺎﺷﺔ ﺍﳊﺎﺳﺐ ﻭﺍﳉﺪﻭﻝ ٢.١ ﻳﻮﺿﺢ ﺧﺮﻳﻄﺔ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪ ،x‬ﻭﻻ ﲢﺘﺎﺝ ﺍﻟﻜﺘﺎﺑﺔ ﳌﺜﻞ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻷﻭﺍﻣﺮ ‪ in/out‬ﺑﻌﻜﺲ ﺍﻟﻜﺘﺎﺑﺔ‬ ‫ﰲ ﻋﻨﻮﺍﻳﻦ ﺍﳌﻨﺎﻓﺬ ‪. port I/O‬‬‫ﻋﻨﺎﻭﻳﻦ ﻣﻨﺎﻓﺬ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ )‪ (Port I/O‬ﻫﻲ ﻋﻨﺎﻭﻳﻦ ﺗﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﺘﺤﻜﻤﺎﺕ‬‫ﻭﻳﻘﻮﻡ ﺍﻟﺒﺎﻳﻮﺱ ﲟﻬﻤﺔ ﺗﺮﻗﻴﻢ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ، ﻭﺍﳉﺪﻭﻝ ٢.٢ ﻳﻌﺮﺽ ﻗﺎﺋﻤﺔ ﺑﻌﻨﺎﻭﻳﻦ ﺍﳌﻨﺎﻓﺬ ﻭﻭﻇﻴﻔﺔ ﻛﻞ ﻣﻨﻬﻢ.‬ ‫٢.٢. ﺍﳌﻌﺎﰿ‬ ‫ﻳﻌﺘﱪ ﺍﳌﻌﺎﰿ ﻫﻮ ﺍﳌﺤﺮﻙ ﺍﻟﺮﺋﻴﺴﻲ ﳉﻬﺎﺯ ﺍﳊﺎﺳﺐ ﺣﻴﺚ ﻳﺴﺘﻘﺒﻞ ﺍﻷﻭﺍﻣﺮ ﻭﻳﻘﻮﻡ ﺑﺘﻔﻴﺬﻫﺎ .‬ ‫٣ﻫﻨﺎﻙ ﺑﻌﺾ ﺍﳌﺴﺠﻼﺕ ﻟﺒﻌﺾ ﺍﳌﺘﺤﻜﻤﺎﺕ ﺗﺄﺧﺬ ﻧﻔﺲ ﺍﻟﺮﻗﻢ ، ﻟﻜﻦ ﻃﺒﻴﻌﺔ ﺍﻷﻣﺮ ﺍ ُﺮﺳﻞ )ﻗﺮﺍءﺓ ﺃﻭ ﻛﺘﺎﺑﺔ( ﻫﻮ ﺍﻟﺬﻱ ﳛﺪﺩ ﺍﳌﺴﺠﻞ‬ ‫ﳌ‬ ‫ﺍﻟﺬﻱ ﳚﺐ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ.‬‫٩١‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬ ‫ﺟﺪﻭﻝ ٢.١.: ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ ﳊﻮﺍﺳﻴﺐ‬ ‫68‪x‬‬ ‫ﻋﻨﻮﺍﻥ ﺍﻟﺒﺪﺍﻳﺔ ﻋﻨﻮﺍﻥ ﺍﻟﻨﻬﺎﻳﺔ ﺍﻟﻮﺻﻒ‬ ‫ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ‪IVT‬‬ ‫‪0x003ff‬‬ ‫00000‪0x‬‬ ‫ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ‬ ‫‪0x004ff‬‬ ‫00400‪0x‬‬ ‫ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ‬ ‫‪0x07bff‬‬ ‫00500‪0x‬‬ ‫ﺑﺮﻧﺎﻣﺞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫‪0x07dff‬‬ ‫00‪0x07c‬‬ ‫ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ‬ ‫‪0x9ffff‬‬ ‫00‪0x07e‬‬ ‫ﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ‪Video RAM‬‬ ‫‪0xaffff‬‬ ‫0000‪0xa‬‬ ‫ﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﺃﺣﺎﺩﻳﺔ ﺍﻟﻠﻮﻥ ‪Monochrome VRAM‬‬ ‫7777‪0xb‬‬ ‫0000‪0xb‬‬ ‫ﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﺍﳌﻠﻮﻧﺔ ‪Color VRAM‬‬ ‫‪0xbffff‬‬ ‫0008‪0xb‬‬ ‫ﺫﺍﻛﺮﺓ ‪Video ROM BIOS‬‬ ‫‪0xc7fff‬‬ ‫0000‪0xc‬‬ ‫ﻣﻨﻄﻘﺔ ‪BIOS Shadow Area‬‬ ‫‪0xeffff‬‬ ‫0008‪0xc‬‬ ‫ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ‬ ‫‪0xfffff‬‬ ‫0000‪0xf‬‬ ‫٢.٢.١. ﺩﻭﺭﺓ ﺗﻨﻔﻴﺬ ﺍﻟﺘﻌﻠﻴﻤﺎﺕ‬‫ﻟﻜﻲ ‪‬ﻨﻔﺬ ﺍﳌﻌﺎﰿ ﺍﻟﱪﺍﻣﺞ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻥ ﻫﺬﺍ ﻳﺘﻄﻠﺐ ﺑﻌﻀﺎ ﻣﻦ ﺍﳋﻄﻮﺍﺕ ﺍﻟﱵ ﳚﺐ ﺃﻥ ﻳﻘﻮﻡ ‪‬ﺎ ،‬ ‫ﻳ‬ ‫ﻭﰲ ﻛﻞ ﺩﻗﺔ ﻟﻠﺴﺎﻋﺔ )‪ (Clock ck‬ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ ﺑﺎﻟﺒﺪء ﲞﻄﻮﺓ ﻣﻦ ﻫﺬﻩ ﺍﳋﻄﻮﺍﺕ ، ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺳﺮﺩﺍ ﳍﺎ.‬‫ﺃﻭﻻﹰ ﻣﺮﺣﻠﺔ ﺟﻠﺐ ﺍﻟﺒﻴﺎﻧﺎﺕ )‪ (Fetch‬ﻭﻓﻴﻬﺎ ﻳﺘﻢ ﺟﻠﺐ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﺍﱃ ﺍﳌﺴﺠﻼﺕ ﺑﺪﺍﺧﻞ‬ ‫ﺍﳌﻌﺎﰿ.‬ ‫ﺛﺎﻧﻴﴼ ﻣﺮﺣﻠﺔ ﺗﻔﺴﲑ ﺍﻟﺒﻴﺎﻧﺎﺕ )‪.(Decode‬‬ ‫ﺛﺎﻟﺜﴼ ﻣﺮﺣﻠﺔ ﺗﻨﻔﻴﺬ ﺍﻟﺒﻴﺎﻧﺎﺕ )‪.(Execute‬‬ ‫ﺭﺍﺑﻌﴼ ﻣﺮﺣﻠﺔ ﺣﻔﻆ ﺍﻟﻨﺘﺎﺋﺞ )‪.(Write back‬‬ ‫‪CPU Modes‬‬ ‫٢.٢.٢. ﺃﳕﺎﻁ ﻋﻤﻞ ﺍﳌﻌﺎﰿ‬‫ﻋﻨﺪﻣﺎ ﻃﺮﺣﺖ ﺷﺮﻛﺔ ﺃﻧﺘﻞ ﺃﻭﻝ ﺍﺻﺪﺍﺭﺓ ﻣﻦ ﻣﻌﺎﳉﺎﺕ ٦١ ﺑﺖ ﱂ ﻳﻜﻦ ﻫﻨﺎﻙ ﻣﺎ ﻳﻌﺮﻑ ﺑﺄﳕﺎﻁ ﺍﳌﻌﺎﰿ ﺣﻴﺚ‬‫ﻛﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﺑﻨﻤﻂ ﻭﺍﺣﺪ ﻭﻫﻮ ﻣﺎ ﻳﻌﺮﻑ ﺍﻻﻥ ﺑﺎﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ )‪ ، (Real Mode‬ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻳﻘﻮﻡ‬‫ﺍﳌﻌﺎﰿ ﺑﺘﻨﻔﻴﺬ ﺃﻱ ﺃﻣﺮ ﻣﻮﺟﻪ ﺍﻟﻴﻪ ﻭﻻ ﻳﻮﺟﺪ ﻣﺎ ‪‬ﻌﺮﻑ ﺑﺼﻼﺣﻴﺎﺕ ﺍﻟﺘﻨﻔﻴﺬ ﺣﻴﺚ ﳝﻜﻦ ﻟﱪﻧﺎﻣﺞ ﻟﻠﻤﺴﺘﺨﺪﻡ ﺃﻱ‬ ‫ﻳ‬‫ﻳﻘﻮﻡ ﺑﺘﻨﻔﻴﺬ ﺃﻣﺮ ﻳﺘﺴﺒﺐ ﰲ ﺍﻳﻘﺎﻑ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ )ﻣﺜﻞ ﺍﻷﻣﺮ ‪ ، (hlt‬ﻛﺬﻟﻚ ﺗﻮﺟﺪ ﻋﺪ ‪ ‬ﻣﻦ ﺍﳌﺸﺎﻛﻞ‬ ‫ﺩ‬‫ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻓﻤﺜﻼ ﻻ ﺗﻮﺟﺪ ﲪﺎﻳﺔ ﻟﻠﺬﺍﻛﺮﺓ ﻣﻦ ﺑﺮﳎﻴﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ ﻭﻻ ﻳﻮﺟﺪ ﺃﻱ ﺩﻋﻢ ﳌﻔﻬﻮﻡ ﺗﻌﺪﺩ ﺍﳌﻬﺎﻡ‬‫)‪ .(Mul tasking‬ﻟﺬﻟﻚ ﺳﺎﺭﻋﺖ ﺃﻧﺘﻞ ﺑﺎﺩﺧﺎﻝ ﻋﺪﺓ ﺃﳕﺎﻁ ﻋﻠﻰ ﺑﻨﻴﺔ ﺍﳌﻌﺎﰿ ﻟﺘﺤﻞ ﻫﺬﻩ ﺍﳌﺸﺎﻛﻞ ، ﲝﻴﺚ ‪‬ﻤﻜﻦ‬ ‫ﻳ‬‫ﻟﻠﻤﻌﺎﰿ ﺃﻱ ﻳﻌﻤﻞ ﰲ ﺃﻱ ﳕﻂ ﻭﺃﻥ ﻳﻘﻮﻡ ﺑﺎﻟﺘﺤﻮﻳﻞ ﻭﻗﺘﻤﺎ ﺷﺎء. ﻭُﻌ ﱠﻑ ﳕﻂ ﺍﳌﻌﺎﰿ ﺑﺄﻧﻪ ﻃﺮﻳﻘﺔ ﻣﻌﻴﻨﺔ ﻳﺘﺒﻌﻬﺎ‬ ‫ﻳﺮ‬ ‫٠٢‬
    • ‫٢.٢. ﺍﳌﻌﺎﰿ‬ x86 ‫ﺟﺪﻭﻝ ٢.٢.: ﻣﻨﺎﻓﺬ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﳊﻮﺍﺳﻴﺐ‬ ‫ﺍﻹﺳﺘﺨﺪﺍﻡ‬ ‫ﺭﻗﻢ ﺍﳌﻨﻔﺬ‬ Slave DMA controller 0000-000f System 0010-001F First Interrupt controller (8259 chip) 0020-0021 Second interrupt controller 0030-0031 Programable Interval Timer 1 (8254 chip) 0040-0043 Programable Interval Timer 2 0048-004B System devices 0050-006F NMI Enable / Real Time Clock 0070-0071 DMA Page registers 0080-008B System devices 0090-009F Slave interrupt controller 00A0-00A1 Master DMA controller 00C0-00DE System devices 00F0-00FF System devices 0100-0167 IDE Interface - Quaternary channel 0168-016F IDE interface - Secondary channel 0170-0177 IDE Interface - Ter ary channel 01E8-01EF IDE interface - Primary channel 01F0-01F7 Games Port (joys ck port) 0200-0207 Usually used by sound cards, also used by NOVEL NETWARE KEY CARD 0220-022F Plug and Play hardware 0270-0273 Parallel Port * 0278-027A Some mes used for LCD Display I/O 0280-028F Alternate VGA Video Display Adaptor assignment (secondary address) 02B0-02DF GPIB 0, data aquisi on card 0 (02E1 to 02E3 only) 02E0-02E7 Serial Port - COM 4 02E8-02EF Serial Port - COM 2 02F8-02FF O en used as a default for Network Interface cards (was prototype card) 0300-031F ST506 and ESDI Hard Disk Drive Interface (mostly used in PX/XT and early PC/AT) 0320-023F MPU-401 (midi) interface, on Sound Cards 0330-0331 Some mes used for Network Interface cards 0360-036F Another address used by the Secondary IDE Controller (see 0170-0177) 0376-0377 Parallel Port * 0378-037A FM (sound) synthesis port on sound cards 0388-038B MDA, EGA and VGA Video Display Adaptor (only 03B0 to 03BB used) 03B0-03BB Parallel Port (originally only fi ed to IBM mono display adaptors) * 03BC-03BF EGA / VGA Video Display Adaptor, (Primary address) 03C0-03DF PCIC PCMCIA Port Controller 03E0-03E7 Serial Port - COM 3 03E8-03EF Floppy Disk Drive Interface 03F0-03F6٢١ Port - COMused by the Primary IDE Controller (see 01F0-01F7) Another address Serial 1 03F7-03f7 03F8-03FF Windows sound system (used by many sound cards) 0533-0537
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬‫ﺍﳌﻌﺎﰿ ﺃﺛﻨﺎء ﻋﻤﻠﻪ ﻟﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﻓﻤﺜﻼ ﳛﺪﺩ ﺍﻟﻨﻤﻂ ﺍﳌﺴﺘﺨﺪﻡ ﻣﺎ ﺇﺫﺍ ﻛﺎﻥ ﻫﻨﺎﻙ ﲪﺎﻳﺔ ﻟﻌﻨﻮﺍﻳﻦ ﺍﻟﺬﺍﻛﺮﺓ ﲝﻴﺚ ﻻ‬ ‫ﳝﻜﻦ ﻟﱪﻧﺎﻣﺞ ﻻ ﳝﺘﻠﻚ ﺻﻼﺣﻴﺎﺕ ﻣﻌﻴﻨﺔ ﺍﻟﻮﺻﻮﻝ ﻷﻱ ﻣﻨﻄﻘﺔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ.‬ ‫‪Real Mode‬‬ ‫٢.٢.٣. ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ‬‫ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻫﻮ ﺍﻟﺬﻱ ﻳﺒﺪﺃ ﺍﳉﻬﺎﺯ ﺍﳊﺎﺳﺐ ﺑﺎﻟﻌﻤﻞ ﻋﻨﺪﻣﺎ ﻳﻘﻠﻊ ﻭﻫﺬﺍ ﺑﺴﺒﺐ ﺃﻥ ﺣﻮﺍﺳﻴﺐ 68‪ x‬ﰎ ﺗﺼﻤﻴﻤﻬﺎ‬‫ﲝﻴﺚ ﺗﺪﻋﻢ ﺍﻷﺟﻬﺰﺓ ﺍﻟﻘﺪﳝﺔ ﻭﺣﱴ ﲢﺎﻓﻆ ﺍﻧﺘﻞ ﻋﻠﻰ ﺫﻟﻚ ﻓﺎﻥ ﻫﺬﺍ ﻣﺎ ﺟﻌﻠﻬﺎ ﺗﺪﻉ ﺍﳌﻌﺎﰿ ﻳﺒﺪﺃ ﺑﺎﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ‬‫ﻋﻨﺪ ﺍﻹﻗﻼﻉ ﺗﻮﺍﻓﻘﴼ ﻣﻊ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﻘﺪﳝﺔ ، ﻭﺑﻌﺪ ﺫﻟﻚ ﻋﻨﺪﻣﺎ ﻳﺴﺘﻠﻢ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺯﻣﺎﻡ ﺍﻟﺘﺤﻜﻢ ﺑﺎﳊﺎﺳﺐ‬‫ﻓﺎﻧﻪ ﳐ ٌ ﻣﺎ ﺑﲔ ﺍﻹﺳﺘﻤﺮﺍﺭ ﺑﺎﻟﻌﻤﻞ ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻭﺑﺎﻟﺘﺎﱄ ﻳﺴﻤﻰ ﻫﺬﺍ ﺍﻟﻨﻈﺎﻡ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ٦١ ﺑﺖ ﻭﺑﲔ ﲢﻮﻳﻞ‬ ‫ﲑ‬‫ﳕﻂ ﺍﳌﻌﺎﰿ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﻻﺧﺮ ﻭﻫﻮ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ )‪ (Protected Mode‬ﻭﺑﺎﻟﺘﺎﱄ ﻳﺴﻤﻰ ﺍﻟﻨﻈﺎﻡ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ٢٣‬‫ﺑﺖ. ﻭ ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻳﺴﺘﺨﺪﻡ ﺍﳌﻌﺎﰿ ﻣﺴﺠﻼﺕ ﻣﻦ ﻃﻮﻝ ٦١ ﺑﺖ )ﻣﺜﻼﹰ ﺍﳌﺴﺠﻼﺕ ‪(ax,bx,cx,dx,...etc‬‬‫ﻭﻳﺴﺘﺨﺪﻡ ﻋﻨﻮﻧﺔ ﺍﳌﻘﻄﻊ:ﺍﻹﺯﺍﺣﺔ )‪ (Segment:Offset‬ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ - ﺳﻴﺘﻢ ﺷﺮﺣﻬﺎ ﰲ ﺍﻟﻔﻘﺮﺓ‬‫ﺍﻟﺘﺎﻟﻴﺔ- ﻭﺃﻳﻀﺎ ﻳﺪﻋﻢ ﺫﺍﻛﺮﺓ ﲝﺠﻢ 1 ﻣﻴﺠﺎﺑﺎﻳﺖ ﻭﻻ ﻳﻘﺪﻡ ﺃﻱ ﺩﻋﻢ ﳊﻤﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ )‪Virtual‬‬ ‫‪ (Memory‬ﻭﻻ ﻳﻮﻓﺮ ﲪﺎﻳﺔ ﻟﻠﺬﺍﻛﺮﺓ ﻣﻦ ﺑﺮﳎﻴﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ.‬ ‫ﻋﻨﻮﻧﺔ ﺍﳌﻘﻄﻊ:ﺍﻹﺯﺍﺣﺔ )‪(Segment:Offset Addressing‬‬‫ﺑﻌﺪ ﻃﺮﺡ ﺃﻧﺘﻞ ﳌﻌﺎﰿ 6808 ﻭﻫﻮ ﺃﻭﻝ ﻣﻌﺎﰿ ٦١ ﺑﺖ ، ﻇﻬﺮﺕ ﻣﺸﻜﻠﺔ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﺃﻥ ﻃﻮﻝ ﺍﳌﺴﺠﻼﺕ‬‫ﺍﳌﺴﺘﺨﺪﻣﺔ ﰲ ﻫﺬﺍ ﺍﳌﻌﺎﰿ )ﻣﺴﺠﻼﺕ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﻌﻨﺎﻭﻳﻦ( ﻫﻮ ٦١ ﺑﺖ ﻭﻫﺬﺍ ﻣﺎ ﲰﺢ ﻟﻠﻤﺴﺠﻞ ﺑﺄﻥ ﻳﺘﻌﺎﻣﻞ‬‫ﻣﻊ ٤٦ ﻛﻴﻠﻮﺑﺎﻳﺖ ﻓﻘﻂ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻥ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ )‪ (Address Bus‬ﰲ ﻫﺬﻩ ﺍﻷﺟﻬﺰﺓ‬‫ﻛﺎﻥ ﲝﺠﻢ ٠٢ ﺑﺖ ﻭﻫﻮ ﻣﺎ ﻳﺴﻤﺢ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺫﺍﻛﺮﺓ ﲝﺠﻢ ١ ﻣﻴﺠﺎ. ﺍﱃ ﻫﻨﺎ ﻛﺎﻥ ﺍﳋﻴﺎﺭ ﺃﻣﺎﻡ ﺷﺮﻛﺔ ﺃﻧﺘﻞ‬‫ﻫﻮ ﺑﺰﻳﺎﺩﺓ ﺣﺠﻢ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﺑﺪﺍﺧﻞ ﺍﳌﻌﺎﰿ ﻭﻟﻜﻦ ﻫﺬﺍ ﺍﳊﻞ ﻛﺎﻥ ﻣﻜﻠﻔﴼ ﺟﺪﺍ ﺁﻧﺬﺍﻙ ﻧﻈﺮﴽ ﻹﻥ ﻫﺬﻩ‬‫ﺍﳌﺴﺠﻼﺕ ﻫﻲ ﺫﻭﺍﻛﺮ ﻣﻦ ﺍﻟﻨﻮﻉ ‪ SRAM‬ﻭﻫﻮ ﻧﻮﻉ ﻣﻜﻠﻔﹼ ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺇﻣﻜﺎﻧﻴﺎﺗﻪ ﺍﻟﻌﺎﻟﻴﺔ. ﻣﺎ ﻓﻌﻠﺘﻪ ﺍﻧﺘﻞ ﻫﻮ‬ ‫ﺎ‬‫ﺇﳚﺎﺩ ﻃﺮﻳﻘﺔ ﳐﺘﻠﻔﺔ ﻟﻌﻨﻮﻧﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺒﺪﻻً ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﺴﺠﻞ ﻭﺍﺣﺪ ﻟﻠﻮﺻﻞ ﺍﱃ ﻋﻨﺎﻭﻳﻦ ﺍﻟﺬﺍﻛﺮﺓ ﰎ ﺍﺳﺘﺨﺪﺍﻡ‬‫ﻣﺴﺠﻠﲔ ﻛﻞ ﻣﻨﻬﻤﺎ ﺑﻄﻮﻝ ٦١ ﺑﺖ ، ﺍﻟﻔﻜﺮﺓ ﻛﺎﻧﺖ ﰲ ﺗﻘﺴﻴﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﱃ ﻣﻘﺎﻃﻊ )‪ (Segments‬ﻭُﺴﺘﺨﺪﻡ‬ ‫ﻳ‬‫ﺃﺣﺪ ﺍﳌﺴﺠﻼﺕ ﻟﻠﺪﻻﻟﺔ ﻋﻠﻰ ﺭﻗﻢ ﺃﻭ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ )‪ (Segment Number or Address‬ﻭﺑﺎﻟﺘﺎﱄ ﻫﻨﺎﻙ ٦٣٥٥٦‬‫ﻣﻘﻄﻊ ﳐﺘﻠﻒ ٤ ﻭُﺴﺘﺨﺪﻡ ﺍﳌﺴﺠﻞ ﺍﻵﺧﺮ ﻟﻠﻮﺻﻞ ﺍﱃ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺑﺪﺍﺧﻞ ﺍﳌﻘﻄﻊ ﻭﻫﻲ ﻣﺎ ﺗﻌﺮﻑ ﺑﺎﻟﻘﻴﻢ )‪(Offsets‬‬ ‫ﻳ‬‫ﺑﺪﺍﺧﻞ ﺍﳌﻘﻄﻊ ﻭﺑﺎﻟﺘﺎﱄ ﻛﻞ ﻣﻘﻄﻊ ﳛﻮﻱ ٦٣٥٥٦ ﺑﺎﻳﺖ )ﺃﻱ ﺃﻥ ﺣﺠﻢ ﺍﳌﻘﻄﻊ ﻫﻮ ٤٦ ﻛﻴﻠﻮﺑﺎﻳﺖ(. ﺇﺫﴽ‬‫‪‬ﻌ ﱠﻑ ﺍﳌﻘﻄﻊ ‪ Segments‬ﺑﺄ‪‬ﺎ ﻣﻨﻄﻘﺔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﲝﺠﻢ ٤٦ ﻛﻴﻠﻮﺑﺎﻳﺖ ﻭﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﻣﻘﻄﻊ ﻭﺫﻟﻚ‬ ‫ﻳﺮ‬‫ﺑﺘﺤﻤﻴﻞ ﺭﻗﻢ ﺍﳌﻘﻄﻊ ﺃﻭ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﺍﱃ ﺃﻱ ﻣﻦ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﺍﳌﻮﺟﻮﺩﺓ ﺑﺪﺍﺧﻞ ﺍﳌﻌﺎﰿ )ﻣﺜﻞ ﺍﳌﺴﺠﻼﺕ‬‫‪ - (CS,SS,DS,ES‬ﺳﻴﺘﻢ ﺷﺮﺣﻬﺎ ﻻﺣﻘﺎ - ، ﻭﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﳏﺘﻮﻳﺎﺕ ﺍﳌﻘﻄﻊ ﺍﻹﺯﺍﺣﺔ ‪ Offset‬ﻭﺫﻟﻚ‬ ‫٤ﻫﺬﺍ ﻧﺎﺗﺞ ﻣﻦ ﺣﺴﺎﺏ 612.‬ ‫٢٢‬
    • ‫٢.٢. ﺍﳌﻌﺎﰿ‬‫0‪0x‬‬ ‫ﺑﺘﺤﻤﻴﻞ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻮﺏ ﺍﻟﻮﺻﻞ ﺍﻟﻴﻪ ﺍﱃ ﺃﻱ ﻣﻦ ﻣﺴﺠﻼﺕ ﺍﻟﻘﻴﻢ )ﺗﺒﺪﺃ ﺍﻟﻌﻨﺎﻭﻳﻦ ﰲ ﺃﻱ ﻣﻘﻄﻊ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ‬‫ﺍﱃ ‪ .(0xffff‬ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﱵ ﺍﻗﺘﺮﺣﺘﻬﺎ ﺍﻧﺘﻞ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﻋﻨﺎﻭﻳﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺧﻠﻘﺖ ﻟﻨﺎ ﻣﻔﻬﻮﻡ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ‬‫)‪ (Logical Address‬ﺣﻴﺚ ﻟﻜﻲ ﻧﺼﻞ ﺍﱃ ﺃﻱ ﻣﻜﺎﻥ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻧﻪ ﳚﺐ ﲢﺪﻳﺪ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﻭﺍﻟﻌﻨﻮﺍﻥ ﺑﺪﺍﺧﻞ‬‫ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻭﺫﻟﻚ ﻋﻠﻰ ﺍﻟﺸﻜﻞ ‪ Segment:Offset‬ﺣﻴﺚ ﺍﳉﺰء ﺍﻷﻭﻝ ﳛﺪﺩ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﻭﺍﳉﺰء ﺍﻟﺜﺎﱐ ﳛﺪﺩ‬‫ﺍﻟﻌﻨﻮﺍﻥ ﺑﺪﺍﺧﻞ ﺍﳌﻘﻄﻊ. ﻣﻬﻤﺔ ﺍﳌﻌﺎﰿ ﺣﺎﻟﻴﺎ ﻫﻲ ﲢﻮﻳﻞ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ ﺍﱃ ﻋﻨﻮﺍﻥ ﻓﻴﺰﻳﺎﺋﻲ ﺃﻭ ﺣﻘﻴﻘﻲ ﻟﻜﻲ ﻳﻘﻮﻡ‬‫ﺑﺎﺭﺳﺎﻟﻪ ﻋﱪ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ، ﻭ ﻃﺮﻳﻘﺔ ﺍﻟﺘﺤﻮﻳﻞ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﺃﻥ ﺍﻹﺯﺍﺣﺔ )‪ (Offset‬ﻳﺘﻢ‬‫ﲨﻌﻬﺎ ﺍﱃ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ )‪ ٥ (Segment‬ﻭﻟﻜﻦ ﺑﻌﺪ ﺃﻥ ﻳﺘﻢ ﺿﺮ‪‬ﺎ ﰲ ﺍﻟﻌﺪﺩ ٦١ ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺃﻱ ﻣﻘﻄﻊ‬ ‫ﻳﺒﺪﺃ ﺑﻌﺪ ٦١ ﺑﺎﻳﺖ ﻣﻦ ﺍﳌﻘﻄﻊ ﺍﻟﺴﺎﺑﻖ ﻟﻪ . ﻭﺍﻟﺘﺤﻮﻳﻞ ﻳﺘﻢ ﻛﺎﻷﰐ :‬‫‪physical address = segment ∗ 0x10 + of f set‬‬‫ﻓﻤﺜﻼ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ 0000‪ 0x07c0:0x‬ﻳﺘﻢ ﲢﻮﻳﻠﻪ ﻭﺫﻟﻚ ﺑﻀﺮﺏ ﺍﻟﻌﻨﻮﺍﻥ 0‪ 0x07c‬ﺑﺎﻟﻌﺪﺩ ٦١ )ﺃﻭ ﺍﻟﻌﺪﺩ 01‪0x‬‬‫ﺑﺎﻟﻨﻈﺎﻡ ﺍﻟﺴﺎﺩﺱ ﻋﺸﺮ( ﻟﻴﺼﺒﺢ ﻫﻜﺬﺍ 00‪ ،0x07c‬ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺘﻢ ﲨﻌﻪ ﺍﱃ ﺍﻝ ‪ Offset‬ﻟﻴﺨﺮﺝ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ‬ ‫00‪.0x07c‬‬ ‫ﻣﺸﻜﻠﺔ ﺗﺪﺍﺧﻞ ﺍﳌﻘﺎﻃﻊ‬‫ﺫﻛﺮﻧﺎ ﰲ ﺍﻟﻔﻘﺮﺓ ﺍﻟﺴﺎﺑﻘﺔ ﺃﻥ ﺃﻱ ﻣﻘﻄﻊ ﻳﺒﺪﺃ ﻣﺒﺎﺷﺮﺓ ﺑﻌﺪ ٦١ ﺑﺎﻳﺖ ﻣﻦ ﺍﳌﻘﻄﻊ ﺍﻟﺴﺎﺑﻖ ﻟﻪ ، ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻥ ﺍﳌﻘﺎﻃﻊ‬‫ﻣﺘﺪﺍﺧﻠﺔ ﺣﻴﺚ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﻟﻌﻨﻮﺍﻥ ﻓﻴﺰﻳﺎﺋﻲ ﻣﻌﲔ ﺑﺄﻛﺜﺮ ﻣﻦ ﻃﺮﻳﻘﺔ ﳐﺘﻠﻔﺔ. ﻣﺜﻼﹰ ﰲ ﻣﺜﺎﻟﻨﺎ ﺍﻟﺴﺎﺑﻖ ﺍﺳﺘﺨﺪﻣﻨﺎ‬‫ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ 0000‪ 0x07c0:0x‬ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﺍﳌﻨﻄﻘﺔ ﺍﻟﺬﺍﻛﺮﻳﺔ 00‪ ، 0x07c‬ﻭﳝﻜﻦ ﺃﻥ ﻧﺴﺘﺒﺪﻝ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ‬‫ﺍﻟﺴﺎﺑﻖ ﺑﺎﻟﻌﻨﻮﺍﻥ 00‪ 0x0000:0x7c‬ﻭﺑﻌﺪ ﺍﺟﺮﺍء ﺍﻟﺘﺤﻮﻳﻞ ﺳﻨﺤﺼﻞ ﻋﻠﻰ ﻧﻔﺲ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ 00‪ .0x07c‬ﻭﰲ‬‫ﺍﳊﻘﻴﻘﺔ ﻫﻨﺎﻙ ٦٩٠٤ ﻃﺮﻳﻘﺔ ﳐﺘﻠﻔﺔ ﻟﻠﻮﺻﻞ ﻟﻌﻨﻮﺍﻥ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ٦ ﻭﺍﻟﺸﻜﻞ ٢.٤ ﻳﻮﺿﺢ ﻟﻨﺎ ﺗﺪﺍﺧﻞ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻊ.‬‫ﻫﺬﺍ ﺍﻟﺘﺪﺍﺧﻞ ‪ Overlapping‬ﲰﺢ ﻷﻱ ﺑﺮﻧﺎﻣﺞ ﻣﺎ ﺇﻣﻜﺎﻧﻴﺔ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺑﻴﺎﻧﺎﺕ ﺑﺮﻧﺎﻣﺞ ﺁﺧﺮ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻴﻬﺎ‬ ‫ﻭﻫﺬﺍ ﻣﺎ ﺟﻌﻞ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﺿﻌﻴﻒ ﻣﻦ ﻧﺎﺣﻴﺔ ﲪﺎﻳﺔ ﺃﺟﺰﺍء ﺍﻟﺬﺍﻛﺮﺓ.‬ ‫‪Protected Mode‬‬ ‫٢.٢.٤. ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬‫ﺑﻌﺪ ﺃﻥ ﰎ ﺍﻟﺘﻌﺮﻑ ﻋﻠﻰ ﻫﺬﻩ ﺍﳌﺸﺎﻛﻞ ﺳﺎﺭﻋﺖ ﺃﻧﺘﻞ ﺑﺎﺻﺪﺍﺭ ﺍﳌﻌﺎﰿ 68208 ﻭﺍﻟﺬﻱ ﻛﺎﻥ ﺃﻭﻝ ﻣﻌﺎﰿ ﻳﻌﻤﻞ ﰲ‬‫ﳕﻄﲔ )ﺍﳊﻘﻴﻘﻲ ﻭﺍﳌﺤﻤﻲ( . ﻫﺬﺍ ﺍﳌﻌﺎﰿ )ﻭﺍﳌﻌﺎﳉﺎﺕ ﺍﻟﱵ ﺗﻠﻴﻬﺎ( ﺣﻞ ﺃﻫﻢ ﻣﺸﻜﻠﺔ ﻭﻫﻲ ﲪﺎﻳﺔ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﻣﻦ ﺍﻟﻮﺻﻮﻝ ﺍﻟﻌﺸﻮﺍﺋﻲ ﻣﻦ ﻗﺒﻞ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﻭﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﻭﺻﻒ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺻﻼﺣﻴﺎﺕ ﺍﻟﻮﺻﻮﻝ‬‫ﺍﻟﻴﻬﺎ ﰲ ﺟﺪﺍﻭﻝ ﺗﺴﻤﻰ ﺟﺪﺍﻭﻝ ﺍﻟﻮﺻﻔﺎﺕ )‪ .(Descriptor Table‬ﺍﳌﻌﺎﰿ 68308 ﻫﻮ ﺃﻭﻝ ﻣﻌﺎﰿ ٢٣ ﺑﺖ‬‫ﻭﻳﺴﺘﺨﺪﻡ ﻣﺴﺠﻼﺕ ﲝﺠﻢ ٢٣ ﻳﺖ ﻭﺣﺠﻢ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺃﻳﻀﺎ ﺑﻨﻔﺲ ﺍﳊﺠﻢ ﳑﺎ ﲰﺢ ﺑﺈﻣﻜﺎﻧﻴﺔ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ‬‫ﺫﺍﻛﺮﺓ ﲝﺠﻢ ٤ ﺟﻴﺠﺎﺑﺎﻳﺖ .ﻛﺬﻟﻚ ﰎ ﺍﺿﺎﻓﺔ ﺩﻋﻢ ﻟﻠﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ ﻭﻣﻔﻬﻮﻡ ﺍﻟﺼﻔﺤﺎﺕ )‪ (Paging‬ﻭﺩﻋﻢ ﺗﻌﺪﺩ‬ ‫٥ﲝﻴﺚ ﻧﻌﺘﱪ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﻫﻮ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ )‪ (Base Address‬ﻟﻌﻨﺎﻭﻳﻦ ﺍﻟﻘﻴﻢ )‪.(Offset‬‬ ‫٦ﺍﻧﻈﺮ ﺍﱃ ﻣﻘﺎﻟﺔ ﺍﻟﻜﺎﺗﺐ ‪ Daniel B. Sedory‬ﻋﻠﻰ ﺍﻟﺮﺍﺑﻂ /‪http://mirror.href.com/thestarman/asm/debug‬‬ ‫‪.Segments.html‬‬‫٣٢‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬ ‫ﺷﻜﻞ ٢.٤.: ﺗﺪﺍﺧﻞ ﺍﳌﻘﺎﻃﻊ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ‬‫ﺍﳌﻬﺎﻡ. ﻭﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﻣﻌﺎﳉﺎﺕ ٢٣ ﺑﺖ ﺑﺎﻋﺘﺒﺎﺭﻫﺎ ﺃﺣﺪ ﺍﻷﻛﺜﺮ ﺍﻧﺘﺸﺎﺭﴽ ﺣﱴ ﻭﻗﺘﻨﺎ ﻫﺬﺍ‬‫،ﻭ ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﻇﻬﻮﺭ ﻣﻌﺎﳉﺎﺕ ٤٦ ﺑﺖ ﺇﻻ ﺍﻥ ﺍﻟﺪﺭﺍﺳﺔ ﺣﻮﻝ ﻣﻌﺎﳉﺎﺕ ٢٣ ﺑﺖ ﺗﻌﺘﱪ ﻫﻲ ﺍﻷﺳﺎﺱ ﻧﻈﺮﴽ‬ ‫ﻻﻥ ﺍﳌﻌﺎﳉﺎﺕ ﺍﳊﺪﻳﺜﺔ ﻣﺎ ﻫﻲ ﺍﻻ ﺗﻄﻮﻳﺮ ﻭﺍﺿﺎﻓﺎﺕ ﻟﻠﻤﻔﺎﻫﻴﻢ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﻌﺎﳉﺎﺕ ﺍﻟﺴﺎﺑﻘﺔ.‬ ‫‪CPU Rings‬‬ ‫ﺣﻠﻘﺎﺕ ﺍﳌﻌﺎﰿ‬‫ﻋﻨﺪﻣﺎ ﻳﻌﻤﻞ ﺍﳌﻌﺎﰿ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﺎﻥ ﻫﺬﺍ ﻳﻀﻤﻦ ﲪﺎﻳﺔ ﻟﻠﺬﺍﻛﺮﺓ ﻣﻦ ﺑﺮﳎﻴﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ ، ﻭﻫﺬﺍ ﺑﺴﺒﺐ‬‫ﺗﻮﺻﻴﻒ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺻﻼﺣﻴﺎﺕ ﺍﻟﻮﺻﻮﻝ ﳍﺎ ﰲ ﺟﺪﻭﻝ ﻳﺴﺘﺨﺪﻣﻪ ﺍﳌﻌﺎﰿ ﻟﻌﻨﻮﻧﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻫﻮ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ.‬‫ﻧﻈﺎﻡ ﺍﻟﺼﻼﺣﻴﺎﺕ ﺍﻟﺬﻱ ﰎ ﺍﺩﺧﺎﻟﻪ ﺍﱃ ﺍﳌﻌﺎﰿ ﻋﻨﺪ ﻋﻤﻠﻪ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻳﺴﻤﻰ ﲝﻠﻘﺎﺕ ﺍﳌﻌﺎﰿ )‪،(CPU Rings‬‬‫ﻫﺬﻩ ﺍﳊﻠﻘﺎﺕ ﲢﺪﺩ ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ﺍﳌﻄﻠﻮﺏ ﻟﻜﻲ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ ﰲ ﺗﻘﺮﻳﺮ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺗﻨﻔﻴﺬ ﺃﻣﺮ ﻣﺎ ﳛﺘﺎﺝ ﺍﱃ‬‫ﺻﻼﺣﻴﺔ ﺃﻋﻠﻰ ﺃﻡ ﻻ، ﻭﻛﺬﻟﻚ ﻟﻜﻲ ﻳﻘﺮﺭ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﻋﻨﻮﺍﻥ ﻣﻌﲔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻣﺴﻤﻮ ‪ ‬ﺑﺎﺳﺘﺨﺪﺍﻡ‬ ‫ﺡ‬‫ﺻﻼﺣﻴﺔ ﻣﻌﻴﻨﺔ ﺃﻡ ﻻ.ﻭﺗﻮﺟﺪ ﺃﺭﺑﻊ ﺣﻠﻘﺎﺕ ﻟﻠﻤﻌﺎﰿ ﺗﺒﺪﺃ ﻣﻦ ﺍﳊﻠﻘﺔ ﺻﻔﺮ )0‪ (Ring‬ﻭﺗﻨﺘﻬﻲ ﺑﺎﳊﻠﻘﺔ ٣ )3‪.(Ring‬‬‫ﺍﳊﻠﻘﺔ ﺻﻔﺮ ﺗﺴﻤﻰ ﳕﻂ ﺍﻟﻨﻮﺍﺓ )‪ (Kernel Mode‬ﺑﺴﺒﺐ ﺃﻥ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﻳﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ﻟﺪﻳﻪ ﺍﻟﺼﻼﺣﻴﺎﺕ‬‫ﺍﻟﻜﺎﻣﻠﺔ ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ ﺑﺎﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﻋﻨﻮﺍﻥ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺗﻨﻔﻴﺬ ﺃﻱ ﺗﻌﻠﻴﻤﻴﺔ ﺣﱴ ﻟﻮ ﺗﺴﺒﺒﺖ ﰲ ﺍﻳﻘﺎﻑ ﺍﻟﻨﻈﺎﻡ‬‫ﻋﻦ ﺍﻟﻌﻤﻞ )ﺍﳌﺴﺆﻭﻟﻴﺔ ﺗﻘﻊ ﻋﻠﻰ ﺍﻟﱪﻧﺎﻣﺞ( ﻟﺬﻟﻚ ﻏﺎﻟﺒﺎ ﺍﻟﱪﺍﻣﺞ ﺍﻟﱵ ﺗﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ﻫﻲ ﺍﻟﱪﺍﻣﺞ ﺍﻟﱵ ﺗﺘﺒﻊ‬‫ﻟﻨﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ. ﺃﻣﺎ ﺍﳊﻠﻘﺔ ٣ ﺗﺴﻤﻰ ﺑﻨﻤﻂ ﺍﳌﺴﺘﺨﺪﻡ )‪ (User Mode‬ﺣﻴﺚ ﺃﻥ ﺍﻟﱪﺍﻣﺞ ﺍﻟﱵ ﺗﻌﻤﻞ ﻋﻠﻴﻬﺎ ﻻ‬‫ﲤﻠﻚ ﺻﻼﺣﻴﺎﺕ ﻟﺘﻨﻔﻴﺬ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻷﻭﺍﻣﺮ )ﻣﺜﻞ ﺍﻻﻣﺮ ‪ cli‬ﻭﺍﻷﻣﺮ ‪ (hlt‬ﻭﻻ ﲤﻠﻚ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﻋﻨﻮﺍﻥ‬‫ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﲞﻼﻑ ﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻟﺘﺨﻴﻠﻴﺔ )‪ (Virtual Address Space‬ﺍﳋﺎﺻﺔ ﺑﺎﻟﱪﻧﺎﻣﺞ ﻧﻔﺴﻪ ﻭﻫﺬﺍ ﻣﺎ ﺭﻓﻊ‬‫ﺩﺭﺟﺔ ﲪﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﺍﱃ ﺃﻗﺼﻰ ﺣﺪ ﳑﻜﻦ ، ﻭﺍﻟﺸﻜﻞ ٢.٥ ﻳﻮﺿﺢ ﻫﺬﻩ ﺍﳊﻠﻘﺎﺕ ﻭﺻﻼﺣﻴﺎ‪‬ﺎ. ﻭﻋﻨﺪﻣﺎ ﻳﺒﺪﺃ‬‫ﺍﻟﻨﻈﺎﻡ ﺑﺎﻹﻗﻼﻉ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻜﻮﻥ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻭﻫﻮ ﳕﻂ ﻻ ﳛﻮﻱ ﻋﻠﻰ ﺣﻠﻘﺎﺕ ﺣﻴﺚ ﺃﻧﻪ ﳝﻜﻦ ﺗﻨﻔﻴﺬ ﻛﻞ‬‫ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﻋﻨﻮﺍﻥ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ، ﻭﻋﻨﺪ ﺍﻟﺘﺤﻮﻳﻞ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ )‪ (PMode‬ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻜﻮﻥ‬ ‫٤٢‬
    • ‫٢.٢. ﺍﳌﻌﺎﰿ‬‫ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ )‪ ، (Kernel Mode‬ﻭﻳﺘﻢ ﲢﻮﻳﻞ ﺍﳊﻠﻘﺔ ﺍﱃ ﺣﻠﻘﺔ ﻣﻌﻴﻨﺔ ﺗﻠﻘﺎﺋﻴﺎ ﻋﻨﺪ ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﻋﻨﻮﺍﻥ ﰲ‬ ‫ﺍﻟﺬﺍﻛﺮﺓ ﻣﻮﺻﻮﻑ ﰲ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺑﺄﻧﻪ ﻳﻌﻤﻞ ﺑﺘﻠﻚ ﺍﳊﻠﻘﺔ.‬ ‫ﺷﻜﻞ ٢.٥.: ﺣﻠﻘﺎﺕ ﺍﳌﻌﺎﰿ‬ ‫68‪x‬‬ ‫٢.٢.٥. ﻣﻌﻤﺎﺭﻳﺔ ﻣﻌﺎﳉﺎﺕ‬‫ﺃﻱ ﻣﻌﺎﰿ ﻳﺘﻌﺮﻑ ﻋﻠﻰ ﳎﻤﻮﻋﺔ ﻣﻦ ﺍﻷﻭﺍﻣﺮ ﺗﺴﻤﻰ ‪ Instruc on Set‬ﺑﻌﻀﴼ ﻣﻨﻬﺎ ﺗﺘﻄﻠﺐ ﺻﻼﺣﻴﺔ ﻣﻌﻴﻨﺔ‬‫)ﺍﳊﻠﻘﺔ ﺻﻔﺮ( ﻟﻜﻲ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ ﺑﺘﻨﻔﻴﺬﻫﺎ )ﺍﻧﻈﺮ ﺍﳉﺪﻭﻝ ٢.٣ ﳌﻌﺮﻓﺔ ﻫﺬﻩ ﺍﻷﻭﺍﻣﺮ( ﻭﺇﻻ ﻓﺎﻥ ﻫﺬﺍ ﺳﻴﺘﺴﺒﺐ‬‫ﰲ ﺣﺪﻭﺙ ﺧﻄﺄ ﻣﻦ ﺍﳌﻌﺎﰿ ﻳﺴﻤﻰ ﺍﳋﻄﺄ ﺍﻟﻌﺎﻡ )‪ (General Protec on Fault‬ﻭﺍﻟﺬﻱ ﺍﻥ ﱂ ﺗﺘﻮﻓﺮ ﺩﺍﻟﺔ ﺗﺘﻌﺎﻣﻞ‬ ‫ﻣﻌﻪ )‪ (Excep on Handler‬ﻓﺎﻥ ﻫﺬﺍ ﻳﺆﺩﻱ ﺍﱃ ﺗﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ.‬‫ﻭﲢﻮﻱ ﻣﻌﺎﳉﺎﺕ 68‪ x‬ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﻣﻨﻬﺎ ﻣﺎ ﻳﺴﺘﺨﺪﻡ ﻟﻸﻏﺮﺍﺽ ﺍﻟﻌﺎﻣﺔ )‪ (General Registers‬ﻭﻣﻨﻬﺎ ﻣﺎ‬‫ﻳﺴﺘﺨﺪﻡ ﳊﻔﻆ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻭﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻊ )‪ (Segments Registers‬ﻭﺗﻮﺟﺪ ﺃﻳﻀﺎ ﻣﺴﺠﻼﺕ ﻻ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ‬‫ﺇﻻ ﰲ ﺑﺮﺍﻣﺞ ﺍﳊﻠﻘﺔ ﺻﻔﺮ )ﺃﻱ ﺍﻟﻨﻮﺍﺓ( ﺣﻴﺚ ﺃﻥ ﺍﻟﺘﻐﻴﲑ ﻓﻴﻬﺎ ﻳﺆﺛﺮ ﻋﻠﻰ ﻋﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﺃﺧﲑﺍ ﻫﻨﺎﻙ ﳎﻤﻮﻋﺔ ﻣﻦ‬ ‫ﺍﳌﺴﺠﻼﺕ ﺍﻟﺪﺍﺧﻠﻴﺔ ﻟﻠﻤﻌﺎﰿ ﻭﺍﻟﱵ ﻻ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﳍﺎ ﺑﺮﳎﻴﴼ. ﻭﺍﻟﻘﺎﺋﻤﺔ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ :‬‫• ﻣﺴﺠﻼﺕ ﻋﺎﻣﺔ : ‪RAX (EAX(AX/AH/AL)), RBX (EBX(BX/BH/BL)), RCX (ECX(CX/CH/CL)), RDX‬‬ ‫))‪.(EDX(DX/DH/DL‬‬ ‫ﻣﺴﺠﻼﺕ ﻋﻨﺎﻭﻳﻦ:‬ ‫•‬ ‫– ﻣﺴﺠﻼﺕ ﻣﻘﺎﻃﻊ:‪. CS,SS,ES,DS,FS,GS‬‬‫– ﻣﺴﺠﻼﺕ ﺇﺯﺍﺣﺔ: ‪RSI (ESI (SI)), RDI (EDI (DI)), RBP (EBP (BP)). RSP (ESP (SP)), RIP (EIP‬‬ ‫))‪.(IP‬‬ ‫ﻣﺴﺠﻞ ﺍﻷﻋﻼﻡ: ))‪.RFLAGS (EFLAGS (FLAGS‬‬ ‫•‬ ‫ﻣﺴﺠﻼﺕ ﺍﻟﺘﻨﻘﻴﺢ: 7‪.DR0, DR1, DR2, DR3, DR4, DR5, DR6, DR‬‬ ‫•‬‫٥٢‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬ ‫ﺟﺪﻭﻝ ٢.٣.: ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﺗﺘﻄﻠﺐ ﺻﻼﺣﻴﺔ ﺍﳊﻠﻘﺔ ﺻﻔﺮ‬ ‫ﺍﻷﻣﺮ ﺍﻟﻮﺻﻒ‬ ‫‪ LGDT‬ﲢﻤﻴﻞ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ﺍﱃ ﺍﳌﺴﺠﻞ ‪GDTR‬‬ ‫‪ LLDT‬ﲢﻤﻴﻞ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﳋﺎﺹ ﺍﱃ ﺍﳌﺴﺠﻞ ‪LDTR‬‬ ‫‪ LTR‬ﲢﻤﻴﻞ ﻣﺴﺠﻞ ﺍﳌﻬﺎﻡ‬ ‫‪ MOV cr x‬ﻧﻘﻞ ﺑﻴﺎﻧﺎﺕ ﺍﱃ ﻣﺴﺠﻞ ﲢﻜﻢ‬ ‫‪ LMSW‬ﲢﻤﻴﻞ ‪new Machine Status WORD‬‬ ‫‪ MOV dr x‬ﻧﻘﻞ ﺑﻴﺎﻧﺎﺕ ﺍﱃ ﻣﺴﺠﻞ ﺗﻨﻘﻴﺢ‬ ‫‪ CLTS‬ﺗﺼﻔﲑ ‪ Task Switch Flag‬ﰲ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻷﻭﻝ‬ ‫‪Invalidate Cache without writeback‬‬ ‫‪INVD‬‬ ‫‪Invalidate TLB Entry‬‬ ‫‪INVLPG‬‬ ‫‪Invalidate Cache with writeback‬‬ ‫‪WBINVD‬‬ ‫ﺇﻳﻘﺎﻑ ﻋﻤﻞ ﺍﳌﻌﺎﰿ‬ ‫‪HLT‬‬ ‫‪MSR‬‬ ‫ﻗﺮﺍءﺓ ﻣﺴﺠﻞ‬ ‫‪RDMSR‬‬ ‫ﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ﻣﺴﺠﻞ ‪MSR‬‬ ‫‪WRMSR‬‬ ‫ﻗﺮﺍءﺓ ‪Performance Monitoring Counter‬‬ ‫‪RDPMC‬‬ ‫ﻗﺮﺍءﺓ ‪me Stamp Counter‬‬ ‫‪RDTSC‬‬ ‫ﻣﺴﺠﻼﺕ ﺍﻟﺘﺤﻜﻢ: 8‪.CR0, CR1, CR2, CR3, CR4, CR‬‬ ‫•‬ ‫ﻣﺴﺠﻼﺕ ﺍﻹﺧﺘﺒﺎﺭ: 7‪.TR1, TR2, TR3, TR4, TR5, TR6, TR‬‬ ‫•‬‫• ﻣﺴﺠﻼﺕ ﺃﺧﺮﻯ: ,2‪mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, xmm0, xmm1, xmm‬‬ ‫‪.xmm3, xmm4, xmm5, xmm6, xmm7, GDTR, LDTR, IDTR, MSR, and TR‬‬ ‫‪General Purpose Registers‬‬ ‫ﺍﳌﺴﺠﻼﺕ ﺍﻟﻌﺎﻣﺔ‬‫ﰲ ﺍﳌﻌﺎﳉﺎﺕ ٢٣ ﺑﺖ ﻳﻮﺟﺪ ٤ ﺃﺭﺑﻊ ﻣﺴﺠﻼﺕ ﻋﺎﻣﺔ ﻃﻮﻝ ﻛﻞ ﻣﻨﻬﺎ ﻫﻮ ٢٣ ﺑﺖ )٤ ﺑﺎﻳﺖ( ﻭﺗﻘﺴﻢ ﺃﻱ ﻣﻦ‬‫ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﺍﱃ ﺟﺰﺋﲔ: ﺍﳉﺰء ﺍﻷﻋﻠﻰ )‪ (High Order Word‬ﻭﻫﻮ ﺑﻄﻮﻝ ٦١ ﺑﺖ ﻭﺍﳉﺰء ﺍﻷﺩﱏ )‪Low‬‬‫‪ (Order Word‬ﻭﻫﻮ ﺃﻳﻀﺎ ﺑﻄﻮﻝ ٦١ ﺑﺖ ، ﻛﺬﻟﻚ ‪‬ﻘﺴﻢ ﺍﳉﺰء ﺍﻷﺩﱏ ﺍﱃ ﺟﺰﺋﲔ: ﺍﳉﺰء ﺍﻷﻋﻠﻰ )‪High‬‬ ‫ﻳ‬‫‪ (Order Byte‬ﻭﻫﻮ ﺑﻄﻮﻝ ٨ ﺑﺖ ﻭﺍﳉﺰء ﺍﻷﺩﱏ )‪ (Low Order Byte‬ﻭﻫﻮ ﺃﻳﻀﺎ ﺑﻄﻮﻝ ٨ ﺑﺖ. ﻋﻠﻰ ﺳﺒﻴﻞ‬‫ﺍﳌﺜﺎﻝ ﻣﺴﺠﻞ ‪ EAX‬ﺣﻴﺚ ﻳﻘﺴﻢ ﺍﱃ ﺟﺰء ﺃﻋﻠﻰ )ﻻ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﺍﻟﻴﻪ ﺑﺸﻜﻞ ﻣﺒﺎﺷﺮ( ﻭﺟﺰء ﺃﺳﻔﻞ ﻭﻫﻮ ‪AX‬‬‫ﺍﻟﺬﻱ ‪‬ﻘﺴﻢ ﺃﻳﻀﺎ ﺍﱃ ﻗﺴﻤﲔ ‪ AH‬ﻭ ‪ .AL‬ﻛﻞ ﻣﺴﺠﻞ ﻣﻦ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﺍﻟﻌﺎﻣﺔ ﻳﺴﺘﺨﺪﻡ ﻷﻱ ﺷﻲء ﻟﻜﻦ‬ ‫ﻳ‬ ‫ﻫﻨﺎﻙ ﺑﻌﺾ ﺍﻹﺳﺘﺨﺪﺍﻣﺎﺕ ﺍﻟﻐﺎﻟﺒﺔ ﻟﻜ ﹲ ﻣﻨﻬﻢ ﺗﻮﺿﺤﻬﺎ ﺍﻟﻘﺎﺋﻤﺔ ﺍﻟﺘﺎﻟﻴﺔ.‬ ‫ﻞ‬ ‫ﺍﳌﺴﺠﻞ ‪ :EAX‬ﻳﺴﺘﺨﺪﻡ ﻟﻨﻘﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﻌﻤﻠﻴﺎﺕ ﺍﳊﺴﺎﺑﻴﺔ.‬ ‫•‬ ‫٦٢‬
    • ‫٢.٢. ﺍﳌﻌﺎﰿ‬‫ﺍﳌﺴﺠﻞ ‪ :EBX‬ﻳﺴﺘﺨﺪﻡ ﰲ ﺍﻟﻮﺻﻮﻝ ﻟﻠﺬﺍﻛﺮﺓ ﺑﺸﻜﻞ ﻏﲑ ﻣﺒﺎﺷﺮ ﻭﺫﻟﻚ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻣﺴﺠﻞ ﺁﺧﺮ ﻳﻌﻤﻞ‬ ‫•‬ ‫ﻛﻌﻨﻮﺍﻥ ﺭﺋﻴﺴﻲ ‪.Base Address‬‬ ‫ﺍﳌﺴﺠﻞ ‪ :ECX‬ﻳﺴﺘﺨﺪﻡ ﰲ ﻋﻤﻠﻴﺎﺕ ﺍﻟﺘﻜﺮﺍﺭ ﻭﺍﻟﻌﺪ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :EDX‬ﻳﺴﺘﺨﺪﻡ ﰲ ﲣﺰﻳﻦ ﺍﻟﺒﻴﺎﻧﺎﺕ.‬ ‫•‬ ‫‪Segment Registers‬‬ ‫ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ‬‫ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﺗﺴﺘﺨﺪﻡ ﻟﺘﺨﺰﻳﻦ ﺃﺭﻗﺎﻡ ﻭﻋﻨﺎﻭﻳﻦ ﺍﳌﻘﺎﻃﻊ )‪ (Segments‬ﻭﺗﻮﺟﺪ ٦ ﻣﺴﺠﻼﺕ ﻣﻘﺎﻃﻊ ﺗﺴﺘﺨﺪﻡ‬ ‫ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻛﻤﺎ ﻳﻠﻲ:‬ ‫ﺍﳌﺴﺠﻞ ‪ :CS‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﺸﻔﺮﺓ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :DS‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :SS‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﳌﻜﺪﺱ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :ES‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :FS‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﻣﻘﻄﻊ ﺑﻌﻴﺪ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :GS‬ﻳﺴﺘﺨﺪﻡ ﻟﻸﻏﺮﺍﺽ ﺍﻟﻌﺎﻣﺔ.‬ ‫•‬‫ﺃﻣﺎ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ )‪ (PMode‬ﻓﺈﻥ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﻻ ﺗﺸﲑ ﺍﱃ ﻣﻘﺎﻃﻊ ﺍﻟﱪﺍﻣﺞ ﻭﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺇﳕﺎ ﺗﺸﲑ ﺍﱃ‬‫ﻭﺍﺻﻔﺎﺕ ﻣﻌﻴﻨﺔ ﰲ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ، ﻫﺬﻩ ﺍﻟﻮﺍﺻﻔﺎﺕ ﲢﺪﺩ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ﻭﻧﻮﻉ ﺍﳌﻘﻄﻊ )ﳛﻮﻱ‬‫ﺷﻔﺮﺍﺕ ﺃﻡ ﺑﻴﺎﻧﺎﺕ ( ﻭﲢﺪﺩ ﺻﻼﺣﻴﺔ ﺍﻟﺘﻨﻔﻴﺬ ﻭﺻﻼﺣﻴﺔ ﻭﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻓﻴﻬﺎ - ﻛﻤﺎ ﺳﻨﺮﻯ ﺫﻟﻚ ﰲ ﺍﻟﻔﺼﻞ‬ ‫ﺍﻟﺮﺍﺑﻊ ﺑﺈﺫﻥ ﺍﷲ-.‬ ‫‪Offset Registers‬‬ ‫ﻣﺴﺠﻼﺕ ﺍﻹﺯﺍﺣﺔ‬‫ﲜﺎﻧﺐ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﻓﺈﻥ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻳﺘﻄﻠﺐ ﻋﻨﻮﺍﻥ ﺍﻹﺯﺍﺣﺔ ﺑﺪﺍﺧﻞ ﺍﳌﻘﻄﻊ ،‬‫ﻭﺗﻮﺟﺪ ٤ ﻣﺴﺠﻼﺕ ﺇﺯﺍﺣﺔ ﰲ ﻣﻌﺎﳉﺎﺕ 68‪ x‬ﺣﺠﻢ ﻛﻞ ﻣﻨﻬﺎ ﻫﻮ ٢٣ ﺑﺖ ﰲ ﺍﻷﻧﻈﻤﺔ ٢٣ ﺑﺖ ﻭ ٦١ ﺑﺖ‬ ‫ﰲ ﺃﻧﻈﻤﺔ ٦١ ﺑﺖ. ﻭﺍﻟﻘﺎﺋﻤﺔ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ:‬ ‫ﺍﳌﺴﺠﻞ ‪ :SI‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻹﺯﺍﺣﺔ ﰲ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :DI‬ﻧﻔﺲ ﺍﻟﻮﻇﻴﻔﺔ ﺍﻟﺴﺎﺑﻘﺔ.‬ ‫•‬‫ﺍﳌﺴﺠﻞ ‪ :BP‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻹﺯﺍﺣﺔ ﺑﺪﺍﺧﻞ ﻣﻘﻄﻊ ﺍﳌﻜﺪﺱ ﻭﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻸﺷﺎﺭﺓ ﻋﻠﻰ ﺃﻱ ﻋﻨﻮﺍﻥ ﰲ‬ ‫•‬ ‫ﺃﻱ ﻣﻘﻄﻊ ﺁﺧﺮ.‬‫٧٢‬
    • ‫68‪x‬‬ ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬ ‫ﺍﳌﺴﺠﻞ ‪ :SP‬ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻹﺯﺍﺣﺔ ﺑﺪﺍﺧﻞ ﻣﻘﻄﻊ ﺍﳌﻜﺪﺱ.‬ ‫•‬ ‫‪Instruc on Pointer‬‬ ‫ﻣﺆﺷﺮ ﺍﻟﺘﻌﻠﻴﻤﺔ‬‫ﻫﺬﺍ ﺍﳌﺴﺠﻞ )‪ (IP‬ﳝﺜﻞ ﺇﺯﺍﺣﺔ ﺑﺪﺍﺧﻞ ﻣﻘﻄﻊ ﺍﻟﺸﻔﺮﺓ )‪ (CS‬ﻭﻫﻮ ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻟﺘﻌﻠﻴﻤﺔ ﺍﻟﺘﺎﻟﻴﺔ ﺍﻟﱵ ﺳﻴﻘﻮﻡ ﺍﳌﻌﺎﰿ‬‫ﺑﺘﻨﻔﻴﺬﻫﺎ ، ﻭﺍﻟﻌﻨﻮﺍﻥ ‪ CS:IP‬ﳝﺜﻞ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﻟﻠﺘﻌﻠﻴﻤﺔ ﺍﻟﺘﺎﻟﻴﺔ. ﻫﺬﺍ ﺍﳌﺴﺠﻞ ﻫﻮ ﺑﻄﻮﻝ ٢٣ ﺑﺖ )‪ (EIP‬ﰲ‬‫ﺃﻧﻈﻤﺔ ٢٣ ﺑﺖ ﻭ ٦١ ﺑﺖ )‪ (IP‬ﰲ ﺃﻧﻈﻤﺔ ٦١ ﺑﺖ، ﻭﻫﻮ ﻣﺴﺠﻞ ﻻ ﳝﻜﻦ ﺗﻐﻴﲑ ﳏﺘﻮﺍﻩ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺗﻌﻠﻴﻤﺔ ﺍﳌﻌﺎﰿ‬ ‫‪ MOV‬ﻭﺇﳕﺎ ﻳﺘﻢ ﺗﻐﻴﲑ ﳏﺘﻮﺍﻩ ﻋﻦ ﺍﻟﻘﻔﺰ ﺍﱃ ﻣﻜﺎﻥ ﺁﺧﺮ ﻟﻠﺘﻨﻔﻴﺬ.‬ ‫‪FLAGS Register‬‬ ‫ﻣﺴﺠﻞ ﺍﻷﻋﻼﻡ‬‫ﻣﺴﺠﻞ ﺍﻷﻋﻼﻡ ﻫﻮ ﻣﺴﺠﻞ ﲝﺠﻢ ٢٣ ﺑﺖ )‪ (EFLAGS‬ﰲ ﺃﻧﻈﻤﺔ ٢٣ ﺑﺖ ﻭ ﲝﺠﻢ ٦١ ﺑﺖ )‪ (FLAGS‬ﰲ‬‫ﺃﻧﻈﻤﺔ ٦١ ﺑﺖ ، ﻭﻫﺬﺍ ﺍﳌﺴﺠﻞ ﻫﻮ ﻋﺒﺎﺭﺓ ﻋﻦ ﺑﺘﺎﺕ )ﺑﺎﳊﺠﻢ ﺍﻟﺴﺎﺑﻖ ﺫﻛﺮﻩ( ﻛﻞ ﺑﺖ ﻟﺪﻳﻪ ﻭﻇﻴﻔﻪ ﳏﺪﺩﻩ ،‬‫ﻭﻳﻨﻘﺴﻢ ﺑﺸﻜﻞ ﻋﺎﻡ ﺍﱃ ﺑﺘﺎﺕ ﺣﺎﻟﺔ )‪ (Status‬ﲝﻴﺚ ﺗﻌﻜﺲ ﺣﺎﻟﺔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ ﺑﺘﻨﻔﻴﺬﻫﺎ ﻭ ﺑﺘﺎﺕ‬‫ﲢﻜﻢ )‪ (Control‬ﲝﻴﺚ ﺗﺘﺤﻜﻢ ﰲ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ ﻭ ﺑﺘﺎﺕ ﻟﻠﻨﻈﺎﻡ )‪ .(System‬ﻭﺍﳉﺪﻭﻝ ٢.٤ ﻳﻮﺿﺢ ﻭﻇﻴﻔﺔ‬ ‫ﻛﻞ ﺑﺖ ﰲ ﻫﺬﺍ ﺍﳌﺴﺠﻞ.‬‫ﻭﳛﺪﺩ ﺍﻟﺒﺘﲔ ‪ IOPL‬ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ﺍﳌﻄﻠﻮﺏ ﻟﺘﻨﻔﻴﺬ ﳎﻤﻮﻋﺔ ﻣﻦ ﺍﻷﻭﺍﻣﺮ )ﻣﺜﻞ ﺍﻷﻭﺍﻣﺮ ‪ (CLI,STI,IN,OUT‬ﺣﻴﺚ‬‫ﻟﻦ ﻳﺘﻢ ﺗﻨﻔﻴﺬ ﻣﺜﻞ ﻫﺬﻩ ﺍﻟﺘﻌﻠﻴﻤﺎﺕ ﺇﻻ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ﺍﳊﺎﱄ ‪ Current Priviledge Level‬ﺃﻋﻠﻰ‬‫ﻣﻦ ﺃﻭ ﻣﺴﺎﻭﻳﴼ ﻟﻠﻘﻴﻤﺔ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﺍﻟﺒﺘﲔ ‪ ، ٧ IOPL‬ﻭﻏﺎﻟﺒﴼ ﻣﺎ ﺗﻜﻮﻥ ﺍﻟﻘﻴﻤﺔ ﻫﻲ ﺻﻔﺮ ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﺍﻟﺘﻌﻠﻴﻤﺎﺕ‬ ‫ﺍﻟﺴﺎﺑﻘﺔ ﻻ ﻳﺘﻢ ﺗﻨﻔﻴﺬﻫﺎ ﺍﻻ ﻟﱪﺍﻣﺞ ﺍﻟﻨﻮﺍﺓ )0‪.(Ring‬‬ ‫‪Control Registers‬‬ ‫ﻣﺴﺠﻼﺕ ﺍﻟﺘﺤﻜﻢ‬‫ﺗﻮﺟﺪ ﰲ ﻣﻌﺎﳉﺎﺕ ٢٣ ﺑﺖ ﺳﺘﺔ ﻣﺴﺠﻼﺕ ﻟﻠﺘﺤﻜﻢ ﰲ ﺳﻠﻮﻙ ﻭﻋﻤﻞ ﺍﳌﻌﺎﰿ ﻭﻫﻲ ,4‪CR0, CR1, CR2,CR3, CR‬‬‫8‪ ، CR‬ﻭﻧﻈﺮﴽ ﳋﻄﻮﺭﺓ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﻓﺎﻥ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﻻ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﳍﺎ ﺇﻻ ﻋﻨﺪ ﺍﻟﻌﻤﻞ ﰲ ﳕﻂ ﺍﻟﻨﻮﺍﺓ‬‫)0‪ (Kernel Moder/Ring‬ﻭﻻ ‪‬ﻤﻜﻦ ﻟﱪﳎﻴﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﻭﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ. ﻭﰲ‬ ‫ﻳ‬‫ﺍﻟﻮﻗﺖ ﺍﳊﺎﱄ ﻳﻬﻤﻨﺎ ﻓﻘﻂ ﺃﻭﻝ ﻣﺴﺠﻞ ﲢﻜﻢ ﻭﻫﻮ 0‪ CR‬ﺣﻴﺚ ﻣﻦ ﺧﻼﻟﻪ ﳝﻜﻦ ﺃﻭ ﻧﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ ﲢﻮﻳﻞ ﳕﻂ ﺍﳌﻌﺎﰿ‬‫ﻣﻦ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ )‪ (PMode‬ﻭﻛﺬﻟﻚ ﳝﻜﻦ ﺃﻥ ﻧﻘﻮﻡ ﺑﺘﻔﻌﻴﻞ ﺧﺎﺻﻴﺔ ﺍﻟﺼﻔﺤﺎﺕ )‪(Paging‬‬ ‫، ﻭﺍﻟﺘﺮﻛﻴﺒﺔ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﳏﺘﻮﻳﺎﺕ ﻛﻞ ﺑﺖ ﰲ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ 0‪ CR‬ﻭﻫﻮ ﻣﺴﺠﻞ ﲝﺠﻢ ٢٣ ﺑﺖ.‬ ‫.‪• Bit 0 (PE) : Puts the system into protected mode‬‬ ‫.‪• Bit 1 (MP) : Monitor Coprocessor Flag This controls the opera on of the WAIT instruc on‬‬ ‫‪• Bit 2 (EM) : Emulate Flag. When set, coprocessor instruc ons will generate an excep on‬‬ ‫٧ﺃﻋﻠﻰ ﻣﺴﺘﻮﻯ ﲪﺎﻳﺔ ﻫﻮ ﺍﳊﻠﻘﺔ ﺻﻔﺮ )0‪ (Ring‬ﻭﻳﻠﻴﻬﺎ ﺍﳊﻠﻘﺔ ١ ﰒ ٢ ﻭ٣.‬ ‫٨٢‬
    • ‫٢.٢. ﺍﳌﻌﺎﰿ‬ EFLAGS ‫ﺟﺪﻭﻝ ٢.٤.: ﻣﺴﺠﻞ ﺍﻷﻋﻼﻡ‬ ‫ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﺳﻢ ﺍﻟﺒﺖ ﺍﻹﺳﺘﺨﺪﺍﻡ‬ Carry Flag - Status bit CF 0 ‫ﳏﺠﻮﺯﺓ‬ - 1 Parity Flag PF 2 ‫ﳏﺠﻮﺯﺓ‬ - 3 Adjust Flag - Status bit AF 4 ‫ﳏﺠﻮﺯﺓ‬ - 5 Zero Flag - Status bit ZF 6 Sign Flag - Status bit SF 7 Trap Flag - System Flag TF 9 Interrupt Enabled Flag - System Flag IF 9 Direc on Flag - Control Flag DF 10 Overflow Flag - Status bit OF 11 I/O Priviledge Level - Control Flag IOPL 12-13 Nested Task Flag - Control Flag NT 14 ‫ﳏﺠﻮﺯﺓ‬ - 15 Resume Flag (386+ Only) - Control Flag RF 16 v8086 Mode Flag (386+ Only) - Control Flag VM 17 Alignment Check (486SX+ Only) - Control Flag AC 18 Virtual Interrupt Flag (Pen um+ Only) - Control Flag VIF 19 Virtual Interrupt Pending (Pen um+ Only) - Control Flag VIP 20 Iden fica on (Pen um+ Only) - Control Flag ID 21 ‫ﳏﺠﻮﺯﺓ‬ - 22-31٢٩
    • x86 ‫٢. ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ‬• Bit 3 (TS) : Task Switched Flag This will be set when the processor switches to another task.• Bit 4 (ET) : ExtensionType Flag. This tells us what type of coprocesor is installed. – 0 - 80287 is installed – 1 - 80387 is installed.• Bit 5 (NE): Numeric Error – 0 - Enable standard error repor ng – 1 - Enable internal x87 FPU error repor ng• Bits 6-15 : Unused• Bit 16 (WP): Write Protect• Bit 17: Unused• Bit 18 (AM): Alignment Mask – 0 - Alignment Check Disable – 1 - Alignment Check Enabled (Also requires AC flag set in EFLAGS and ring 3)• Bits 19-28: Unused• Bit 29 (NW): Not Write-Through• Bit 30 (CD): Cache Disable• Bit 31 (PG) : Enables Memory Paging. – 0 - Disable – 1 - Enabled and use CR3 register ٣٠
    • ‫ﺍﻟﻘﺴﻢ ‪.II‬‬‫‪Boo ng‬‬ ‫ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﺃﺣﺪ ﺃﻫﻢ ﺍﻷﺳﺎﺳﻴﺎﺕ ﰲ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻫﻲ ﻛﺘﺎﺑﺔ ﳏﻤ ﹲ ﻟﻪ ، ﻫﺬﺍ ﺍﳌﺤﻤﻞ ﻳﻌﻤﻞ ﻋﻠﻰ ﻧﺴﺦ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﻦ‬ ‫ﻞ‬‫ﺃﺣﺪ ﺍﻷﻗﺮﺍﺹ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﰒ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ، ﻭﻫﻜﺬﺍ ﺗﻨﺘﻬﻲ ﺩﻭﺭﺓ ﻋﻤﻞ ﺍﳌﺤﻤﻞ ﻭﻳﺒﺪﺃ ﻧﻈﺎﻡ‬‫ﺍﻟﺘﺸﻐﻴﻞ ﻣﺘﻤﺜﻼ ﰲ ﺍﻟﻨﻮﺍﺓ ﺑﺎﻟﺒﺪء ﺑﺘﻨﻔﻴﺬ ﺍﻻﻭﺍﻣﺮ ﻭﺍﳌﻬﻤﺎﺕ ﻭﺗﻠﺒﻴﺔ ﺇﺣﺘﻴﺎﺟﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ. ﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﺳﻨﺪﺭﺱ‬‫ﻛﻴﻔﻴﺔ ﺑﺮﳎﺔ ﺍﳌﺤﻤﻞ ﻭﻣﺎﻫﻴﺘﻪ ﻭﺳﻴﺘﻢ ﺍﻻﻗﻼﻉ ﻣﻦ ﻗﺮﺹ ﻣﺮﻥ ﺑﻨﻈﺎﻡ 21‪ ، FAT‬ﻓﺎﻟﻐﺮﺽ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﻫﻮ ﺩﺭﺍﺳﺔ‬ ‫ﺃﺳﺎﺳﻴﺎﺕ ﺍﳌﺤﻤﻞ ﻭﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﻧﻮﺍﺓ ﻣﺒﺴﻄﺔ .‬ ‫٣.١. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ‬‫ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ )‪ (Boot-Strapping‬ﻫﻲ ﺃﻭﻝ ﺧﻄﻮﺓ ﻳﻘﻮﻡ ‪‬ﺎ ﺍﳉﻬﺎﺯ ﻋﻨﺪ ﻭﺻﻠﻪ ﺑﺎﻟﻜﻬﺮﺑﺎء ﻟﺘﺤﻤﻴﻞ ﻧﻈﺎﻡ‬‫ﺍﻟﺘﺸﻐﻴﻞ، ﻭﺗﺒﺪﺃ ﻫﺬﻩ ﺍﻟﻌﻤﻠﻴﺔ ﻣﺒﺎﺷﺮﺓ ﻋﻨﺪ ﺍﻟﻀﻐﻂ ﻋﻠﻰ ﻣﻔﺘﺎﺡ ﺍﻟﺘﺸﻐﻴﻞ ﰲ ﺍﳊﺎﺳﺐ ، ﺣﻴﺚ ﺗﺮﺳﻞ ﺇﺷﺎﺭﺓ‬‫ﻛﻬﺮﺑﺎﺋﻴﺔ ١ ﺍﱃ ﺍﻟﻠﻮﺣﺔ ﺍﻻﻡ ) ‪ ( MotherBoard‬ﻭﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺘﻮﺟﻴﻬﻬﺎ ﺍﱃ ﻭﺣﺪﺓ ﻣﻮﺯﺩ ﺍﻟﻄﺎﻗﺔ )‪Power Supply‬‬‫‪ .(Unit‬ﺑﻌﺪ ﺫﻟﻚ ﻳﺄﰐ ﺩﻭﺭ ﻭﺣﺪﺓ ‪ PSU‬ﻟﻜﻲ ﺗﻘﻮﻡ ﲟﻬﻤﺔ ﺗﺰﻭﻳﺪ ﺍﳊﺎﺳﺐ ﻭﻣﻠﺤﻘﺎﺗﻪ ﺑﺎﻟﻜﻤﻴﺔ ﺍﳌﻄﻠﻮﺑﺔ ﻣﻦ ﺍﻟﻄﺎﻗﺔ،‬‫ﻭﺇﺭﺳﺎﻝ ﺍﺷﺎﺭﺓ ‪ Power Good‬ﺇﱃ ﺍﻟﻠﻮﺣﺔ ﺍﻻﻡ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﻧﻈﺎﻡ ﺍﻝ ‪ . BIOS‬ﺗﺪﻝ ﻫﺬﻩ ﺍﻻﺷﺎﺭﺓ ﻋﻠﻰ ﺃﻧﻪ ﰎ‬‫ﺗﺰﻭﻳﺪ ﺍﻟﻄﺎﻗﺔ ﺍﻟﻜﺎﻓﻴﺔ ، ﻭﻓﻮﺭﺍ ﺳﻴﺒﺪﺃ ﺑﺮﻧﺎﻣﺞ ﺍﻟﻔﺤﺺ ﺍﻟﺬﺍﰐ ) ‪ ( Power on Self Test‬ﺍﻟﺬﻱ ﻳﻌﺮﻑ ﺍﺧﺘﺼﺎﺭﴽ‬‫ﺏ ‪ POST‬ﺑﻔﺤﺺ ﺃﺟﻬﺰﺓ ﻭﳏﻠﻘﺎﺕ ﺍﳊﺎﺳﺐ )ﻣﺜﻞ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﺍﳌﺎﻭﺱ ﻭﺍﻟﻨﺎﻗﻞ ﺍﻟﺘﺴﻠﺴﻠﻲ ...ﺍﱁ(‬‫ﻭﺍﻟﺘﺄﻛﺪ ﻣﻦ ﺃ‪‬ﺎ ﺳﻠﻴﻤﺔ. ﺑﻌﺪﻫﺎ ﻳﻘﻮﻡ ﺍﻝ ‪ POST‬ﺑﻨﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﱃ ﻧﻈﺎﻡ ﺍﻝ ‪ BIOS‬ﺣﻴﺚ ﺳﻴﻘﻮﻡ ﺍﻝ ‪POST‬‬‫ﺑﺘﺤﻤﻴﻞ ﺍﻝ ‪ BIOS‬ﺍﱃ ‪‬ﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ 0‪ 0xFFFF‬ﻭ ﺳﻴﻘﻮﻡ ﺃﻳﻀﺎ ﺑﻮﺿﻊ ﺗﻌﻠﻴﻤﺔ ﻗﻔﺰ ) ‪ ( jump‬ﰲ ﺃﻭﻝ ﻋﻨﻮﺍﻥ‬‫ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﺍﱃ ‪‬ﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ، ﻛﺬﻟﻚ ﻣﻦ ﻣﻬﺎﻡ ﺍﻝ ‪ POST‬ﻫﻲ ﺗﺼﻔﲑ ﺍﳌﺴﺠﻠﲔ ‪ CS:IP‬ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻥ ﺃﻭﻝ‬‫ﺗﻌﻠﻴﻤﻴﺔ ﺳﻴﻨﻔﺬﻫﺎ ﺍﳌﻌﺎﰿ ﻫﻲ ﺗﻌﻠﻴﻤﺔ ﺍﻟﻘﻔﺰ ﺍﱃ ‪‬ﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﺍﻝ ‪ . BIOS‬ﻳﺴﺘﻠﻢ ﺍﻝ ‪ BIOS‬ﺍﻟﺘﺤﻜﻢ‬‫ﻭﻳﺒﺪﺃ ﰲ ﺍﻧﺸﺎء ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ) ‪ ( Interrupt Vector Table‬ﻭﺗﻮﻓﲑ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﻘﺎﻃﻌﺎﺕ ،ﻭﻳﻘﻮﻡ ﺑﺎﳌﺰﻳﺪ‬‫ﻣﻦ ﻋﻤﻠﻴﺎﺕ ﺍﻟﻔﺤﺺ ﻭﺍﻻﺧﺘﺒﺎﺭ ﻟﻠﺤﺎﺳﺐ ، ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺒﺪﺃ ﰲ ﻣﻬﻤﺔ ﺍﻟﺒﺤﺚ ﻋﻦ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﰲ ﺍﻻﺟﻬﺰﺓ‬‫ﺍﳌﻮﺟﻮﺩﺓ ﺑﻨﺎءﺍ ﻋﻠﻰ ﺗﺮﺗﻴﺒﻬﺎ ﰲ ﺍﻋﺪﺍﺩﺍﺕ ﺍﻝ ‪ BIOS‬ﰲ ﺑﺮﻧﺎﻣﺞ ‪، Setup‬ﻭﰲ ﺣﺎﻟﺔ ﱂ ﳚﺪ ﺍﻝ ‪ BIOS‬ﺟﻬﺎﺯﺍ ﻗﺎﺑﻼ‬‫ﻟﻼﻗﻼﻉ ﰲ ﻛﻞ ﺍﻟﻘﺎﺋﻤﺔ ﻓﺎﻧﻪ ﻳﺼﺪﺭ ﺭﺳﺎﻟﺔ ﺧﻄﺄ ﺑﻌﺪﻡ ﺗﻮﻓﺮ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻭﻳﻮﻗﻒ ﺍﳊﺎﺳﺐ ﻋﻦ ﺍﻟﻌﻤﻞ ) ‪( Halt‬‬‫، ﻭﰲ ﺣﺎﻟﺔ ﺗﻮﻓﺮ ﺟﻬﺎﺯﴽ ﻗﺎﺑﻼً ﻟﻺﻗﻼﻉ ﺳﻴﻘﻮﻡ ﺍﻝ ‪ BIOS‬ﺑﺘﺤﻤﻴﻞ ﺍﻟﻘﻄﺎﻉ ﺍﻷﻭﻝ ﻣﻨﻪ ) ﳛﻮﻱ ﻫﺬﺍ ﺍﻟﻘﻄﺎﻉ ﻋﻠﻰ‬‫ﺑﺮﻧﺎﻣﺞ ﺍﳌﺤﻤﻞ( ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ 00‪ 0x07c‬ﻭﺳ‪‬ﻨﻘَﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﳌﺤﻤﻞ.‬ ‫ﻴ‬ ‫١ﻫﺬﻩ ﺍﻹﺷﺎﺭﺓ ﲢﻮﻱ ﻋﻠﻰ ﺑﺖ ) ‪ ( bit‬ﺗﺪﻝ ﻗﻴﻤﺘﻪ ﺍﺫﺍ ﻛﺎﻧﺖ 1 ﻋﻠﻰ ﺃﻧﻪ ﰎ ﺗﺸﻐﻴﻞ ﺍﳊﺎﺳﺐ.‬‫٣٣‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﺧﻼﻝ ﻫﺬﻩ ﺍﳌﻬﻤﺔ )ﺍﻗﻼﻉ ﺍﻟﻨﻈﺎﻡ( ﻳﻮﻓﺮ ﻟﻨﺎ ﻧﻈﺎﻡ ﺍﻝ ‪ BIOS‬ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻋﻠﻰ ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﺍﻟﺬﻱ‬‫ﻳﺘﻢ ﺍﻧﺸﺎﺋﻪ ﺑﺪءﴽ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0‪ ، 0x‬ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻫﻲ ﺧﺪﻣﺎﺕ ﻳﻮﻓﺮﻫﺎ ﻟﻨﺎ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﻻﺩﺍء ﻭﻇﻴﻔﺔ ﻣﻌﻴﻨﺔ‬‫ﻣﺜﻞ ﻣﻘﺎﻃﻌﺔ ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ. ﻭﺍﺣﺪﺓ ﻣﻦ ﺃﻫﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﻟﻠﺒﺤﺚ ﻋﻦ‬‫ﺟﻬﺎﺯ ﺍﻻﻗﻼﻉ ﻫﻲ ﺍﳌﻘﺎﻃﻌﺔ 91‪ int 0x‬ﺣﻴﺚ ﺗﻜﻤﻦ ﻭﻇﻴﻔﺘﻬﺎ ﰲ ﺍﻟﺒﺤﺚ ﻋﻦ ﻫﺬﺍ ﺍﳉﻬﺎﺯ ﻭﻣﻦ ﰒ ﲢﻤﻴﻞ ﺍﻟﻘﻄﺎﻉ‬‫ﺍﻷﻭﻝ ﻣﻨﻪ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ 00‪ 0x07c‬ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻪ . ﻃﺮﻳﻘﺔ ﺍﻟﺒﺤﺚ ﻭﺍﻟﺘﺤﻤﻴﻞ ﻟﻴﺴﺖ ﺑﺎﻻﻣﺮ ﺍﳌﻌﻘﺪ‬‫ﺣﻴﺚ ﻋﻠﻰ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ ﺍﻟﺒﺤﺚ ﰲ ﺃﻭﻝ ﻗﻄﺎﻉ )ﻣﻦ ﺃﻱ ﺟﻬﺎﺯ ﻣﻮﺟﻮﺩ ﻋﻠﻰ ﻗﺎﺋﻤﺔ ﺍﻻﺟﻬﺰﺓ ﺍﻟﻘﺎﺑﻠﺔ ﻟﻼﻗﻼﻉ(‬‫ﻋﻦ ﺍﻟﺘﻮﻗﻴﻊ 55‪ 0xAA‬ﻭﻫﻲ ﻋﺒﺎﺭﺓ ﻋﻦ ﺑﺎﻳﺘﲔ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﻋﻠﻰ ﺁﺧﺮ ﺍﻟﻘﻄﺎﻉ ﺍﻻﻭﻝ ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﺍﳉﻬﺎﺯ‬‫ﻗﺎﺑﻞ ﻟﻼﻗﻼﻉ. ﻭﻣﻦ ﺍﳉﺪﻳﺮ ﺑﺎﻟﺬﻛﺮ ﺃﻥ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﻮﻓﺮﻫﺎ ﻟﻨﺎ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ ﻓﻘﻂ ﺍﺫﺍ ﻛﺎﻥ‬‫ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ‪ Real Mode‬ﺃﻣﺎ ﺇﺫﺍ ﰎ ﺗﻐﻴﲑ ﳕﻂ ﺍﳌﻌﺎﰿ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ‪Protected Mode‬‬‫- ﻛﻤﺎ ﺳﻨﺮﻯ ﺫﻟﻚ ﻻﺣﻘﺎ- ﻓﺎﻧﻪ ﻟﻦ ﳝﻜﻦ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺑﻞ ﺳﻴﺘﺴﺒﺐ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ ﰲ ﺣﺪﻭﺙ‬ ‫ﺍﺳﺘﺜﻨﺎءﺍﺕ ) ‪ ( Excep on‬ﺗﻮﻗﻒ ﻋﻤﻞ ﺍﳊﺎﺳﺐ.‬ ‫‪Bootloader‬‬ ‫٣.٢. ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻫﻮ ﺑﺮﻧﺎﻣﺞ ﻭﻇﻴﻔﺘﻪ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻫﻲ ﲢﻤﻴﻞ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ.ﻫﺬﺍ ﺍﳌﺤﻤﻞ ﳚﺐ‬ ‫ﺍﻥ ﺗﺘﻮﻓﺮ ﻓﻴﻪ ﺍﻟﺸﺮﻭﻁ ﺍﻻﺗﻴﺔ :‬ ‫١. ﺣﺠﻢ ﺍﻟﱪﻧﺎﻣﺞ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ 215 ﺑﺎﻳﺖ ﺑﺎﻟﻀﺒﻂ.‬‫٢. ﺃﻥ ﻳﺘﻮﺍﺟﺪ ﻋﻠﻰ ﺍﻟﻘﻄﺎﻉ ﺍﻷﻭﻝ ﰲ ﺍﻟﻘﺮﺹ : ﺍﻟﻘﻄﺎﻉ ﺭﻗﻢ 1 ، ﺍﻟﺮﺃﺱ 0 ، ﺍﳌﺴﺎﺭ 0 ، ﻭﺃﻥ ﳛﻤﻞ ﺍﻟﺘﻮﻗﻴﻊ‬ ‫ﺍﳌﻌﺮﻭﻑ.‬ ‫٣. ﺃﻥ ﳛﻮﻱ ﺷﻔﺮﺓ ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ.‬‫( ﻭﻫﻮ ﻣﺎ‬ ‫‪header,symbol table,...etc‬‬ ‫ﺧﺎﱄ ﻣﻦ ﺃﻱ ﺃﺿﺎﻓﺎﺕ )‬ ‫‪object code‬‬ ‫٤. ﺃﻥ ﻳﻜﻮﻥ ﺍﻟﱪﻧﺎﻣﺞ‬ ‫ﻳﻌﺮﻑ ﺃﻳﻀﺎ ﺑـ ‪. Flat Binary‬‬‫ﺍﻟﺸﺮﻁ ﺍﻷﻭﻝ ‪‬ﻘﻴﺪ ﻭﻇﻴﻔﺔ ﺍﳌﺤﻤﻞ ﻭﻗﺪﺭﺗﻪ ﻋﻠﻰ ﺗﻮﻓﲑ ﺧﺼﺎﺋﺺ ﻣﺘﻘﺪﻣﺔ ٢، ﺣﻴﺚ ﺃﻥ ﻫﺬﺍ ﺍﳊﺠﻢ ﻻ ﻳﻜﻔﻲ‬ ‫ﻳ‬‫ﻟﻜﻲ ﻳﺒﺤﺚ ﺍﳌﺤﻤﻞ ﻋﻦ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻭﲤﻬﻴﺪ ﺍﻟﻄﺮﻳﻖ ﳍﺎ ﻟﻠﺒﺪء ﺑﺘﻨﻔﻴﺬﻫﺎ ، ﻭﺑﺴﺒﺐ ﺃﻥ ﺍﻟﻨﻮﺍﺓ ﺳﺘﻜﻮﻥ ‪ 32-bit‬ﻓﺎﻧﻪ‬‫ﳚﺐ ﲡﻬﻴﺰ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻷﺷﻴﺎء ﺑﺪءﴽ ﻣﻦ ﺟﺪﺍﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ )ﺍﻟﻌﺎﻣﺔ ﻭﺍﳋﺎﺻﺔ( ﻭﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ 02‪ A‬ﻭﺍﻧﺘﻬﺎءﴽ‬‫ﺑﺘﻐﻴﲑ ﳕﻂ ﺍﳌﻌﺎﰿ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﺍﻟﻘﻔﺰ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ﻟﻠﻤﺒﺎﺷﺮﺓ ﰲ ﺗﻨﻔﻴﺬﻫﺎ . ﻛﻞ ﺫﻟﻚ ﳛﺘﺎﺝ ﺍﱃ ﺣﺠﻢ ﺃﻛﱪ‬‫ﻣﻦ ﺍﳊﺠﻢ ﺍﳌﺸﺮﻭﻁ ﻟﺬﻟﻚ ﻋﺎﺩﺓ ﻣﺎ ﻳﻠﺠﺄ ﻣﱪﳎﻮﺍ ﺍﳌﺤﻤﻼﺕ ﺍﱃ ﲡﺰﺋﻴﻬﺎ ﻋﻠﻰ ﻣﺮﺣﻠﺘﲔ ﻭﻫﻮ ﻣﺎ ﻳﺴﻤﻰ ﺏ‬‫‪ . Mul -Stage Boot Loader‬ﺍﻟﺸﺮﻁ ﺍﻟﺜﺎﱐ ﻟﻠﻤﺤﻤﻞ ﻭﻫﻮ ﺃﻥ ﻳﺘﻮﺍﺟﺪ ﻋﻠﻰ ﺃﻭﻝ ﻗﻄﺎﻉ ﰲ ﺍﻟﻘﺮﺹ ﻭﻫﻮ ﳛﻤﻞ‬ ‫ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﺍﻟﺘﺎﱄ:‬ ‫• ﺍﻟﻘﻄﺎﻉ ﺭﻗﻢ 1‬ ‫‪Safe Mode‬‬ ‫٢ﻣﺜﻞ ﺧﺎﺻﻴﺔ ﺍﻝ‬ ‫٤٣‬
    • ‫٣.٣. ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ‬ ‫0‬ ‫ﺍﳌﺴﺎﺭ ﺭﻗﻢ‬ ‫•‬ ‫0‬ ‫ﺍﻟﺮﺃﺱ ﺭﻗﻢ‬ ‫•‬‫ﻭﲢﻘﻴ ‪ ‬ﻫﺬﺍ ﺍﻟﺸﺮﻁ ﻟﻴﺲ ﺑﺎﻷﻣﺮ ﺍﳌﻌﻘﺪ ﺧﺼﻮﺻﺎ ﻣﻊ ﺗﻮﻓﺮ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻻﺩﻭﺍﺕ ﺍﻟﱵ ﺗﺴﺎﻋﺪ ﻋﻠﻰ ﻧﺴﺦ ﻣﻘﻄﻊ‬ ‫ﻖ‬‫ﻣﻦ ﻗﺮﺹ ﻣﺎ ﺍﱃ ﻣﻘﻄﻊ ﰲ ﻗﺮﺹ ﺁﺧﺮ ، ﺃﻣﺎ ﺍﻟﺸﻖ ﺍﻟﺜﺎﱐ ﻣﻦ ﺍﻟﺸﺮﻁ ﻓﻬﻮ ﻣﺘﻌﻠﻖ ﺑﺘﻤﻴﻴﺰ ﺍﻟﻘﻄﺎﻉ ﺍﻻﻭﻝ ﻛﻘﻄﺎﻉ‬‫ﻗﺎﺑﻞ ﻟﻼﻗﻼﻉ ﻣﻦ ﻏﲑﻩ ، ﺣﻴﺚ ﺣﱴ ﻳﻜﻮﻥ ﺍﻟﻘﻄﺎﻉ ﻗﺎﺑﻼ ﻟﻼﻗﻼﻉ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﳛﻤﻞ ﺍﻟﺘﻮﻗﻴﻊ 55‪ 0xAA‬ﰲ‬‫ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 015 ﻭ 115 . ﻭﺑﺪﻭﻥ ﻫﺬﺍ ﺍﻟﺘﻮﻗﻴﻊ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ )ﻭﲢﺪﻳﺪﺍ ﻣﻘﺎﻃﻌﺔ ﺭﻗﻢ 91‪ (0x‬ﻟﻦ ﺗﺘﻌﺮﻑ ﻋﻠﻰ‬‫ﻫﺬﺍ ﺍﻟﻘﻄﺎﻉ ﻛﻘﻄﺎﻉ ﻗﺎﺑ ٌ ﻟﻺﻗﻼﻉ. ﺃﻣﺎ ﺍﻟﺸﺮﻁ ﺍﻟﺜﺎﻟﺚ ﻓﻬﻮ ﺷﺮﻁ ﺍﺧﺘﻴﺎﺭﻱ ﻭﻟﻴﺲ ﺍﺟﺒﺎﺭﻱ ، ﻓﻤﻦ ﺍﳌﻤﻜﻦ ﺃﻥ‬ ‫ﻞ‬‫ﺗﻜﻮﻥ ﻭﻇﻴﻔﺔ ﺍﳌﺤﻤﻞ ﻫﻲ ﻋﺮﺽ ﺭﺳﺎﻟﺔ ﺗﺮﺣﻴﺐ ﻓﻘﻂ ! ﻭﻟﻜﻦ ﰲ ﺃﻏﻠﺐ ﺍﳊﺎﻻﺕ ﺍﻟﻮﺍﻗﻌﻴﺔ ﳚﺐ ﺃﻥ ‪‬ﺤ ﱠﻞ‬ ‫ﺗ ﻤ‬‫ﺍﻟﻨﻮﺍﺓ ﻭُﻨ ﱠﺬ ﻋﻦ ﻃﺮﻳﻖ ﻫﺬﺍ ﺍﳌﺤﻤﻞ. ﻭﻗﺪ ﺃﺳﻠﻔﻨﺎ ﻭﺫﻛﺮﻧﺎ ﺃﻥ ﲢﻤﻴﻞ ﻧﻮﺍﺓ ‪ 32-bit‬ﳜﺘﻠﻒ ﻋﻦ ﲢﻤﻴﻞ ﻧﻮﺍﺓ ‪16-bit‬‬ ‫ﺗﻔ‬‫، ﺣﻴﺚ ﰲ ﺍﻻﻭﱃ ﳚﺐ ﲡﻬﻴﺰ ﺍﻟﻄﺮﻳﻖ ﺃﻣﺎﻡ ﺍﻟﻨﻮﺍﺓ ﻭﺗﻔﻌﻴﻞ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ ﻟﺬﻟﻚ ﻭ‪‬ﺟﺐ ﺗﻘﺴﻴﻢ ﻣﻬﻤﺔ ﳏﻤﻞ‬‫ﺍﻟﻨﻈﺎﻡ ﺍﱃ ﻣﺮﺣﻠﻴﱳ - ﻛﻤﺎﺳﻨﺮﻯ ﺫﻟﻚ - ، ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﺍﻟﻨﻮﺍﺓ ‪ 16-bit‬ﻓﺎﻧﻪ ﳝﻜﻦ ﲢﻤﻴﻠﻬﺎ ﲟﺮﺣﻠﺔ ﻭﺍﺣﺪﺓ‬‫ﻓﻘﻂ . ﻭﺍﻟﺸﺮﻁ ﺍﻻﺧﲑ ﻳﺘﻌﻠﻖ ﺑﺼﻴﻐﺔ ﺍﳌﻠﻒ ﺍﻟﺘﻨﻔﻴﺬﻱ ﻟﻠﻤﺤﻤﻞ، ﺣﻴﺚ ﺃﻏﻠﺐ ﺍﳌﺘﺮﲨﺎﺕ ﲣﺮﺝ ﺻﻴﻎ ﺗﻨﻔﻴﺬﻳﺔ‬‫ﲢﻮﻱ ﻋﻠﻰ ﺍﻟﻜﺜﲑ ﻣﻦ ﺍﳌﻌﻠﻮﻣﺎﺕ ﺍﳌﻀﺎﻓﺔ ﻣﻦ ﻗﺒﻠﻪ ) ﻛﺼﻴﻎ ‪ ( ELF,PE,COFF,...etc‬ﻭﻫﺬﺍ ﻣﺎ ﳚﻌﻞ ﻋﻤﻠﻴﺔ ﺗﻨﻔﻴﺬ‬‫ﺍﳌﺤﻤﻞ ﻭﺗﺸﻐﻴﻠﻪ ﻣﻦ ﻗﺒﻞ ﺍﻟﺒﺎﻳﻮﺱ ﻣﺴﺘﺤﻴﻠﺔ ، ﻓﺎﻟﺒﺎﻳﻮﺱ ﻋﻨﺪﻣﺎ ﻳﻘﺮﺃ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻧﻪ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ‬‫ﺍﱃ ﺃﻭﻝ ﺑﺎﻳﺖ ﻓﻴﻪ ﻭﺍﻟﺬﻱ ﳚﺐ ﺍﻥ ﻳﻜﻮﻥ ﻗﺎﺑﻞ ﻟﻠﺘﻨﻔﻴﺬ ﻭﻟﻴﺲ ﻣﻌﻠﻮﻣﺎﺕ ﺃﻭ ﻫﻴﺪﺭ ﻋﻦ ﺍﳌﻠﻒ - ﻛﻤﺎ ﰲ ﺣﺎﻟﺔ‬‫ﺍﻟﺼﻴﻎ ﺍﻟﺴﺎﺑﻖ ﺫﻛﺮﻫﺎ- . ﻟﺬﻟﻚ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﺻﻴﻐﺔ ﺍﳌﺤﻤﻞ ﻫﻲ ﻋﺒﺎﺭﺓ ﻋﻦ ﺍﻟﺼﻴﻐﺔ ﺍﻟﺜﻨﺎﺋﻴﺔ ﺍﳌﻘﺎﺑﻠﺔ ﻟﻸﻭﺍﻣﺮ‬ ‫ﺍﳌﻮﺟﻮﺩﺓ ﻓﻴﻪ ﺑﺪﻭﻥ ﺃﻱ ﺍﺿﺎﻓﺎﺕ ﺃﻱ ‪ Object Code‬ﺍﻭ ‪.Flat Binary‬‬‫ﻭﳚﺪﺭ ﺑﻨﺎ ﺍﳊﺪﻳﺚ ﻋﻦ ﻟﻐﺔ ﺑﺮﳎﺔ ﳏ ﱢﻞ ﺍﻟﻨﻈﺎﻡ، ﻓﻐﺎﻟﺒﺎ ﺗﺴﺘﺨﺪﻡ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ )‪ (Assembly 16-bit‬ﻷﺳﺒﺎﺏ‬ ‫ﻤ‬‫ﻛﺜﲑﺓ ، ﻣﻨﻬﺎ ﺃﻥ ﺍﳊﺎﺳﺐ ﻋﻨﺪﻣﺎ ﻳﺒﺪﺃ ﺍﻟﻌﻤﻞ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻜﻮﻥ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﲢﻘﻴﻘﺎ ﻷﻏﺮﺍﺽ ﺍﻟﺘﻮﻓﻘﻴﺔ )‬‫‪ ( Backward Compa bility‬ﻣﻊ ﺍﻷﺟﻬﺰﺓ ﺍﻟﺴﺎﺑﻘﺔ ، ﺃﻳﻀﺎ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ‪ 16-bit‬ﳚﻌﻞ ﻣﻦ ﺍﳌﻤﻜﻦ‬‫ﺍﺳﺘﺪﻋﺎء ﻣﻘﺎﻃﻌﺎﺕ ﻭﺧﺪﻣﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ - ﻗﺒﻞ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺑﻴﺌﺔ ‪ ، - 32-bit‬ﺃﺧﲑﴽ ﻻ ﺣﺎﺟﺔ ﳌﻠﻔﺎﺕ ﻭﻗﺖ‬‫ﺍﻟﺘﺸﻐﻴﻞ ‪ ، run- me library‬ﺣﻴﺚ ﺃﻥ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻣﺎﻫﻲ ﺍﻻ ﳐﺘﺼﺮﺍﺕ ﻟﻠﻐﺔ ﺍﻵﻟﺔ ‪ .Machine Language‬ﻛﻞ‬‫ﻫﺬﺍ ﻻ ﳚﻌﻞ ﻋﻤﻠﻴﺔ ﻛﺘﺎﺑﺔ ﳏ ﱢﻞ ﺍﻟﻨﻈﺎﻡ ﺑﻠﻐﺔ ﺍﻟﺴﻲ ﻣﺴﺘﺤﻴﻼ ! ﻓﻬﻨﺎﻙ ﻛ ﱞ ﻛﺒﲑ ﻣﻦ ﺍﳌﺤﻤﻼﺕ ﺗﺴﺘﺨﺪﻡ ﻟﻐﺔ‬ ‫ﻢ‬ ‫ﻤ‬‫ﺍﻟﺴﻲ ﻭﺍﻟﺘﺠﻤﻴﻊ ﰲ ﺁﻥ ﻭﺍﺣﺪ ) ﻣﺜﻞ ‪ ، ( GRUB,NTLDR,LILO...etc‬ﻟﻜﻦ ﻗﺒﻞ ﺑﺮﳎﺔ ﻣﺜﻞ ﻫﺬﻩ ﺍﳌﺤﻤﻼﺕ ﳚﺐ‬‫ﺑﺮﳎﺔ ﺑﻌﺾ ﻣﻠﻔﺎﺕ ﺍﻝ ‪ run- me‬ﻟﺘﻮﻓﲑ ﺑﻴﺌﺔ ﻟﻜﻲ ﺗﻌﻤﻞ ﺑﺮﺍﻣﺞ ﺍﻟﺴﻲ ﻋﻠﻴﻬﺎ ، ﺃﻳﻀﺎ ﳚﺐ ﻛﺘﺎﺑﺔ ‪ loader‬ﻟﻜﻲ‬ ‫ﻳﻘﺮﺃ ﺍﻟﺼﻴﻐﺔ ﺍﻟﻨﺎﲡﺔ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﺍﻟﺴﻲ ﻭﻳﺒﺪﺃ ﺍﻟﺘﻨﻔﻴﺬ ﻣﻦ ﺩﺍﻟﺔ ﺍﻝ ‪. main‬‬ ‫٣.٣. ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺃﺛﻨﺎء ﻣﺮﺣﻠﺔ ﺍﻹﻗﻼﻉ ﻭﻋﻨﺪﻣﺎ ‪‬ﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻓﺎﻥ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﺗﺄﺧﺬ ﺍﻟﺸﻜﻞ ٣.١ .ﻭﺃﻭﻝ‬ ‫ﻳ‬‫٤٢٠١ ﺑﺎﻳﺖ ﺗﺴﺘﺨﺪﻡ ﻣﻦ ﻗﺒﻞ ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﺬﻱ ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﺍﻟﺘﻨﻔﻴﺬ ﻟﻜﻞ ﻣﻘﺎﻃﻌﺔ ﻟﻠﺒﺎﻳﻮﺱ ،‬‫٥٣‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫ﺷﻜﻞ ٣.١.: ﳐﻄﻂ ﳏﺘﻮﻳﺎﺕ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ‬‫ﻳﻠﻴﻬﺎ ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﰒ ﻣﺴﺎﺣﺔ ﺫﺍﻛﺮﺓ ﺧﺎﻟﻴﺔ ﲢﻮﻱ ﺍﻟﻌﻨﻮﺍﻥ 00‪ 0x07c‬ﻭﻫﻮ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺬﻱ ﻳﻨﻘﻞ ﺍﻟﺒﺎﺑﻮﺱ‬‫ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻪ )ﻋﻨﻮﺍﻥ ﺑﺮﻧﺎﻣﺞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ( ، ﻭﻳﻠﻴﻬﺎ ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺑﺎﻳﻮﺱ ﺍﳌﻮﺳﻌﺔ ﻭﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﻭﺍﻟﱵ ﲟﺠﺮﺩ‬‫ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻴﻬﺎ ﺗﻈﻬﺮ ﺍﻷﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ )‪ (Memory Mapped‬ﻭﻳﻠﻴﻬﺎ ﺍﻟﺒﺎﻳﻮﺱ ﻋﻠﻰ ﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﻭﻣﻨﺎﻃﻖ‬‫ﳏﺠﻮﺯﺓ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻟﺒﻌﺾ ﺃﺟﻬﺰﺓ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻭﻣﻦ ﰒ ﺍﻟﺒﺎﻳﻮﺱ ﻭﺍﻟﺬﻱ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0000‪ 0xf‬ﻭﻫﻮ‬ ‫ﻣﻮﺟﻮﺩ ﻋﻠﻰ ﺫﺍﻛﺮﺓ ﺍﻟﺮﻭﻡ )‪. (Memory Mapped‬‬ ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﺍﳌﺜﺎﻝ ١.٣ ﻳﻮﺿﺢ ﺃﺻﻐﺮ ﳏﻤﻞ ﻟﻠﻨﻈﺎﻡ ﳝﻜﻦ ﻛﺘﺎﺑﺘﻪ ﻭﺗﻨﻔﻴﺬﻩ ، ﺑﺎﺳﺘﺨﺪﺍﻡ ﺍﳌﺠﻤﻊ ‪ ٣ NASM‬ﻭﻫﻮ ﳎﻤﻊ ﻣﺘﻌﺪﺩ‬ ‫ﺍﳌﻨﺼﺎﺕ ﻭﻳﻮﻓﺮ ﻣﻴﺰﺓ ﺍﻧﺘﺎﺝ ﻣﻠﻔﺎﺕ ﺛﻨﺎﺋﻴﺔ ‪. object code‬‬ ‫٣ﺭﺍﺟﻊ ﺍﳌﻠﺤﻖ ﺍ ﳌﻌﺮﻓﺔ ﻛﻴﻔﻴﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﺠﻤﻊ ﻟﺘﺮﲨﺔ ﺍﳌﺤﻤﻞ ﻭﻛﻴﻔﻴﺔ ﻧﺴﺨﻪ ﺍﱃ ‪ floppy disk or CD‬ﻟﻴﺘﻢ ﺍﻟﻘﻼﻉ ﻣﻨﻪ ﺳﻮﺍءﴽ ﻛﺎﻥ‬ ‫ﻋﻠﻰ ﺟﻬﺎﺯ ﻓﻌﻠﻲ ﺃﻭ ﻋﻠﻰ ﺟﻬﺎﺯ ﲣﻴﻠﻲ )‪. (Virtual Machine‬‬ ‫٦٣‬
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫‪Example‬‬ ‫‪٣.١: Smallest Bootloader‬‬‫١‬‫.‪٢ ;Simple Bootloader do nothing‬‬‫٣‬‫61 ‪٤ bits‬‬ ‫.‪; 16−bit real mode‬‬‫٥‬‫:‪٦ start‬‬ ‫.‪; label are pointer‬‬‫٧‬ ‫‪cli‬‬ ‫.‪; clear interrupt‬‬‫٨‬ ‫‪hlt‬‬ ‫.‪; halt the system‬‬‫٩‬‫٠١‬ ‫) $$−$(−015 ‪times‬‬ ‫‪db‬‬ ‫0‬ ‫.‪; append zeros‬‬‫١١‬‫٢١‬ ‫.)00‪; $ is the address of first instruction (should be 0x07c‬‬‫٣١‬ ‫.‪; $$ is the address of current line‬‬‫٤١‬ ‫.‪; $−$$ means how many byte between start and current‬‬‫٥١‬‫٦١‬ ‫‪; if cli and hlt take 4 byte then time directive will fill‬‬‫٧١‬ ‫.‪; 510−4 = 506 zeros‬‬‫٨١‬‫٩١‬ ‫55‪; finally the boot signature 0xaa‬‬‫٠٢‬ ‫‪db‬‬ ‫.‪0x55 ; first byte of a boot signature‬‬‫١٢‬ ‫‪db‬‬ ‫.‪0xaa ; second byte of a boot signature‬‬‫ﻭﻋﻨﺪﻣﺎ ﻳﺒﺪﺃ ﺍﳉﻬﺎﺯ ﺑﺎﻟﻌﻤﻞ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ ﻳﻘﻮﻡ ﺑﻨﺴﺦ ﻫﺬﺍ ﺍﳌﺤﻤﻞ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 00‪ 0x0000:0x7c‬ﻭﻳﺒﺪﺃ‬‫ﺑﺘﻨﻔﻴﺬﻩ ، ﻭﰲ ﻫﺬﺍ ﺍﳌﺜﺎﻝ ﻓﺎﻥ ﺍﳌﺤﻤﻞ ﻫﺬﺍ ﺍﻟﺬﻱ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ )‪ (real mode‬ﻻ ﻳﻘﻮﻡ ﺑﺸﻲء ﺫﻭ‬‫ﻓﺎﺋﺪﺓ ﺣﻴﺚ ﻳﺒﺪﺃ ﺑﺘﻨﻔﻴﺬ ﺍﻻﻣﺮ ‪ cli‬ﺍﻟﺬﻱ ﻳﻮﻗﻒ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ، ﻳﻠﻴﻬﺎ ﺍﻻﻣﺮ ‪ hlt‬ﺍﻟﺬﻱ ﻳﻮﻗﻒ ﻋﻤﻞ ﺍﳌﻌﺎﰿ‬‫ﻭﺑﺎﻟﺘﺎﱄ ﻳﺘﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ ، ﻭﺑﺪﻭﻥ ﻫﺬﺍ ﺍﻷﻣﺮ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻴﺴﺘﻤﺮ ﰲ ﺗﻨﻔﻴﺬ ﺃﻭﺍﻣﺮ ﻻ ﻣﻌﲎ ﳍﺎ )‪(garbage‬‬‫ﻭﺍﻟﱵ ﺳﺘﺆﺩﻱ ﺍﱃ ﺳﻘﻮﻁ )‪ (Crash‬ﺍﻟﻨﻈﺎﻡ . ﻭﺑﺴﺒﺐ ﺃﻥ ﺣﺠﻢ ﺍﳌﺤﻤﻞ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ 215 ﺑﺎﻳﺖ ﻭﺃﻥ ﺁﺧﺮ‬‫ﺑﺎﻳﺘﲔ ﻓﻴﻪ ﳚﺐ ﺃﻥ ﺗﻜﻮﻧﺎ ﺍﻟﺘﻮﻗﻴﻊ ﺍﳋﺎﺹ ﺑﺎﳌﺤﻤﻞ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﺃﻭﻝ 015 ﺑﺎﻳﺖ ﺫﺍﺕ ﻗﻴﻤﺔ ﻭﺍﺧﺮ ﺑﺎﻳﺘﲔ‬‫ﳘﺎ 55‪ ، 0xaa‬ﻟﺬﻟﻚ ﰎ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﻮﺟﻪ ‪ times‬ﻟﻜﻲ ﻳﺘﻢ ﻣﻠﺊ ﺍﳌﺘﺒﻘﻲ ﻣﻦ ﺃﻭﻝ 015 ﺑﺎﻳﺖ ﺑﺎﻟﻘﻴﻤﺔ ﺻﻔﺮ‬‫)ﻭﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﺃﻱ ﻗﻴﻤﺔ ﺍﺧﺮﻯ( ﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﻛﺘﺎﺑﺔ ﺍﻟﺘﻮﻗﻴﻊ ﺍﳋﺎﺹ ﺑﺎﳌﺤﻤﻞ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺍﻟﺘﻌﺮﻑ ﻋﻠﻴﻪ‬ ‫ﻣﻦ ﻗ‪‬ﺒﻞ ﺍﻟﺒﺎﻳﻮﺱ.‬ ‫٣.٤.١. ﻋﺮﺽ ﺭﺳﺎﻟﺔ ﺗﺮﺣﻴﺒﻴﺔ‬‫ﻃﺎﳌﺎ ﻣﺎ ﺯﻟﻨﺎ ﻧﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻓﺎﻥ ﺫﻟﻚ ﳝﻜﻨﻨﺎ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ، ﻭﰲ ﺍﳌﺜﺎﻝ ٢.٣ ﰎ‬ ‫ﻋﺮﺽ ﺭﺳﺎﻟﺔ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 01‪ int 0x‬ﺍﻟﺪﺍﻟﺔ ‪. 0xe‬‬‫٧٣‬
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ Example ٣.٢: Welcom to OS World١٢ ;Hello Bootloader٣٤ bits 16 ; 16−bit real mode.٥ org 0x0 ; this number will added to all addresses (relocating).٦٧ start:٨ jmp main ; jump over data and function to entry point.٩١٠١١١٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٣ ; data١٤ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٥١٦ hello msg db "Welcome to eqraOS, Coded by Ahmad Essam",0xa,0xd,0١٧١٨ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٩ ; puts16: prints string using BIOS interrupt٢٠ ; input:٢١ ; es: pointer to data segment.٢٢ ; si: point to the string٢٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٤٢٥ puts16:٢٦٢٧ lodsb ; read character from ds:si to al ,and increment si if df=0.٢٨٢٩ cmp al,0 ; check end of string ?٣٠ je end puts16 ; yes jump to end.٣١٣٢ mov ah,0xe ; print character routine number.٣٣ int 0x10 ; call BIOS.٣٤٣٥ jmp puts16 ; continue prints until 0 is found.٣٦٣٧ end puts16:٣٨ ٣٨
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬٣٩ ret٤٠٤١٤٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٣ ; entry point of bootloader.٤٤ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٥٤٦ main:٤٧٤٨ ;−−−−−−−−−− −−−−−−−−−−−٤٩ ; intit registers٥٠ ;−−−−−−−−−− −−−−−−−−−−−٥١٥٢ ; because bootloader are loaded at 0x07c00 we can refrence this location with many different combination of segment:offset addressing.٥٣٥٤ ; So we will use either 0x0000:0x7c000 or 0x:07c0:0x0000 , and in this example we use 0x07c0 for segment and 0x0 for offset.٥٥٥٦ mov ax,0x07c0٥٧ mov ds,ax٥٨ mov es,ax٥٩٦٠ mov si,hello msg٦١ call puts16٦٢٦٣ cli ; clear interrupt.٦٤ hlt ; halt the system.٦٥٦٦ times 510−($−$$ ) db 0 ; append zeros.٦٧٦٨ ; finally the boot signature 0xaa55٦٩ db 0x55٧٠ db 0xaadata segment ‫ ﻭﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ‬code segment ‫ﺍﻟﺸﻲء ﺍﳌﻼﺣﻆ ﰲ ﺍﳌﺜﺎﻝ ﺍﻟﺴﺎﺑﻖ ﻫﻮ ﺃﻥ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ‬‫ﻣﺘﻮﺍﺟﺪﺍﻥ ﰲ ﻧﻔﺲ ﺍﳌﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ )ﺩﺍﺧﻞ ﺍﻝ 215 ﺑﺎﻳﺖ( ﻟﺬﻟﻚ ﳚﺐ ﺗﻌﺪﻳﻞ ﻗﻴﻢ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ‬‫ﻟﻼﺷﺎﺭﺓ ﺍﱃ ﺍﳌﻜﺎﻥ ﺍﻟﺼﺤﻴﺢ. ﻭ ﺑﺪﺍﻳﺔ ﻧﺬﻛﺮ ﺃﻥ ﺍﻟﺒﺎﻳﻮﺱ ﻋﻨﺪﻣﺎ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺑﺮﻧﺎﻣﺞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﻗﻤﻨﺎ‬‫ ﻟﺬﻟﻚ ﻻ ﺩﺍﻋﻲ‬cs:ip ‫ ﻭﺍﻟﱵ ﻳﻨﺘﺞ ﻣﻨﻬﺎ ﺗﺼﺤﻴﺢ ﻗﻴﻢ ﺍﻝ‬far jump ‫ﺑﻜﺘﺎﺑﺘﻪ ﻓﺎﻧﻪ ﰲ ﺣﻘﻴﻘﺔ ﺍﻷﻣﺮ ﻳﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ‬٣٩
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﻟﻠﻘﻠﻖ ﺣﻮﻝ ﻫﺬﻳﻦ ﺍﳌﺴﺠﻠﲔ، ﻟﻜﻦ ﳚﺐ ﺗﻌﺪﻳﻞ ﻗﻴﻢ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﺍﻻﺧﺮﻯ ﻣﺜﻞ ‪.ds,es,ss,fs,gs‬‬‫ﻭﻛﻤﺎ ﻧﻌﻠﻢ ﺃﻥ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﳌﺤﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻫﻮ 00‪ 0x07c‬ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﺍﻟﻴﻪ ﺑﺄﻛﺜﺮ ﻣﻦ 0004 ﻃﺮﻳﻘﺔ‬‫ﳐﺘﻠﻔﺔ ، ﻟﻜﻦ ﺳﻮﻑ ﻧﻘﺘﺼﺮ ﻋﻠﻰ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻨﻮﺍﻥ 0‪ 0x07c0:0x‬ﺃﻭ ﺍﻟﻌﻨﻮﺍﻥ 00‪ 0x0:0x7c‬ﻧﻈﺮﴽ ﻻﻥ‬ ‫ﻫﺬﻩ ﻫﻲ ﺍﻟﻘﻴﻢ ﺍﻟﻔﻌﻠﻴﺔ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻣﻬﺎ ﺍﻟﺒﺎﻳﻮﺱ.‬‫ﻭﰲ ﺣﺎﻟﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻻﻭﱃ ﻓﺎﻥ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﳚﺐ ﺃﻥ ﲢﻮﻱ ﺍﻟﻘﻴﻤﺔ 0‪) 0x07c‬ﻛﻤﺎ ﰲ ﺍﳌﺜﺎﻝ‬‫ﺍﻋﻼﻩ( ﺃﻣﺎ ﺑﻘﻴﺔ ﺍﻟﻌﻨﻮﺍﻧﲔ )ﺳﻮﺍءﺍ ﻟﻠﻤﺘﻐﲑﺍﺕ ﻭﺍﻝ ‪ (label‬ﻓﺎ‪‬ﺎ ﳚﺐ ﺃﻥ ﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻘﻴﻤﺔ 0‪ ،0x‬ﻭﻛﻤﺎ ﻫﻮ ﻣﻌﺮﻭﻑ‬‫ﺍﻥ ﺍﳌﺠﻤﻌﺎﺕ ﻋﻨﺪﻣﺎ ﺗﺒﺪﺃ ﰲ ﻋﻤﻠﻴﺔ ﺗﺮﲨﺔ ﺍﳌﻠﻒ ﺍﱃ ﻣﻠﻒ ﺛﻨﺎﺋﻲ ﻓﺎ‪‬ﺎ ﺗﺒﺪﺃ ﺑﺘﺮﻗﻴﻢ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺑﺪءﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0‪0x‬‬‫ﻟﺬﻟﻚ ﻛﺎﻧﺖ ﻭﻇﻴﻔﺔ ﺍﳌﻮﺟﻪ ‪ org‬ﻫﻲ ﻋﻤﻞ ﺍﻋﺎﺩﺓ ﺗﻌﻴﲔ )‪ (reloca ng‬ﻟﻠﻌﻨﺎﻭﻳﻦ ﺑﺎﻟﻘﻴﻤﺔ ﺍﻟﱵ ﰎ ﻛﺘﺎﺑﺘﻬﺎ ، ﻭﰲ‬‫ﺍﳌﺜﺎﻝ ﺃﻋﻼﻩ ﻛﺎﻧﺖ ﺍﻟﻘﻴﻤﺔ ﻫﻲ 0‪ ، 0x‬ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﻣﻜﺎﻥ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﻓﺎﻥ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﳚﺐ ﺃﻥ ﲢﻮﻱ ﺍﻟﻘﻴﻤﺔ 0‪ 0x‬ﺑﻴﻨﻤﺎ ﺍﳌﺴﺠﻼﺕ ﺍﻻﺧﺮﻯ ﳚﺐ ﺃﻥ ﺗﺒﺪﺃ ﻗﻴﻤﻬﺎ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ‬‫00‪ ، 0x7c‬ﻭﻫﺬﺍ ﻻ ﳝﻜﻦ ﺑﺎﻟﻮﺿﻊ ﺍﻟﻄﺒﻴﻌﻲ ﻻﻥ ﺍﳌﺠﻤﻌﺎﺕ ﺳﺘﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0‪ 0x‬ﻟﺬﻟﻚ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ‬ ‫ﺍﳌﻮﺟﻪ ‪ org‬ﻭﲢﺪﻳﺪ ﻗﻴﻤﺔ ﺍﻝ ‪ relocate‬ﺑﺎﻟﻘﻴﻤﺔ 00‪. 0x7c‬‬ ‫٣.٤.٢. ﻣﻌﻠﻮﻣﺎﺕ ﻗﻄﺎﻉ ﺍﻻﻗﻼﻉ‬‫ﺇﺿﺎﻓﺔ ﺍﱃ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻓﺎﻥ ﻗﻄﺎﻉ ﺍﻹﻗﻼﻉ ‪ boot sector‬ﳚﺐ ﺃﻥ ﳛﻮﻱ ﻛﺬﻟﻚ ﻋﻠﻰ ﻣﻌﻠﻮﻣﺎﺕ ﺗﺴﺎﻋﺪ ﰲ‬‫ﻭﺻﻒ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ ﻭﻭﺻﻒ ﺍﻟﻘﺮﺹ ﺍﻟﺬﻱ ﺳﻴﺘﻢ ﺍﻻﻗﻼﻉ ﻣﻨﻪ ، ﻫﺬﻩ ﺍﳌﻌﻠﻮﻣﺎﺕ ﲢﻮﻱ ﻣﻌﺮﻑ ‪OEM‬‬‫ﻭﲢﻮﻱ ﺑﻴﺎﻧﺎﺕ ‪) BIOS Parameter Block‬ﲣﺘﺼﺮ ﺏ ‪ (BPB‬ﻭﳚﺐ ﺃﻥ ﺗﺒﺪﺃ ﻛﻞ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻣﻦ ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ‬‫3 ٤. ﻭﺳﻮﻑ ﻳﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﻜﺜﺮﺓ ﺃﺛﻨﺎء ﺗﻄﻮﻳﺮ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻛﺬﻟﻚ ﺃﺣﺪ ﻓﻮﺍﺋﺪ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻫﻮ‬ ‫ﺗﻌﺮﻑ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻋﻠﻰ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ ﰲ ﺍﻟﻘﺮﺹ.‬‫‪Example‬‬ ‫‪٣.٣: Bios Parameter Block‬‬‫١‬‫‪٢ OEM ID‬‬ ‫‪db‬‬ ‫‪"eqraOS‬‬ ‫"‬ ‫‪; Name of your OS, Must‬‬ ‫.‪be 8 byte! no more no less‬‬‫٣‬‫‪٤ bytes per sector‬‬ ‫‪dw‬‬ ‫002‪0x‬‬ ‫.‪; 512 byte per sector‬‬‫‪٥ sectors per cluster‬‬ ‫‪db‬‬ ‫1‪0x‬‬ ‫.‪; 1 sector per cluster‬‬‫‪٦ reserved sectors‬‬ ‫‪dw‬‬ ‫1‪0x‬‬ ‫‪; boot sector is‬‬ ‫.‪reserved‬‬‫‪٧ total fats‬‬ ‫‪db‬‬ ‫2‪0x‬‬ ‫.‪; two fats‬‬‫‪٨ root directory‬‬ ‫‪dw‬‬ ‫0‪0xe‬‬ ‫422 ‪; root dir has‬‬ ‫.‪entries‬‬‫‪٩ total sectors‬‬ ‫‪dw‬‬ ‫04‪0xb‬‬ ‫‪; 2880 sectors in the‬‬ ‫.‪volume‬‬ ‫٤ﳍﺬﺍ ﺍﻟﺴﺒﺐ ﻓﺎﻥ ﺃﻭﻝ ﺗﻌﻠﻴﻤﺔ ﰲ ﺍﳌﺤﻤﻞ ﺳﺘﻜﻮﻥ ﺗﻌﻠﻴﻤﺔ ﺍﻟﻘﻔﺰ ﺍﱃ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﻨﻔﻴﺬﻳﺔ، ﻭﺑﺪﻭﻥ ﺍﻟﻘﻔﺰ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻴﺒﺪﺃ ﺑﺘﻨﻔﻴﺬ ﻫﺬﻩ‬ ‫ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﺎﻋﺘﺒﺎﺭ ﺍ‪‬ﺎ ﺗﻌﻠﻴﻤﺎﺕ ﻭﻫﺬﺍ ﻣﺎ ﻳﺆﺩﻱ ﰲ ﺍﻻﺧﺮ ﺍﱃ ﺳﻘﻮﻁ ﺍﻟﻨﻈﺎﻡ.‬ ‫٠٤‬
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬١٠ media descriptor db 0xf0 ; 1.44 floppy disk.١١ sectors per fat dw 0x9 ; 9 sector per fat.١٢ sectors per track dw 0x12 ; 18 sector per track.١٣ number of heads dw 0x2 ; 2 heads per platter.١٤ hidden sectors dd 0x0 ; no hidden sector.١٥ total sectors large dd 0x0١٦١٧ ; Extended BPB.١٨١٩ drive number db 0x0٢٠ flags db 0x0٢١ signature db 0x29 ; must be 0x28 or 0x29.٢٢ volume id dd 0x0 ; serial number written when foramt the disk.٢٣ volume label db "MOS FLOPPY " ; 11 byte.٢٤ system id db "fat12 " ; 8 byte. .OEM and BPB ‫ﺍﳌﺜﺎﻝ ٤.٣ ﻳﻮﺿﺢ ﺷﻔﺮﺓ ﺍﳌﺤﻤﻞ ﺑﻌﺪ ﺍﺿﺎﻓﺔ ﺑﻴﺎﻧﺎﺕ‬ Example ٣.٤: BPB example١٢ ;Hello Bootloader٣٤ bits 16 ; 16−bit real mode.٥ org 0x0 ; this number will added to all addresses (relocating).٦٧ start:٨ jmp main ; jump over data and function to entry point.٩١٠١١ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٢ ; OEM Id and BIOS Parameter Block (BPB)١٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٤١٥ ; must begin at byte 3(4th byte), if not we should add nop instruction.١٦١٧ OEM ID db "eqraOS " ; Name of your OS, Must be 8 byte! no more no less.١٨٤١
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬١٩ bytes per sector dw 0x200 ; 512 byte per sector.٢٠ sectors per cluster db 0x1 ; 1 sector per cluster.٢١ reserved sectors dw 0x1 ; boot sector is reserved.٢٢ total fats db 0x2 ; two fats.٢٣ root directory dw 0xe0 ; root dir has 224 entries.٢٤ total sectors dw 0xb40 ; 2880 sectors in the volume.٢٥ media descriptor db 0xf0 ; 1.44 floppy disk.٢٦ sectors per fat dw 0x9 ; 9 sector per fat.٢٧ sectors per track dw 0x12 ; 18 sector per track.٢٨ number of heads dw 0x2 ; 2 heads per platter.٢٩ hidden sectors dd 0x0 ; no hidden sector.٣٠ total sectors large dd 0x0٣١٣٢ ; Extended BPB.٣٣٣٤ drive number db 0x0٣٥ flags db 0x0٣٦ signature db 0x29 ; must be 0x28 or 0x29.٣٧ volume id dd 0x0 ; serial number written when foramt the disk.٣٨ volume label db "MOS FLOPPY " ; 11 byte.٣٩ system id db "fat12 " ; 8 byte.٤٠٤١٤٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٣ ; data٤٤ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٥٤٦ hello msg db "Welcome to eqraOS, Coded by Ahmad Essam",0xa,0xd,0٤٧٤٨ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٩ ; puts16: prints string using BIOS interrupt٥٠ ; input:٥١ ; es: pointer to data segment.٥٢ ; si: point to the string٥٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٥٤٥٥ puts16: ٤٢
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬٥٦٥٧ lodsb ; read character from ds:si to al ,and increment si if df=0.٥٨٥٩ cmp al,0 ; check end of string ?٦٠ je end puts16 ; yes jump to end.٦١٦٢ mov ah,0xe ; print character routine number.٦٣ int 0x10 ; call BIOS.٦٤٦٥ jmp puts16 ; continue prints until 0 is found.٦٦٦٧ end puts16:٦٨٦٩ ret٧٠٧١٧٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٧٣ ; entry point of bootloader.٧٤ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٧٥٧٦ main:٧٧٧٨ ;−−−−−−−−−− −−−−−−−−−−−٧٩ ; intit registers٨٠ ;−−−−−−−−−− −−−−−−−−−−−٨١٨٢ ; because bootloader are loaded at 0x07c00 we can refrence this location with many different combination٨٣ ; of segment:offset addressing.٨٤٨٥ ; So we will use either 0x0000:0x7c000 or 0x07c0:0x0000٨٦ ; and in this example we use 0x07c0 for segment and 0x0 for offset.٨٧٨٨ mov ax,0x07c0٨٩ mov ds,ax٩٠ mov es,ax٩١٩٢ mov si,hello msg٩٣ call puts16٤٣
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ٩٤ ٩٥ cli ; clear interrupt. ٩٦ hlt ; halt the system. ٩٧ ٩٨ times 510−($−$$ ) db 0 ; append zeros. ٩٩١٠٠ ; finally the boot signature 0xaa55١٠١ db 0x55١٠٢ db 0xaa ‫ ﺣﻴﺚ ﻛﻤﺎ ﻧﻼﺣﻆ‬Hex Editor ‫ﻭ ﺍﳌﺨﺮﺝ ٥.٣ ﻳﻮﺿﺢ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺴﺎﺑﻘﺔ ﰲ ﺣﺎﻟﺔ ﻋﺮﺿﻬﺎ ﺑﺄﻱ ﳏﺮﺭ ﺳﺎﺩﺱ ﻋﺸﺮ‬ ‫ﺃﻥ ﺑﻴﺎﻧﺎﺕ ﺍﳌﺤﻤﻞ ﻣﺘﺪﺍﺧﻠﺔ ﻣﻊ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﻨﻔﻴﺬﻳﺔ )ﺗﻌﻠﻴﻤﺎﺕ ﺍﳌﻌﺎﰿ( ﻟﺬﻟﻚ ﳚﺐ ﺃﻥ ﻳﺘﻢ ﺍﻟﻘﻔﺰ ﻓﻮﻕ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ‬ .‫ﺎ ﲢﻤﻞ ﺍﻟﺘﻮﻗﻴﻊ ﺍﻟﺼﺤﻴﺢ‬‫ﻔﺬ ﻛﺘﻌﻠﻴﻤﺎﺕ ﺧﺎﻃﺌﺔ ، ﻛﺬﻟﻚ ﳚﺐ ﺍﻟﺘﺄﻛﺪ ﻣﻦ ﺁﺧﺮ ﺑﺎﻳﺘﲔ ﻭﺃ‬‫ﻨ‬ ‫ﺣﱴ ﻻ‬ ‫ﺗ‬ Example ٣.٥: Hex value of bootloader O f f s e t ( h ) 00 01 02 03 04 05 06 07 00000000 E9 72 00 65 71 72 61 4F é r . eqraO 00000008 53 20 20 00 02 01 01 00 S ..... 00000010 02 E0 00 40 0B F0 09 00 . à .@ . . . đ 00000018 12 00 02 00 00 00 00 00 ........ 00000020 00 00 00 00 00 00 29 00 ......). 00000028 00 00 00 4D 4F 53 20 46 . . . MOS F 00000030 4C 4F 50 50 59 20 66 61 LOPPY f a 00000038 74 31 32 20 20 20 57 65 t12 We 00000040 6C 63 6F 6D 65 20 74 6F lcome t o 00000048 20 65 71 72 61 4F 53 2C eqraOS , 00000050 20 43 6F 64 65 64 20 62 Coded b 00000058 79 20 41 68 6D 61 64 20 y Ahmad 00000060 45 73 73 61 6D 0A 0D 00 Essam . . . 00000068 AC 3C 00 74 07 B4 0E CD ¬ <. t . ´ . Í 00000070 10 E9 F4 FF C3 B8 C0 07 . Ăéôÿ¸À . 00000078 8E D8 8E C0 BE 3E 00 E8 .Ø.À¾>.è 00000080 E6 FF FA F4 00 00 00 00 æÿúô . . . . 00000088 00 00 00 00 00 00 00 00 ........ ... ... 000001F0 00 00 00 00 00 00 00 00 ........ ٤٤
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬000001F8 00 00 00 00 00 00 55 AA . . . . . . Uª‫ﻭﳝﻜﻦ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﳌﺤﺮﺭﺍﺕ ﻭﺍﻟﺘﻌﺪﻳﻞ ﺍﳌﺒﺎﺷﺮ ﰲ ﻗﻴﻢ ﺍﳍﻴﻜﺲ ﻟﻠﻤﻠﻒ ﺍﻟﺜﻨﺎﺋﻲ ٥، ﻓﻤﺜﻼ ﳝﻜﻦ ﺣﺬﻑ‬‫ﺍﻟﺘﻮﻗﻴﻊ ﻭﺍﺳﺘﺒﺪﺍﻟﻪ ﺑﺄﻱ ﺭﻗﻢ ﻭﳏﺎﻭﻟﺔ ﺍﻹﻗﻼﻉ ﻣﻦ ﺍﻟﻘﺮﺹ ! ﺑﺎﻟﺘﺄﻛﻴﺪ ﻻ ﳝﻜﻦ ﺍﻻﻗﻼﻉ ﺑﺴﺒﺐ ﺃﻥ ﺍﻟﺒﺎﻳﻮﺱ ﻟﻦ‬‫ﺎﺋﻴﺔ ﻭﻃﺒﺎﻋﺔ ﺍﳉﻤﻠﺔ ﺍﻟﺘﺮﺣﻴﺒﺔ‬ ‫ﻳﺘﻌﺮﻑ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﺑﺄﻧﻪ ﻗﺎﺑﻞ ﻟﻺﻗﻼﻉ ، ﻛﺬﻟﻚ ﻛﻤﺜﺎﻝ ﳝﻜﻦ ﻋﻤﻞ ﺣﻠﻘﺔ ﻻ‬‫ ﻭﺇﺩﺧﺎﻝ‬Disassembler ‫ﰲ ﻛﻞ ﺗﻜﺮﺍﺭ ، ﻭﳚﺐ ﺃﻭﻻ ﺍﻋﺎﺩﺓ ﲡﻤﻴﻊ ﺍﳌﻠﻒ ﺍﻟﺜﻨﺎﺋﻲ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺃﻱ ﻣﻦ ﺑﺮﺍﻣﺞ ﺍﻝ‬ .‫ﺗﻌﻠﻴﻤﺔ ﻗﻔﺰ ﺑﻌﺪ ﺍﺳﺘﺪﻋﺎء ﺩﺍﻟﺔ ﻃﺒﺎﻋﺔ ﺍﻟﺴﻠﺴﻠﺔ ﺍﱃ ﻣﺎ ﻗﺒﻠﻬﺎ‬ Example ٣.٦: Complete Example١ ;Hello Bootloader٢٣ bits 16 ; 16−bit real mode.٤ org 0x0 ; this number will added to all addresses (relocating).٥٦ start:٧ jmp main ; jump over data and function to entry point.٨٩١٠ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١١ ; OEM Id and BIOS Parameter Block (BPB)١٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٣١٤ ; must begin at byte 3(4th byte), if not we should add nop instruction.١٥١٦ OEM ID db "eqraOS " ; Name of your OS, Must be 8 byte! no more no less.١٧١٨ bytes per sector dw 0x200 ; 512 byte per sector.١٩ sectors per cluster db 0x1 ; 1 sector per cluster.٢٠ reserved sectors dw 0x1 ; boot sector is reserved.٢١ total fats db 0x2 ; two fats.٢٢ root directory dw 0xe0 ; root dir has 224 entries.٢٣ total sectors dw 0xb40 ; 2880 sectors in the volume.٢٤ media descriptor db 0xf0 ; 1.44 floppy disk. .source code ‫٥ﰲ ﺣﺎﻟﺔ ﱂ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﻣﻠﻒ ﺍﳌﺼﺪﺭ‬٤٥
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬٢٥ sectors per fat dw 0x9 ; 9 sector per fat.٢٦ sectors per track dw 0x12 ; 18 sector per track.٢٧ number of heads dw 0x2 ; 2 heads per platter.٢٨ hidden sectors dd 0x0 ; no hidden sector.٢٩ total sectors large dd 0x0٣٠٣١ ; Extended BPB.٣٢٣٣ drive number db 0x0٣٤ flags db 0x0٣٥ signature db 0x29 ; must be 0x28 or 0x29.٣٦ volume id dd 0x0 ; serial number written when foramt the disk.٣٧ volume label db "MOS FLOPPY " ; 11 byte.٣٨ system id db "fat12 " ; 8 byte.٣٩٤٠٤١ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٢ ; data٤٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٤٤٥ hello msg db "Welcome to eqraOS, Coded by Ahmad Essam",0xa,0xd,0٤٦٤٧ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٨ ; puts16: prints string using BIOS interrupt٤٩ ; input:٥٠ ; es: pointer to data segment.٥١ ; si: point to the string٥٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٥٣٥٤ puts16:٥٥٥٦ lodsb ; read character from ds:si to al ,and increment si if df=0.٥٧٥٨ cmp al,0 ; check end of string ?٥٩ je end puts16 ; yes jump to end.٦٠٦١ mov ah,0xe ; print character routine number.٦٢ int 0x10 ; call BIOS.٦٣ ٤٦
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ٦٤ jmp puts16 ; continue prints until 0 is found. ٦٥ ٦٦ end puts16: ٦٧ ٦٨ ret ٦٩ ٧٠ ٧١ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ٧٢ ; entry point of bootloader. ٧٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ٧٤ ٧٥ main: ٧٦ ٧٧ ;−−−−−−−−−− −−−−−−−−−−− ٧٨ ; intit registers ٧٩ ;−−−−−−−−−− −−−−−−−−−−− ٨٠ ٨١ ; because bootloader are loaded at 0x07c00 we can refrence this location with many different combination ٨٢ ; of segment:offset addressing. ٨٣ ٨٤ ; So we will use either 0x0000:0x7c000 or 0x07c0:0x0000 ٨٥ ; and in this example we use 0x07c0 for segment and 0x0 for offset. ٨٦ ٨٧ mov ax,0x07c0 ٨٨ mov ds,ax ٨٩ mov es,ax ٩٠ ٩١ mov si,hello msg ٩٢ call puts16 ٩٣ ٩٤ cli ; clear interrupt. ٩٥ hlt ; halt the system. ٩٦ ٩٧ times 510−($−$$ ) db 0 ; append zeros. ٩٨ ٩٩ ; finally the boot signature 0xaa55١٠٠ db 0x55١٠١ db 0xaa ٤٧
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫31‪int 0x‬‬ ‫٣.٤.٣. ﲢﻤﻴﻞ ﻗﻄﺎﻉ ﻣﻦ ﺍﻟﻘﺮﺹ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺍﳌﻘﺎﻃﻌﺔ‬‫ﺑﻌﺪ ﺃﻥ ﰎ ﺗﺸﻐﻴﻞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻟﻌﺮﺽ ﺭﺳﺎﻟﺔ ﺗﺮﺣﻴﺒﺔ ، ﻓﺎﻥ ﻣﻬﻤﺔ ﺍﳌﺤﻤﻞ ﺍﻟﻔﻌﻠﻴﺔ ﻫﻲ ﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﺍﳌﺮﺣﻠﺔ‬‫ﺍﻟﺜﺎﻧﻴﺔ ﻟﻪ ﺣﻴﺚ ﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺳﺎﺑﻘﺎ ﺃﻥ ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺳﺘﻜﻮﻥ ﻋﻠﻰ ﻣﺮﺣﻠﺘﲔ ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺍﻟﻘﻴﻮﺩ ﻋﻠﻰ ﺣﺠﻢ‬‫ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ ، ﻭﺗﻜﻤﻦ ﻭﻇﻴﻔﺔ ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ ﰲ ﺍﻟﺒﺤﺚ ﻋﻦ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ‬‫، ﻭﺑﻌﺪﻫﺎ ﻳﺄﰐ ﺩﻭﺭ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﰲ ﺍﻟﺒﺤﺚ ﻋﻦ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻭﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ. ﻭﺳﻨﺘﻨﺎﻭﻝ ﺍﻻﻥ ﻛﻴﻔﻴﺔ ﲢﻤﻴﻞ‬ ‫ﻣﻘﻄﻊ ﻣﻦ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 31‪. int 0x‬‬ ‫ﺇﻋﺎﺩﺓ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ‬‫ﻋﻨﺪ ﺗﻜﺮﺍﺭ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻓﺎﻧﻪ ﳚﺐ ﰲ ﻛﻞ ﻣﺮﺓ ﺃﻥ ﻧﻌﻴﺪ ﻣﻜﺎﻥ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ﺃﻭﻝ ﻣﻘﻄﻊ ‪sector‬‬‫ﰲ ﺍﻟﻘﺮﺹ ﻭﺫﻟﻚ ﻟﻜﻲ ﻧﻀﻤﻦ ﻋﺪﻡ ﺣﺪﻭﺙ ﻣﺸﺎﻛﻞ، ﻭﺗﺴﺘﺨﺪﻡ ﺍﻟﺪﺍﻟﺔ 0‪ 0x‬ﻣﻦ ﺍﳌﻘﺎﻃﻌﺔ 31‪ int 0x‬ﳍﺬﺍ‬ ‫ﺍﻟﻐﺮﺽ.‬ ‫ﺍﳌﺪﺧﻼﺕ :‬ ‫ﺍﳌﺴﺠﻞ ‪.0x0 : ah‬‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ : dl‬ﺭﻗﻢ ﳏﺮﻙ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻭﻫﻮ 0‪.0x‬‬ ‫•‬ ‫ﺍﻟﻨﺘﻴﺠﺔ:‬ ‫ﺍﳌﺴﺠﻞ ‪ : ah‬ﺍﳊﺎﻟﺔ.‬ ‫•‬ ‫‪ 0x1 : CF‬ﺍﺫﺍ ﺣﺪﺙ ﺧﻄﺄ ، 0‪ 0x‬ﺍﺫﺍ ﲤﺖ ﺍﻟﻌﻤﻠﻴﺔ ﺑﻨﺠﺎﺡ.‬ ‫•‬ ‫ﻣﺜﺎﻝ:‬‫‪Example‬‬ ‫‪٣.٧: Reset Floppy Drive‬‬‫:‪١ reset floppy‬‬‫٢‬‫٣‬ ‫0‪mov ah,0x‬‬ ‫.‪; reset floppy routine number‬‬‫٤‬ ‫0‪mov dl,0x‬‬ ‫‪; drive number‬‬‫٥‬‫٦‬ ‫31‪int 0x‬‬ ‫‪; call BIOS‬‬‫٧‬‫٨‬ ‫‪jc reset floppy‬‬ ‫.‪; try again if error occur‬‬ ‫٨٤‬
    • ‫٣.٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫‪sectors‬‬ ‫ﻗﺮﺍءﺓ ﺍﳌﻘﺎﻃﻊ‬‫ﻟﻘﺮﺍءﺓ ﺍﳌﻘﺎﻃﻊ‬ ‫2‪0x‬‬ ‫ﺍﻟﺪﺍﻟﺔ‬ ‫31‪int 0x‬‬ ‫ﺃﺛﻨﺎء ﺍﻟﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻓﺎﻧﻨﺎ ﺳﻨﺴﺘﺨﺪﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ‬ ‫)‪ (sectors‬ﻣﻦ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ‪. RAM‬‬ ‫ﺍﳌﺪﺧﻼﺕ :‬ ‫• ﺍﳌﺴﺠﻞ ‪ :ah‬ﺍﻟﺪﺍﻟﺔ 2‪0x‬‬ ‫• ﺍﳌﺴﺠﻞ ‪ :al‬ﻋﺪﺩ ﺍﳌﻘﺎﻃﻊ ﺍﻟﱵ ﳚﺐ ﻗﺮﺍﺋﺘﻬﺎ.‬ ‫ﺍﳌﺴﺠﻞ ‪ :ch‬ﺭﻗﻢ ﺍﻻﺳﻄﻮﺍﻧﺔ )‪ ، (Cylinder‬ﺑﺎﻳﺖ ﻭﺍﺣﺪ.‬ ‫•‬‫‪hard‬‬ ‫ﺍﳌﺴﺠﻞ ‪ :cl‬ﺭﻗﻢ ﺍﳌﻘﻄﻊ ، ﻣﻦ ﺍﻟﺒﺖ 0 - 5 ، ﺃﻣﺎ ﺍﺧﺮ ﺑﺘﲔ ﻳﺴﺘﺨﺪﻣﺎﻥ ﻣﻊ ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ‬ ‫•‬ ‫‪.disk‬‬ ‫ﺍﳌﺴﺠﻞ ‪ :dh‬ﺭﻗﻢ ﺍﻟﺮﺃﺱ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ : dl‬ﺭﻗﻢ ﳏﺮﻙ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻭﻫﻮ 0‪.0x‬‬ ‫•‬ ‫ﺍﻟﻌﻨﻮﺍﻥ ‪ : es:bx‬ﻣﺆﺷﺮ ﺍﱃ ﺍﳌﺴﺎﺣﺔ ﺍﻟﱵ ﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﺍﳌﻘﺎﻃﻊ ﺍﻟﻴﻬﺎ.‬ ‫•‬ ‫ﺍﻟﻨﺘﻴﺠﺔ:‬ ‫• ﺍﳌﺴﺠﻞ ‪ : ah‬ﺍﳊﺎﻟﺔ.‬ ‫• ﺍﳌﺴﺠﻞ ‪ :al‬ﻋﺪﺩ ﺍﳌﻘﺎﻃﻊ ﺍﻟﱵ ﰎ ﻗﺮﺍﺋﺘﻬﺎ.‬ ‫‪ 0x1 : CF‬ﺍﺫﺍ ﺣﺪﺙ ﺧﻄﺄ ، 0‪ 0x‬ﺍﺫﺍ ﲤﺖ ﺍﻟﻌﻤﻠﻴﺔ ﺑﻨﺠﺎﺡ.‬ ‫•‬ ‫ﻣﺜﺎﻝ:‬ ‫‪Example‬‬ ‫‪٣.٨: Read Floppy Disk Sectors‬‬‫١‬‫:‪٢ read sectors‬‬‫٣‬‫٤‬ ‫:‪reset floppy‬‬‫٥‬‫٦‬ ‫0‪mov ah,0x‬‬ ‫.‪; reset floppy routine number‬‬‫٧‬ ‫0‪mov dl,0x‬‬ ‫‪; drive number‬‬‫٨‬‫٩‬ ‫31‪int 0x‬‬ ‫‪; call BIOS‬‬‫٠١‬‫١١‬ ‫‪jc reset floppy‬‬ ‫.‪; try again if error occur‬‬‫٩٤‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫٢١‬‫٣١‬ ‫.‪; init buffer‬‬‫٤١‬ ‫0001‪mov ax,0x‬‬‫٥١‬ ‫‪mov es,ax‬‬‫٦١‬ ‫‪xor bx,bx‬‬‫٧١‬‫٨١‬ ‫:‪read‬‬‫٩١‬‫٠٢‬ ‫‪mov‬‬ ‫2‪ah,0x‬‬ ‫.‪; routine number‬‬‫١٢‬ ‫‪mov‬‬ ‫1,‪al‬‬ ‫?‪; how many sectors‬‬‫٢٢‬ ‫‪mov‬‬ ‫1,‪ch‬‬ ‫.‪; cylinder or track number‬‬‫٣٢‬ ‫‪mov‬‬ ‫2,‪cl‬‬ ‫‪; sector number "fisrt sector is 1 not 0",now we read‬‬ ‫.‪the second sector‬‬‫٤٢‬ ‫0,‪mov dh‬‬ ‫."0 ‪; head number "starting with‬‬‫٥٢‬ ‫0,‪mov dl‬‬ ‫.‪; drive number ,floppy drive always zero‬‬‫٦٢‬‫٧٢‬ ‫31‪int 0x‬‬ ‫.‪; call BIOS‬‬‫٨٢‬ ‫‪jc read‬‬ ‫.‪; if error, try again‬‬‫٩٢‬‫٠٣‬ ‫0‪jmp 0x1000:0x‬‬ ‫.‪; jump to execute the second sector‬‬ ‫21‪FAT‬‬ ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬‫ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻫﻮ ﺑﺮﻧﺎﻣﺞ ﻳﺴﺎﻋﺪ ﰲ ﺣﻔﻆ ﺍﳌﻠﻔﺎﺕ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﲝﻴﺚ ﻳﻨﺸﺊ ﻟﻨﺎ ﻣﻔﻬﻮﻡ ﺍﳌﻠﻒ ﻭﺧﺼﺎﺋﺼﻪ ﻭﺍﻟﻌﺪﻳﺪ‬‫ﻣﻦ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﳌﺘﻌﻠﻘﺔ ﺑﻪ ﻣﻦ ﺗﺎﺭﻳﺦ ﺍﻻﻧﺸﺎء ﻭﺍﻟﻮﻗﺖ ، ﻛﺬﻟﻚ ﳛﺘﻔﻆ ﺑﻘﺎﺋﻤﺔ ﲜﻤﻴﻊ ﺍﳌﻠﻔﺎﺕ ﻭﺃﻣﺎﻛﻦ ﺗﻮﺍﺟﺪﻫﺎ‬‫ﰲ ﺍﻟﻘﺮﺹ ، ﺃﻳﻀﴼ ﺃﺣﺪ ﺃﻫﻢ ﻓﻮﺍﺋﺪ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﻫﻲ ﻣﺘﺎﺑﻌﺔ ﺍﻷﻣﺎﻛﻦ ﺍﻟﻐﲑ ﺍﳌﺴﺘﺨﺪﻣﺔ ﰲ ﺍﻟﻘﺮﺹ ﻭﺍﻷﻣﺎﻛﻦ‬‫ﺍﻟﱵ ﺗﻀﺮﺭﺕ ﺑﺴﺒﺐ ﺃﻭ ﻵﺧﺮ ‪ ، bad sectors‬ﻛﺬﻟﻚ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﺍﳉﻴﺪﺓ ﺗﻘﻮﻡ ﺑﻌﻤﻞ ﲡﻤﻴﻊ ﺍﳌﻠﻔﺎﺕ ﺍﳌﺒﻌﺜﺮﺓ‬‫ﻋﻠﻰ ﺍﻟﻘﺮﺹ ‪ Defragmenta on‬ﺣﱴ ﺗﺴﺘﻔﻴﺪ ﻣﻦ ﺍﳌﺴﺎﺣﺎﺕ ﺍﻟﺼﻐﲑﺓ ﺍﻟﱵ ﻇﻬﺮﺕ ﺑﺴﺒﺐ ﺣﺬﻑ ﻣﻠﻒ ﻣﻮﺟﻮﺩ‬‫ﺃﻭ ﲣﺮﻳﻦ ﻣﻠﻒ ﺫﻭ ﺣﺠﻢ ﺃﻗﻞ ﻣﻦ ﺍﳌﺴﺎﺣﺔ ﺍﳋﺎﻟﻴﺔ. ﻭﺑﺪﻭﻥ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﻓﺎﻥ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻟﻘﺮﺹ ﺳﻴﻜﻮﻥ‬‫ﻣﺴﺘﺤﻴﻼ ! ﺣﻴﺚ ﻟﻦ ﻧﻌﺮﻑ ﻣﺎﻫﻲ ﺍﳌﺴﺎﺣﺎﺕ ﺍﻟﻐﲑ ﻣﺴﺘﺨﺪﻣﺔ ﻣﻦ ﺍﻻﺧﺮﻯ ﻭﻟﻦ ﻧﺴﺘﻄﻴﻊ ﺍﻥ ﻧﻘﻮﻡ ﺑﻘﺮﺍءﺓ ﻣﻠﻒ‬ ‫ﻃﻠﺒﻪ ﺍﳌﺴﺘﺨﺪﻡ ﻟﻌﺮﺿﻪ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ !‬ ‫ﻭﺑﺸﻜﻞ ﻋﺎﻡ ﻓﺎﻥ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻳﺘﻜﻮﻥ ﻣﻦ:‬ ‫ﺑﺮﻧﺎﻣﺞ ﻟﻠﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﺍﻟﻘﺮﺹ ﻭﺳﻨﻄﻠﻖ ﻋﻠﻴﻪ ﺍﺳﻢ ﺍﳌﺤﺮﻙ )‪.(Driver‬‬ ‫•‬ ‫ﻭﺟﻮﺩ ﻫﻴﻜﻠﺔ ﺑﻴﺎﻧﺎﺕ ‪ Data Structure‬ﻣﻌﻴﻨﺔ ﻋﻠﻰ ﺍﻟﻘﺮﺹ،ﻳﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﺩﺭﺍﻳﻔﺮ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ.‬ ‫•‬ ‫٠٥‬
    • ‫21‪FAT‬‬ ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬‫ﻭﺣﻴﺚ ﺃﻥ ﺑﺮﳎﺔ ﺑﺮﻧﺎﻣﺞ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﺗﻌﺘﻤﺪ ﻛﻠﻴُ ﻋﻠﻰ ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ، ﻓﺎﻧﻨﺎ ﺳﻨﺒﺪﺃ‬ ‫ﺎ‬‫ﺑﺎﳊﺪﻳﺚ ﻋﻨﻬﺎ ﺃﻭﻻ ﻭﺳﻮﻑ ﻧﺄﺧﺬ ﻧﻈﺎﻡ 21‪ FAT‬ﻋﻠﻰ ﻗﺮﺹ ﻣﺮﻥ ﻛﻤﺜﺎﻝ ، ﻧﻈﺮﴽ ﻟﺒﺴﺎﻃﺔ ﻫﺬﺍ ﺍﻟﻨﻈﺎﻡ ﻭﺧﻠﻮﻩ ﻣﻦ‬ ‫ﺍﻟﺘﻌﻘﻴﺪﺍﺕ.‬ ‫21‪FAT‬‬ ‫٣.٥.١. ﻗﻴﻮﺩ ﻧﻈﺎﻡ‬‫ﻳﻌﺘﱪ ﻧﻈﺎﻡ 21‪ FAT‬ﻣﻦ ﺃﻗﺪﻡ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﻇﻬﻮﺭﴽ ﻭﻗﺪ ﺍﻧﺘﺸﺮ ﺍﺳﺘﺨﺪﺍﻣﻪ ﰲ ﺍﻻﻗﺮﺍﺹ ﺍﳌﺮﻧﺔ ﻣﻨﺬ ﺃﻭﺍﺧﺮ ﺍﻟﺴﺒﻌﻴﻨﺎﺕ‬ ‫، ﻭﻳﻌﻴﺐ ﻧﻈﺎﻡ 21‪: FAT‬‬ ‫ﻋﺪﻡ ﺩﻋﻤﻪ ﻟﻠﻤﺠﻠﺪﺍﺕ ﺍﳍﺮﻣﻴﺔ ﻭﻳﺪﻋﻢ ﻓﻘﻂ ﳎﻠﺪ ﻭﺍﺣﺪ ﻳﺴﻤﻰ ﺍﳉﺬﺭ ‪.Root Directory‬‬ ‫•‬ ‫ﻃﻮﻝ ﺍﻟﻌﻨﻘﻮﺩ )‪ (Cluster‬ﻫﻮ 21 ﺑﺖ ، ﲟﻌﲎ ﺃﻥ ﻋﺪﺩ ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﻫﻲ 212.‬ ‫•‬ ‫ﺃﲰﺎء ﺍﳌﻠﻔﺎﺕ ﻻ ﺗﺰﻳﺪ ﻋﻦ 21 ﺑﺖ.‬ ‫•‬ ‫ﻳﺴﺘﻮﻋﺐ ﻛﺤﺪ ﺃﻗﺼﻰ 7704 ﻣﻠﻒ ﻓﻘﻂ.‬ ‫•‬ ‫23.‬ ‫‪MB‬‬ ‫ﺣﺠﻢ ﺍﻟﻘﺮﺹ ﳛﻔﻆ ﰲ 61 ﺑﺖ ، ﻭﻟﺬﺍ ﻓﺎﻧﻪ ﻻ ﻳﺪﻋﻢ ﺍﻻﻗﺮﺍﺹ ﺍﻟﱵ ﺣﺠﻤﻬﺎ ﻳﺰﻳﺪ ﻋﻦ‬ ‫•‬ ‫‪.(Par‬‬ ‫)‪ons‬‬ ‫ﻳﺴﺘﺨﺪﻡ ﺍﻟﻌﻼﻣﺔ 10‪ 0x‬ﻟﺘﻤﻴﻴﺰ ﺍﻟﺘﻘﺴﻴﻤﺎﺕ ﻋﻠﻰ ﺍﻟﻘﺮﺹ‬ ‫•‬‫ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺃﻧﻨﺎ ﺳﻨﺴﺘﺨﺪﻡ ﻫﺬﺍ ﺍﻟﻨﻈﺎﻡ ﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﻧﻈﺮﴽ ﻟﺒﺴﺎﻃﺘﻪ ، ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻧﻪ ﻗﺪ ﺗﻼﺷﻰ‬ ‫ﺍﺳﺘﺨﺪﺍﻣﻪ ﰲ ﻫﺬﺍ ﺍﻟﺰﻣﻦ ﺍﻻ ﺍﻧﻪ ﻳﻌﺘﱪ ﺃﺳﺎﺱ ﺟﻴﺪ ﻟﻸﻧﻈﻤﺔ ﺍﳌﺘﻘﺪﻣﺔ ﻟﺬﺍ ﻭﺟﺐ ﺩﺭﺍﺳﺘﻪ.‬ ‫٣.٥.٢. ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ 21‪ FAT‬ﻋﻠﻰ ﺍﻟﻘﺮﺹ‬ ‫ﻋﻨﺪ ‪‬ﺌﻴﺔ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ٦ )‪ (Format‬ﺑﻨﻈﺎﻡ 21‪ FAT‬ﻓﺎﻥ ﺗﺮﻛﻴﺒﺔ ﺍﻟﻘﺮﺹ ﺗﻜﻮﻥ ﻋﻠﻰ ﺍﻟﺸﻜﻞ ٣.٢ :‬ ‫ﺷﻜﻞ ٣.٢.: ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ 21‪ FAT‬ﻋﻠﻰ ﺍﻟﻘﺮﺹ‬ ‫٦ﺳﻮﺍءﴽ ﻛﺎﻧﺖ ﺍﻟﺘﻬﺌﻴﺔ ﻣﻦ ﻗﺒﻞ ﺩﺭﺍﻳﻔﺮ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﺍﻟﺬﻱ ﺳﻨﻘﻮﻡ ﺑﱪﳎﺘﻪ ﺃﻭ ﻛﺎﻧﺖ ﻣﻦ ﻗﺒﻞ ﻧﻈﺎﻡ ﺍﻟﺸﺘﻐﻴﻞ ﺍﳌﺴﺘﺨﺪﻡ ﺃﺛﻨﺎء ﻋﻤﻠﻴﺔ‬ ‫ﺍﻟﺘﻄﻮﻳﺮ ، ﻓﻤﺜﻼ ﰲ ﻭﻳﻨﺪﻭﺯ ﳝﻜﻦ ﺇﻋﺎﺩﺓ ‪‬ﺌﻴﺔ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺑﻨﻈﺎﻡ 21‪. FAT‬‬‫١٥‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﻭﺃﻭﻝ ﻣﻘﻄﻊ ﻫﻮ ﻣﻘﻄﻊ ﺍﻻﻗﻼﻉ )‪ (Boot Sector‬ﻭﳛﻮﻱ ﺷﻔﺮﺓ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ )ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ( ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ‬‫ﺑﻴﺎﻧﺎﺕ ﻭﻣﻌﻠﻮﻣﺎﺕ ‪ ، BPB and OEM id‬ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻋﻨﻮﺍﻧﻪ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﻫﻮ : ﺍﳌﻘﻄﻊ 1 ﺍﳌﺴﺎﺭ 0‬‫ﺍﻟﺮﺃﺱ 0 ﻭﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ ﺍﻟﺬﻱ ﳚﺐ ﲤﺮﻳﺮ ﺍﱃ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 31‪ int 0x‬ﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺎﻟﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻘﺮﺹ‬‫ﻛﺬﻟﻚ ﰲ ﺣﺎﻟﺔ ﻣﺎ ﺃﺭﺩﻧﺎ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﻣﺘﺤﻜﻢ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ. ﻭﻧﻈﺮ ﻟﺼﻌﻮﺑﺔ ﻫﺬﻩ ﺍﻟﻌﻨﻮﻧﺔ ﻭﺍﻟﱵ ﺗﻌﺮﻑ‬ ‫ً‬‫ﺏ ‪ Absolute Sector‬ﻓﺎﻥ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﺗﺘﻌﺎﻣﻞ ﻣﻊ ﻧﻈﺎﻡ ﻋﻨﻮﻧﺔ ﳐﺘﻠﻒ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﳏﺘﻮﻳﺎﺕ ﺍﻟﻘﺮﺹ ، ﻓﺒﺪﻻً‬ ‫ﻣﻦ ﺫﻛﺮ ﻛﻞ ﻣﻦ ﺍﳌﻘﻄﻊ ﻭﺍﳌﺴﺎﺭ ﻭﺍﻟﺮﺃﺱ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﻣﻘﻄﻊ ﻣﺎ ﻓﺎﻥ ﻫﺬﻩ ﺍﻟﻌﻨﻮﻧﺔ ﺗﺴﺘﺨﺪﻡ ﻓﻘﻂ ﺭﻗﻢ ﻟﻠﻤﻘﻄﻊ .‬ ‫ﻧﻈﺎﻡ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻟﺬﻱ ﺗﺴﺘﺨﺪﻣﻪ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﻳﺴﻤﻰ ﺑﺎﻟﻌﻨﻮﻧﺔ ﺍﳌﻨﻄﻘﻴﺔ )‪ (Logical Sector Addressing‬ﻭﳜﺘﺼﺮ‬ ‫ﺏ ‪ LBA‬ﻫﻮ ﻧﻈﺎﻡ ﺑﺴﻴﻂ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺗﺮﻗﻴﻢ ﺍﳌﻘﺎﻃﻊ ﺑﺸﻜﻞ ﻣﺘﺴﻠﺴﻞ ﺑﺪﺋﴼ ﻣﻦ ﻣﻘﻄﻊ ﺍﻻﻗﻼﻉ )‪(Boot Sector‬‬ ‫ﻭﺍﻟﺬﻱ ﻳﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ 0 ، ﻭﺍﳌﻘﻄﻊ ﺍﻟﺜﺎﱐ 1 ﻭﻫﻜﺬﺍ ﻫﻠﻢ ﺟﺮﺍ ﺣﱴ ﻧﺼﻞ ﺍﱃ ﺁﺧﺮ ﻣﻘﻄﻊ ﰲ ﺍﻟﻘﺮﺹ. ﻭﲟﺎ ﺃﻧﻪ‬ ‫ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻨﻮﻧﺔ ﺍﳊﻘﻴﻘﺔ ﺑﺪﻻ ﻣﻦ ﺍﳌﻨﻄﻘﻴﺔ ﳊﻈﺔ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻘﺮﺹ )ﺗﺬﻛﺮ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 31‪int 0x‬‬ ‫ﻭﺍﳌﺴﺠﻼﺕ ﺍﻟﱵ ﳚﺐ ﺍﺩﺧﺎﻝ ﻗﻴﻤﻬﺎ( ﻓﺎﻧﻪ ﳚﺐ ﺍﳚﺎﺩ ﻃﺮﻳﻘﺔ ﻟﻠﺘﺤﻮﻳﻞ ﻣﻦ ﺍﻟﻌﻨﻮﻧﺔ ﺍﳊﻘﻴﻘﺔ ﺍﱃ ﺍﳌﻨﻄﻘﻴﺔ -ﺳﻨﻨﺎﻗﺶ‬ ‫ﺍﳌﻮﺿﻮﻉ ﻻﺣﻘﺎ-. ﻧﻨﺘﻘﻞ ﺍﱃ ﺍﳌﻘﻄﻊ ﺍﻟﺘﺎﱄ ﳌﻘﻄﻊ ﺍﻹﻗﻼﻉ ﻭﻫﻮ ﻣﻘﻄﻊ )ﺃﻭ ﻋﺪﺓ ﻣﻘﺎﻃﻊ( ﳝﻜﻦ ﺃﻥ ﳛﺠﺰﻫﺎ ﺍﳌﱪﻣﺞ‬ ‫ﻻﺩﺍء ﺃﻱ ﻭﻇﻴﻔﺔ ﻳﺮﻳﺪﻫﺎ ﻭﺗﺴﻤﻰ ﺍﳌﻘﺎﻃﻊ ﺍﳌﺤﺠﻮﺯﺓ ﺍﻻﺿﺎﻓﻴﺔ ‪ ، Extra Reserved Sectors‬ﻭﺍﳌﻘﺼﻮﺩ ﲟﺤﺠﻮﺯﺓ‬‫ﺃﻱ ﺍﻧﻪ ﻻ ﻳﻮﺟﺪ ﳍﺎ ﻭﺟﻮﺩ ﰲ ﺩﻟﻴﻞ ‪ ، FAT‬ﻭﻣﻘﻄﻊ ﺍﻹﻗﻼﻉ ﻫﻮ ﻣﻘﻄﻊ ﳏﺠﻮﺯ ﺩﺍﺋﻤﺎ ﻟﺬﻟﻚ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﺍﳌﺘﻐﲑ‬ ‫‪ reserved sectors‬ﰲ ﻣﻌﻠﻮﻣﺎﺕ ‪ BPB‬ﻫﻲ ﻭﺍﺣﺪ ، ﻭﰲ ﺣﺎﻟﺔ ﻣﺎ ﺃﺭﺩﺕ ﺣﺠﺰ ﻣﻘﺎﻃﻊ ﺃﺧﺮﻯ ﻛﻞ ﻣﺎ ﻋﻠﻴﻚ‬‫ﻫﻮ ﺯﻳﺎﺩﺓ ﻫﺬﻩ ﺍﻟﻘﻴﻤﺔ ﺑﻌﺪﺩ ﺍﳌﻘﺎﻃﻊ ﺍﳌﺮﻏﻮﺑﺔ ، ﻭﻟﻠﻮﺻﻮﻝ ﺍﱃ ﳏﺘﻮﻳﺎﺕ ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﺍﻻﺿﺎﰲ)ﺍﻥ ﻛﺎﻥ ﻟﻪ ﻭﺟﻮﺩ(‬‫ﻓﺎﻥ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳊﻘﻴﻘﻲ ﻟﻪ ﻫﻮ ﺍﳌﻘﻄﻊ 2 ﺍﳌﺴﺎﺭ 0 ﺍﻟﺮﺃﺱ 0 ، ﺃﻣﺎ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ ﻟﻪ ﻫﻮ ﺍﳌﻘﻄﻊ 1. ﻭﺑﺸﻜﻞ ﻋﺎﻡ‬ ‫ﻓﺎﻧﻪ ﰲ ﺍﻟﻐﺎﻟﺐ ﻻ ﻳﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻊ ﺍﺿﺎﻓﻴﺔ ﺳﻮﻯ ﻣﻘﻄﻊ ﺍﻻﻗﻼﻉ . ﺍﳌﻘﻄﻊ ﺍﻟﺜﺎﻟﺚ ﻫﻮ ﺟﺪﻭﻝ ‪ ، FAT‬ﻭﻫﻮ‬ ‫ﺟﺪﻭﻝ ﳛﻮﻱ ﺳﺠﻼﺕ ﺑﻄﻮﻝ 21 ﺑﺖ ﻋﻦ ﻛﻞ ﻛﻠﺴﺘﺮ )‪ (Cluster‬ﰲ ﺍﻟﻘﺮﺹ ، ﺑﻴﺎﻧﺎﺕ ﻫﺬﺍ ﺍﻟﺴﺠﻞ ﺗﻮﺿﺢ ﻣﺎ‬ ‫ﺍﺫﺍ ﻛﺎﻥ ﺍﻟﻜﻠﺴﺘﺮ ﻗﻴﺪ ﺍﻻﺳﺘﺨﺪﺍﻡ ﺃﻡ ﻻ ، ﻭﻫﻞ ﻫﻮ ﺁﺧﺮ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ﺃﻡ ﻻ ﻭﺇﺫﺍ ﻛﺎﻥ ﻟﻴﺲ ﺑﺎﺧﺮ ﻓﺎﻧﻪ ﻳﻮﺿﺢ‬ ‫ﻟﻨﺎ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻟﺘﺎﱄ ﻟﻠﻤﻠﻒ ، ﻭﻳﻮﺿﺢ ﺍﻟﺸﻜﻞ ﺍﻟﺘﺎﱄ ﺗﺮﻛﻴﺒﺔ ﻫﺬﺍ ﺍﳉﺪﻭﻝ‬‫ﺍﺫﴽ ﻫﺬﺍ ﻭﻇﻴﻔﺔ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻫﻲ ﻣﻌﺮﻓﺔ ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﺍﳋﺎﻟﻴﺔ ﻣﻦ ﻏﲑﻫﺎ ﻛﺬﻟﻚ ﺍﻟﻮﻇﻴﻔﺔ ﺍﻻﺧﺮﻯ ﻫﻲ ﻣﻌﺮﻓﺔ ﲨﻴﻊ‬ ‫ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﳌﻠﻒ ﻣﺎ ﻭﻳﺘﻢ ﺫﻟﻚ ﺑﺎﻟﻨﻈﺮ ﺍﱃ ﻗﻴﻤﺔ ﺍﻟﺴﺠﻞ )ﻗﻴﻤﺔ ﺍﻝ 21 ﺑﺖ( ، ﻭﺍﻟﻘﻴﻢ ﻫﻲ :‬ ‫ﺍﻟﻘﻴﻤﺔ 00‪ :0x‬ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﻟﻜﻠﺴﺘﺮ ﺧﺎﱄ.‬ ‫•‬ ‫ﺍﻟﻘﻴﻤﺔ 10‪ : 0x‬ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﻟﻜﻠﺴﺘﺮ ﳏﺠﻮﺯ.‬ ‫•‬‫ﺍﻟﻘﻴﻢ ﻣﻦ 20‪ 0x‬ﺍﱃ ‪ : 0xfef‬ﺗﺪﻝ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻟﺘﺎﱄ )ﲟﻌﲎ ﺁﺧﺮ ﺃﻥ ﺍﻟﻜﻠﺴﺘﺮ ﳏﺠﻮﺯ ﻭﺗﻮﺟﺪ‬ ‫•‬ ‫ﻛﻠﺴﺘﺮﺍﺕ ﻣﺘﺒﻘﻴﺔ ﻟﻠﻤﻠﻒ(.‬ ‫ﺍﻟﻘﻴﻢ ﻣﻦ 0‪ 0xff‬ﺍﱃ 6‪ :0xff‬ﻗﻴﻢ ﳏﺠﻮﺯﺓ.‬ ‫•‬ ‫ﺍﻟﻘﻴﻤﺔ 6‪ : 0xff‬ﺗﺪﻝ ﻋﻠﻰ ‪.Bad Cluster‬‬ ‫•‬ ‫ﺍﻟﻘﻴﻢ ﻣﻦ 8‪ 0xff‬ﺍﱃ ‪ :0xfff‬ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺍﻻﺧﲑ ﻟﻠﻤﻠﻒ.‬ ‫•‬ ‫٢٥‬
    • ‫21‪FAT‬‬ ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬‫ﻭﳝﻜﻦ ﺍﻟﻨﻈﺮ ﺍﱃ ﺟﺪﻭﻝ ‪ FAT‬ﺑﺄﻧﻪ ﻣﺼﻔﻮﻓﺔ ﻣﻦ ﺍﻟﻘﻴﻢ ﺃﻋﻼﻩ ، ﻭﻋﻨﺪﻣﺎ ﻧﺮﻳﺪ ﲢﻤﻴﻞ ﻣﻠﻒ ﻓﺎﻧﻨﺎ ﺳﻨﺄﰐ ﺑﻌﻨﻮﺍﻥ ﺃﻭﻝ‬‫ﻛﻠﺴﺘﺮ ﻟﻪ ﻣﻦ ﺟﺪﻭﻝ ‪) Root Directory‬ﺳﻨﺄﰐ ﻋﻠﻴﻬﺎ ﻻﺣﻘﺎ( ﻭﺑﻌﺪﻫﺎ ﻧﺴﺘﺨﺪﻡ ﻋﻨﻮﺍﻥ ﺍﻟﻜﻠﺴﺘﺮ ﻙ ‪ index‬ﺍﱃ‬‫ﺟﺪﻭﻝ ‪ FAT‬ﻭﻧﻘﺮﺃ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻘﺎﺑﻠﻪ ﻟﻠﻜﻠﺴﺘﺮ ، ﻓﺎﺫﺍ ﻛﺎﻧﺖ ﺍﻟﻘﻴﻤﺔ ﺑﲔ 20‪ 0x‬ﺍﱃ ‪ 0xfef‬ﻓﺎ‪‬ﺎ ﺗﺪﻝ ﻋﻠﻰ ﺍﻟﻜﻠﺴﺘﺮ‬‫ﺍﻟﺘﺎﱄ ﻟﻠﻤﻠﻒ ، ﻭﻣﻦ ﰒ ﺳﻨﺴﺘﺨﺪﻡ ﻫﺬﻩ ﺍﻟﻘﻴﻤﺔ ﺃﻳﻀﺎ ﻙ ‪ index‬ﻭﻧﻘﺮﺃ ﺍﻟﻘﻴﻤﺔ ﺍﳉﺪﻳﺪﺓ ، ﻭﻧﺴﺘﻤﺮ ﻋﻠﻰ ﻫﺬﺍ ﺍﳊﺎﻝ‬‫ﺍﱃ ﺃﻥ ﻧﻘﺮﺃ ﻗﻴﻤﺔ ﺗﺪﻝ ﻋﻠﻰ ‪‬ﺎﻳﺔ ﺍﳌﻠﻒ. ﻫﺬﺍ ﺍﳉﺪﻭﻝ ‪ FAT‬ﻳﺒﺪﺃ ﻣﻦ ﺍﳌﻘﻄﻊ ﺍﳌﻨﻄﻘﻲ 1 ٧ ﻭﻃﻮﻟﻪ 9 ﻣﻘﺎﻃﻊ ﺃﻱ‬‫ﺃﻥ ‪‬ﺎﻳﺔ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﺗﻜﻮﻥ ﰲ ﺍﳌﻘﻄﻊ ﺗﻜﻮﻥ ﰲ ﺁﺧﺮ ﺍﳌﻘﻄﻊ 01، ﻭﳌﻌﺮﻓﺔ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳊﻘﻴﻘﻲ ﻟﻠﻤﻘﻄﻊ ﻓﺎﻧﻪ ﳝﻜﻦ‬‫ﺍﺳﺘﺨﺪﺍﻡ ﺑﻌﺾ ﺍﳌﻌﺎﺩﻻﺕ ﻟﻠﺘﺤﻮﻳﻞ ، ﻭﺍﻟﻘﺴﻢ ﺍﻟﺘﺎﱄ ﺳﻴﻮﺿﺢ ﺫﻟﻚ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺷﺮﺡ ﻣﺒﺴﻂ ﻋﻦ ﻫﻴﻜﻠﺔ ﺍﻟﻘﺮﺹ‬‫ﺍﳌﺮﻥ ﻭﻛﻴﻔﻴﺔ ﺣﻔﻈﻪ ﻟﻠﺒﻴﺎﻧﺎﺕ . ﻭﺑﻌﺪ ﺟﺪﻭﻝ ‪ FAT‬ﺗﻮﺟﺪ ﻧﺴﺨﺔ ﺃﺧﺮﻯ ﻣﻦ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻭﺗﺴﺘﺨﺪﻡ ﻛﻨﺴﺨﺔ‬‫ﺍﺣﺘﻴﺎﻃﻴﺔ ‪ backup‬ﻭﻫﻲ ﺑﻨﻔﺲ ﺣﺠﻢ ﻭﺧﺼﺎﺋﺺ ﺍﻟﻨﺴﺨﺔ ﺍﻻﻭﱃ ، ﻭﺑﻌﺪﻫﺎ ﻳﺄﰐ ﺩﻟﻴﻞ ﺍﳉﺬﺭ ‪Root Directory‬‬‫ﻭﻫﻮ ﻣﺼﻔﻮﻓﺔ ﻣﻦ 422 ﺳﺠﻞ ﻛﻞ ﺳﺠﻞ ﺑﻄﻮﻝ 23 ﺑﺎﻳﺖ ، ﻭﻇﻴﻔﻴﺔ ﻫﺬﺍ ﺍﻟﺪﻟﻴﻞ ﻫﻲ ﺣﻔﻆ ﺃﲰﺎء ﺍﳌﻠﻔﺎﺕ‬‫ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﻌﻠﻮﻣﺎﺕ ﺍﻟﱵ ﲣﺺ ﻭﻗﺖ ﺍﻻﻧﺸﺎء ﻭﺍﻟﺘﻌﺪﻳﻞ ﻭﺣﺠﻢ ﺍﳌﻠﻒ‬‫ﻭﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ، ﻋﻨﻮﺍﻥ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺃﻫﻢ ﻣﻌﻠﻮﻣﺔ ﻟﻜﻲ ﻧﺴﺘﻄﻴﻊ ﲢﻤﻴﻞ ﺍﳌﻠﻒ ﻛﺎﻣﻼ ، ﺣﻴﺚ ﻛﻤﺎ‬‫ﺫﻛﺮﻧﺎ ﺃﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﺳﻴﻌﻤﻞ ﻙ ‪ index‬ﰲ ﺟﺪﻭﻝ ‪ FAT‬ﻭﺑﻌﺪﻫﺎ ﺳﻨﺤﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻧﺖ ﺗﻮﺟﺪ ﻛﻠﺴﺘﺮﺍﺕ ﺃﺧﺮﻯ‬‫ﳚﺐ ﲢﻤﻴﻠﻬﺎ ﺃﻡ ﺃﻥ ﺍﳌﻠﻒ ﻳﺘﻜﻮﻥ ﻣﻦ ﻛﻠﺴﺘﺮ ﻭﺍﺣﺪ. ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﳏﺘﻮﻳﺎﺕ ﺍﻟﺴﺠﻞ ﺍﻟﻮﺍﺣﺪ ﰲ ﺩﻟﻴﻞ‬ ‫ﺍﻝ ‪ root directory‬ﺑﺪﺍءﴽ ﻣﻦ ﺍﻟﺒﺎﻳﺖ ﺍﻻﻭﻝ ﺍﱃ ﺍﻻﺧﲑ:‬‫ﺍﻟﺒﺎﻳﺘﺎﺕ 0-7: ﺍﺳﻢ ﺍﳌﻠﻒ) ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳊﺠﻢ ﺃﻗﻞ ﻣﻦ 8 ﺑﺎﻳﺖ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺣﺮﻑ ﺍﳌﺴﺎﻓﺔ ﻟﺘﻌﺒﺌﺔ‬ ‫•‬ ‫ﺍﳌﺘﺒﻘﻲ(.‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 8-01: ﺍﻣﺘﺪﺍﺩ ﺍﳌﻠﻒ)ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﺴﺎﻓﺔ ﺃﻳﻀﺎ ﻟﺘﻌﺒﺌﺔ ﺍﳌﺘﺒﻘﻲ(.‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺖ 11: ﺧﺼﺎﺋﺺ ﺍﳌﻠﻒ ﻭﻫﻲ :‬ ‫•‬ ‫– ﺍﻟﺒﺖ 0: ﺍﻟﻘﺮﺍءﺓ ﻓﻘﻂ.‬ ‫– ﺍﻟﺒﺖ 1: ﳐﻔﻲ.‬ ‫– ﺍﻟﺒﺖ 2: ﻣﻠﻒ ﻧﻈﺎﻡ.‬ ‫– ﺍﻟﺒﺖ3: ﺍﺳﻢ ﺍﻟﻘﺮﺹ ‪.Volume Label‬‬ ‫– ﺍﻟﺒﺖ 4: ﺍﳌﻠﻒ ﻫﻮ ﳎﻠﺪ ﻓﺮﻋﻲ.‬ ‫– ﺍﻟﺒﺖ 5: ﺃﺭﺷﻴﻒ.‬ ‫– ﺍﻟﺒﺖ 6: ﺟﻬﺎﺯ.‬ ‫– ﺍﻟﺒﺖ 7: ﻏﲑ ﻣﺴﺘﺨﺪﻡ.‬ ‫ﺍﻟﺒﺎﻳﺖ 21: ﻏﲑ ﻣﺴﺘﺨﺪﻡ.‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺖ 31: ﻭﻗﺖ ﺍﻻﻧﺸﺎء ﺑﻮﺣﺪﺓ ‪.MS‬‬ ‫•‬ ‫٧ﺑﺎﻓﺘﺮﺍﺽ ﺍﻟﻮﺿﻊ ﺍﻟﻐﺎﻟﺐ ﻭﻫﻮ ﻋﺪﻡ ﻭﺟﻮﺩ ﻣﻘﺎﻃﻊ ﺇﺿﺎﻓﻴﺔ ﺑﺎﺳﺘﺜﻨﺎء ﻣﻘﻄﻊ ﺍﻹﻗﻼﻉ‬‫٣٥‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 41-51: ﻭﻗﺖ ﺍﻻﻧﺸﺎء ﺑﺎﻟﺘﺮﺗﻴﺐ ﺍﻟﺘﺎﱄ:‬ ‫•‬ ‫– ﺍﻟﺒﺘﺎﺕ 0-4: ﺍﻟﺜﻮﺍﱐ )0-92(.‬ ‫– ﺍﻟﺒﺘﺎﺕ 5-01: ﺍﻟﺪﻗﺎﺋﻖ )0-95(.‬ ‫– ﺍﻟﺒﺘﺎﺕ 11-51: ﺍﻟﺴﺎﻋﺎﺕ )0-32(.‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 61-71: ﺳﻨﺔ ﺍﻻﻧﺸﺎء ﺑﺎﻟﺘﺮﺗﻴﺐ ﺍﻟﺘﺎﱄ:‬ ‫•‬ ‫– ﺍﻟﺒﺘﺎﺕ 0-4: ﺍﻟﺴﻨﺔ )0=0891; 721=7012(.‬ ‫– ﺍﻟﺒﺘﺎﺕ 5-8: ﺍﻟﺸﻬﺮ )1=ﻳﻨﺎﻳﺮ; 21=ﺩﻳﺴﻤﱪ(.‬ ‫– ﺍﻟﺒﺘﺎﺕ 9-51: ﺍﻟﺴﺎﻋﺔ )0-32(.‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 81-91: ﺗﺎﺭﻳﺦ ﺁﺧﺮ ﺍﺳﺘﺨﺪﺍﻡ )ﺗﺘﺒﻊ ﻧﻔﺲ ﺍﻟﺘﺮﺗﻴﺐ ﺍﻟﺴﺎﺑﻖ(.‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 02-12: ‪.EA index‬‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 22-32: ﻭﻗﺖ ﺁﺧﺮ ﺗﻌﺪﻳﻞ )ﺗﺘﺒﻊ ﻧﻔﺲ ﺗﺮﺗﻴﺐ ﺍﻟﺒﺎﻳﺘﺎﺕ 41-51(.‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 42-52: ﺗﺎﺭﻳﺦ ﺁﺧﺮ ﺗﻌﺪﻳﻞ )ﺗﺘﺒﻊ ﻧﻔﺲ ﺗﺮﺗﻴﺐ ﺍﻟﺒﺎﻳﺘﺎﺕ 61-71(.‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 62-72: ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ.‬ ‫•‬ ‫ﺍﻟﺒﺎﻳﺘﺎﺕ 82-92: ﺣﺠﻢ ﺍﳌﻠﻒ.‬ ‫•‬‫ﻭﳚﺐ ﻣﻼﺣﻈﺔ ﺃﻥ ﺣﺠﻢ ﺍﻟﺴﺠﻼﺕ ﻫﻮ ﺛﺎﺑﺖ ‪ Fixed Lenght Record‬ﻓﻤﺜﻼ ﺍﺳﻢ ﺍﳌﻠﻒ ﳚﺐ ﺍﻥ ﻳﻜﻮﻥ ﺑﻄﻮﻝ‬‫8 ﺑﺎﻳﺖ ﻭﰲ ﺣﺎﻟﺔ ﺯﺍﺩ ﻋﻠﻰ ﺫﻟﻚ ﻓﺎﻥ ﻫﺬﺍ ﺳﻮﻑ ﳛﺪﺙ ﺿﺮﺭﴽ ﻋﻠﻰ ﻫﺬﺍ ﺍﻟﺪﻟﻴﻞ ، ﺃﻳﻀﺎ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﻻﺳﻢ‬ ‫ﲝﺠﻢ ﺃﻗﻞ ﻣﻦ ﺍﳌﻄﻠﻮﺏ ﻓﺎﻧﻪ ﳚﺐ ﺗﻜﻠﻤﺔ ﺍﻟﻌﺪﺩ ﺍﻟﻨﺎﻗﺺ ﻣﻦ ﺍﳊﺮﻭﻑ ﲝﺮﻑ ﺍﳌﺴﺎﻓﺔ ‪.Space‬‬ ‫٣.٥.٣. ﻫﻴﻜﻠﺔ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ‬‫ﻳﺘﻜﻮﻥ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻣﻦ ﻗﺮﺹ ‪) Pla er‬ﺃﻭ ﻋﺪﺓ ﺃﻗﺮﺍﺹ( ﻣﻘﺴﻤﺔ ﺍﱃ ﻣﺴﺎﺭﺍﺕ )‪ (Tracks‬ﻭﻛﻞ ﻣﻦ ﻫﺬﻩ ﺍﳌﺴﺎﺭﺍﺕ‬‫ﻳﺘﻜﻮﻥ ﻣﻦ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﻘﻄﺎﻋﺎﺕ ﻭﻳﻮﺟﺪ ﻋﺎﺩﺓ ﺭﺃﺳﲔ ﻟﻠﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻰ ﻛﻞ ﻗﺮﺹ. ﻭﰲ ﺍﻻﻗﺮﺍﺹ ﺍﳌﺮﻧﺔ‬‫ﺫﺍﺕ ﺍﳊﺠﻢ ‪ 1.44 MB‬ﻳﻮﺟﺪ 08 ﻣﺴﺎﺭﴽ )ﻣﻦ ﺍﳌﺴﺎﺭ 0 ﺍﱃ ﺍﳌﺴﺎﺭ 97( ﻭﻛﻞ ﻣﺴﺎﺭ ﻳﺘﻜﻮﻥ ﻣﻦ 81 ﻗﻄﺎﻉ‬ ‫، ﻭﺑﺎﻟﺘﺎﱄ ﻓﺎﻥ ﻋﺪﺩ ﺍﻟﻘﻄﺎﻋﺎﺕ ﺍﻟﻜﻠﻴﺔ ﻫﻲ 2 ∗ 81 ∗ 08 ﻭﺗﺴﺎﻭﻱ 0882 ﻗﻄﺎﻋﴼ.‬‫ﻭﻟﺘﺨﺰﻳﻦ ﺑﻴﺎﻧﺎﺕ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﻓﺎﻧﻪ ﳚﺐ ﲢﺪﻳﺪ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳊﻘﻴﻘﻲ ﻭﺍﻟﺬﻱ ﻳﺘﻜﻮﻥ ﻣﻦ ﻋﻨﻮﺍﻥ ﺍﻟﻘﻄﺎﻉ ﻭﺍﳌﺴﺎﺭ‬‫ﻭﺍﻟﺮﺃﺱ ، ﻭﺃﻭﻝ ﻗﻄﺎﻉ ﰲ ﺍﻟﻘﺮﺹ )ﻗﻄﺎﻉ ﺍﻻﻗﻼﻉ( ﻳﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ: ﺍﻟﻘﻄﺎﻉ 1 ﺍﳌﺴﺎﺭ 0 ﺍﻟﺮﺃﺱ 0 ، ﻭﺍﻟﻘﻄﺎﻉ‬‫ﺍﻟﺜﺎﱐ ﻳﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ: ﺍﻟﻘﻄﺎﻉ 2 ﺍﳌﺴﺎﺭ 0 ﺍﻟﺮﺃﺱ 0 ، ﻭﻫﻜﺬﺍ ﻳﺴﺘﻤﺮ ﻧﻈﺎﻡ ﺍﻟﺘﺨﺰﻳﻦ ﰲ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺍﱃ ﺃﻥ‬‫ﻳﺼﻞ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 81 ﺍﳌﺴﺎﺭ 0 ﺍﻟﺮﺃﺱ 0 ﻭﻫﻮ ﻋﻨﻮﺍﻥ ﺁﺧﺮ ﻗﻄﺎﻉ ﻋﻠﻰ ﺍﳌﺴﺎﺭ ﺍﻻﻭﻝ ﻭﺍﻟﺮﺃﺱ ﺍﻻﻭﻝ ، ﻭﺳﻴﺘﻢ‬‫ﺣﻔﻆ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﺘﺎﻟﻴﺔ ﰲ ﺍﻟﺮﺃﺱ ﺍﻟﺜﺎﱐ ﻋﻠﻰ ﺍﻟﻌﻨﻮﺍﻥ: ﺍﻟﻘﻄﺎﻉ 1 ﺍﳌﺴﺎﺭ 0 ﺍﻟﺮﺃﺱ 1 ﻭﻳﺴﺘﻤﺮ ﺍﱃ ﺃﻥ ﻳﺼﻞ ﺍﱃ ﺁﺧﺮ‬‫ﻗﻄﺎﻉ ﰲ ﻫﺬﺍ ﺍﳌﺴﺎﺭ ﻋﻠﻰ ﺍﻟﺮﺃﺱ ﺍﻟﺜﺎﱐ، ﻭﺑﻌﺪﻫﺎ ﺳﻴﺘﻢ ﺣﻔﻆ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﺘﺎﻟﻴﺔ ﰲ ﺍﻟﺮﺃﺱ ﺍﻻﻭﻝ ﺍﳌﺴﺎﺭ ﺍﻟﺜﺎﱐ ...‬ ‫،ﻭﻫﻜﺬﺍ.‬ ‫٤٥‬
    • ‫21‪FAT‬‬ ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬ ‫21‪FAT‬‬ ‫٣.٥.٤. ﺍﻟﻘﺮﺍءﺓ ﻭ ﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﻧﻈﺎﻡ‬‫21‪FAT‬‬ ‫ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ )ﻗﺮﺍءﺓ ﻭﻛﺘﺎﺑﺔ ﺍﻟﻘﻄﺎﻋﺎﺕ( ﻓﺎﻧﻪ ﻳﻠﺰﻣﻨﺎ ﺑﺮﳎﺔ ﺩﺭﺍﻳﻔﺮ ﻟﻨﻈﺎﻡ‬‫ﻭﺍﻟﺬﻱ ﺳﻴﻌﻤﻞ ﻛﻮﺳﻴﻂ ﺑﲔ ﺍﳌﺴﺘﺨﺪﻡ ﻭﺑﲔ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ، ﲟﻌﲎ ﺃﻥ ﺃﻱ ﻃﻠﺐ ﻟﻘﺮﺍءﺓ ﻣﻠﻒ ﻣﺎ ﳚﺐ ﺃﻥ ﺗﺬﻫﺐ‬‫ﺃﻭﻻ ﺍﱃ ﻧﻈﺎﻡ 21‪ FAT‬ﺣﻴﺚ ﺳﻴﻘﺮﺭ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻠﻒ ﻣﻮﺟﻮﺩﴽ ﺃﻡ ﻻ )ﻋﻦ ﻃﺮﻳﻖ ﺍﻟﺒﺤﺚ ﰲ ﺩﻟﻴﻞ ‪Root‬‬‫‪ (directory‬ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻣﻮﺟﻮﺩﴽ ﺳﻴﻌﻮﺩ ﻟﻨﺎ ﲜﻤﻴﻊ ﺧﺼﺎﺋﺺ ﺍﳌﻠﻒ ﻭﺭﻗﻢ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻪ ﻟﻜﻲ ﻧﺘﻤﻜﻦ ﻣﻦ‬‫ﲢﻤﻴﻞ ﺍﳌﻠﻒ ﻛﺎﻣ ً ، ﻭﻧﻔﺲ ﺍﳌﺒﺪﺃ ﰲ ﺣﺎﻟﺔ ﻃﻠﺐ ﺍﳌﺴﺘﺨﺪﻡ ﻛﺘﺎﺑﺔ ﻣﻠﻒ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﻓﺎﻥ ﺩﺭﺍﻳﻔﺮ ﻧﻈﺎﻡ 21‪FAT‬‬ ‫ﻼ‬‫ﺳﻴﺒﺤﺚ ﰲ ﺟﺪﻭﻝ ‪ FAT‬ﻋﻦ ﻣﺴﺎﺣﺔ ﺧﺎﻟﻴﺔ ﻣﻨﺎﺳﺒﺔ ﻟﻠﻤﻠﻒ ﻭﺫﻟﻚ ﺑﺎﺗﺒﺎﻉ ﺃﺣﺪ ﺍﳋﻮﺭﺍﺯﻣﻴﺎﺕ ﺍﳌﻌﺮﻭﻓﺔ ﻭﺑﻌﺪﻫﺎ‬ ‫ﺳﻴﺘﻢ ﺣﻔﻆ ﺍﳌﻠﻒ ﻭﻛﺘﺎﺑﺔ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﳌﺘﻌﻠﻘﺔ ﺑﻪ ﰲ ﺩﻟﻴﻞ ‪. Root directory‬‬‫ﻭﺳﻨﺄﺧﺬ ﻣﺜﺎﻝ ﻋﻠﻰ ﺍﳌﻮﺿﻮﻉ ﻭﺫﻟﻚ ﺑﱪﳎﺔ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ‪Second Stage Bootloader‬‬‫ﻭﺳﺘﻘﺘﺼﺮ ﻭﻇﻴﻔﺘﻪ ﺣﺎﻟﻴﴼ ﰲ ﻃﺒﺎﻋﺔ ﺭﺳﺎﻟﺔ ﺗﺮﺣﻴﺒﺔ ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻧﻪ ﰎ ﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﺑﻨﺠﺎﺡ ، ﻭﰲ‬ ‫ﺍﻷﻗﺴﺎﻡ ﺍﻟﺘﺎﻟﻴﺔ ﺳﻨﺒﺪﺃ ﰲ ﺗﻄﻮﻳﺮ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻭﲡﻬﻴﺰ ﻣﺮﺣﻠﺔ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺑﻴﺌﺔ 23 ﺑﺖ.‬‫ﻣﻬﻤﺔ ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ ﺳﺘﺘﻐﲑ ﻋﻦ ﻣﺎ ﺳﺒﻖ ، ﺣﻴﺚ ﺍﻻﻥ ﳚﺐ ﻋﻠﻰ ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ ﺃﻥ ﺗﻘﻮﻡ ﺑﺎﻟﺒﺤﺚ ﻋﻦ ﺍﳌﺮﺣﻠﺔ‬ ‫ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ، ﻭﻳﺘﻢ ﻫﺬﺍ ﻭﻓﻖ ﺍﳋﻄﻮﺍﺕ ﺍﻟﺘﺎﻟﻴﺔ:‬‫١. ﲢﻤﻴﻞ ﺟﺪﻭﻝ ‪ Root Directory‬ﻣﻦ ﺍﻟﻘﺮﺹ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻣﻦ ﰒ ﺍﻟﺒﺤﺚ ﻋﻦ ﻣﻠﻒ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻭﺃﺧﺬ‬ ‫ﺭﻗﻢ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻪ.‬ ‫٢. ﲢﻤﻴﻞ ﺟﺪﻭﻝ ‪ FAT‬ﻣﻦ ﺍﻟﻘﺮﺹ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻣﻦ ﰒ ﲢﻤﻴﻞ ﲨﻴﻊ ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﻟﻠﻤﻠﻒ.‬ ‫٣. ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺃﻭﻝ ﺑﺎﻳﺖ ﰲ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.‬ ‫ﺇﻧﺸﺎء ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﺑﺪﺍﻳﺔ ﺳﻨﻘﻮﻡ ﺑﺈﻧﺸﺎء ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﻧﺴﺨﻬﺎ ﺍﱃ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ، ﻭﻧﻈﺮﴽ ﻻﻥ ﺗﻄﻮﻳﺮ ﻧﻈﺎﻣﻨﺎ ﺍﳋﺎﺹ‬‫ﳚﺐ ﺍﻥ ﻳﺘﻢ ﲢﺖ ﻧﻈﺎﻡ ﺁﺧﺮ ﻓﺎﻥ ﻫﺬﺍ ﺍﻟﻨﻈﺎﻡ ﺍﻵﺧﺮ ﻏﺎﻟﺒﺎ ﻣﺎ ﳛﻮﻱ ﺩﺭﺍﻳﻔﺮ ﻟﻨﻈﺎﻡ ﻣﻠﻔﺎﺕ 21‪ FAT‬ﺣﻴﺚ ﻳﺘﻜﻔﻞ‬‫ﺑﻌﻤﻠﻴﺔ ﻛﺘﺎﺑﺔ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﱃ ﺟﺪﻭﻝ ‪ Root Directory‬ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺍﻟﺒﺤﺚ ﻋﻦ ﻛﻠﺴﺘﺮﺍﺕ ﺧﺎﻟﻴﺔ ﰲ ﺟﺪﻭﻝ ‪FAT‬‬‫ﺩﻭﻥ ﺃﻱ ﺗﺪﺧﻞ ﻣﻦ ﻗﺒﻞ ﻣﻄﻮﺭ ﺍﻟﻨﻈﺎﻡ ﺍﳉﺪﻳﺪ، ﻟﺬﻟﻚ ﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﻣﻦ ﺍﻟﺘﻄﻮﻳﺮ ﺳﻨﺘﺠﺎﻫﻞ ﺟﺰﺋﻴﺔ ﺍﻟﻜﺘﺎﺑﺔ ﰲ‬‫ﻧﻈﺎﻡ 21‪ FAT‬ﻭﻧﺘﺮﻙ ﺍﳌﻬﻤﺔ ﻟﻨﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺍﻟﺬﻱ ﻧﻌﺘﻤﺪ ﻋﻠﻴﻪ ﰲ ﻋﻤﻠﻴﺔ ﺗﻄﻮﻳﺮ ﺍﻟﻨﻈﺎﻡ ﺍﳉﺪﻳﺪ ، ﻭ‪‬ﺬﺍ ﺳﻴﻜﻮﻥ‬‫ﺍﻟﺪﺭﺍﻳﻔﺮ ﺍﻟﺬﻱ ﺳﻨﻨﺸﺌﻪ ﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﻣﺎ ﻫﻮ ﺍﻻ ﺟﺰء ﻣﻦ ﺍﻟﺪﺭﺍﻳﻔﺮ ﺍﻟﻜﺎﻣﻞ ﺍﻟﺬﻱ ﺳﻴﺘﻢ ﺗﻜﻠﻤﺘﻪ ﻻﺣﻘﺎ ﲟﺸﻴﺌﺔ‬ ‫ﺍﷲ.ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻣﺜﺎﻝ ﻟﻠﻤﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﺍﳌﺤﻤﻞ ﻟﻌﺮﺽ ﺭﺳﺎﻟﺔ ﺑﺴﻴﻄﺔ.‬‫‪Example‬‬ ‫2‪٣.٩: Hello Stage‬‬‫١‬ ‫.‪; Second Stage Bootloader‬‬‫٢‬ ‫.)00500‪; loaded by stage1.bin at address 0x050:0x0 (0x‬‬‫٣‬‫٥٥‬
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬٤٥ bits 16 ; 16−bit real mode.٦ org 0x0 ; offset to zero.٧٨ start: jmp stage2٩١٠١١ ; data and variable١٢ hello msg db "Welcome to eqraOS Stage2",0xa,0xd,0١٣١٤ ; include files:١٥ %include "stdio.inc" ; standard i/o routines.١٦١٧١٨١٩٢٠ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢١ ; entry point of stage2 bootloader.٢٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٣٢٤ stage2:٢٥٢٦ push cs٢٧ pop ds ; ds = cs.٢٨٢٩ mov si,hello msg٣٠ call puts16٣١٣٢ cli ; clear interrupt.٣٣ hlt ; halt the system.stage2.sys ‫ ﺃﻣﺎ ﺍﳌﻠﻒ ﺍﻟﻨﺎﺗﺞ ﻣﻦ ﻋﻤﻠﻴﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺳﻴﻜﻮﻥ ﺑﺎﻻﺳﻢ‬stage2.asm ‫ﻭﺳﻴﺘﻢ ﺗﺴﻤﻴﺔ ﺍﳌﻠﻒ ﺑﺎﻻﺳﻢ‬‫ﻭﳝﻜﻦ ﺗﺴﻤﻴﺘﻪ ﺑﺄﻱ ﺍﺳﻢ ﺍﺧﺮ ﺑﺸﺮﻁ ﺃﻥ ﻻ ﻳﺰﻳﺪ ﺍﻻﺳﻢ ﻋﻦ 8 ﺣﺮﻭﻑ ﻭﺍﻻﻣﺘﺪﺍﺩ ﻋﻦ 3 ﺣﺮﻭﻑ ، ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ‬.Root Directory ‫ ﺣﱴ ﻻ ﻳﺘﻀﺮﺭ ﺟﺪﻭﻝ‬Spaces ‫ ﺳﻴﻘﻮﻡ ﺑﺎﺿﺎﻓﺔ ﻣﺴﺎﻓﺎﺕ‬FAT12 ‫ﻃﻮﻝ ﺍﻻﺳﻢ ﺃﻗﻞ ﻓﺎﻥ ﺩﺭﺍﻳﻔﺮ‬(FAT12 ‫ﻭﳝﻜﻨﻨﺎ ﺃﻥ ﻧﻔﺮﻕ ﺑﲔ ﺍﲰﺎء ﺍﳌﻠﻔﺎﺕ ﺍﻟﺪﺍﺧﻠﻴﺔ )ﻭﻫﻲ ﺍﻟﱵ ﻳﺘﻢ ﺍﺿﺎﻓﺔ ﻣﺴﺎﻓﺎﺕ ﻋﻠﻴﻬﺎ ﻭﻳﺴﺘﺨﺪﻣﻬﺎ ﻧﻈﺎﻡ‬ .(‫ﻭﺍﻷﲰﺎء ﺍﳋﺎﺭﺟﻴﺔ )ﻭﻫﻲ ﺍﻟﱵ ﻳﻨﺸﺌﻬﺎ ﺍﳌﺴﺘﺨﺪﻡ‬ ٥٦
    • FAT12 ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬ ‫ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ‬Root Directory ‫ﲢﻤﻴﻞ ﺍﻝ‬‫ ﳛﻮﻱ ﺃﲰﺎء ﻛﻞ ﺍﳌﻠﻔﺎﺕ ﻭ ﺃﻣﺎﻛﻦ ﺗﻮﺍﺟﺪﻫﺎ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﻟﺬﺍ ﳚﺐ ﲢﻤﻴﻠﻪ ﺃﻭﻻ ﻭﺍﻟﺒﺤﺚ‬Root Directory ‫ﺟﺪﻭﻝ‬‫( ﻭﻋﻨﺪ ﺍﻟﺒﺤﺚ ﳚﺐ ﺍﻟﺒﺤﺚ ﺑﺎﻻﺳﻢ ﺍﻟﺪﺍﺧﻠﻲ ﺍﻟﺬﻱ‬stage2.sys ‫ﻋﻦ ﻣﻠﻒ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ )ﺫﻭ ﺍﻻﺳﻢ ﺍﳋﺎﺭﺟﻲ‬.‫" ، ﻭﻧﺄﰐ ﺑﺮﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻷﻭﻝ ﻟﻠﻤﻠﻒ‬stage2 sys" ‫ﻳﺴﺘﺨﺪﻣﻪ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻟﺬﻟﻚ ﳚﺐ ﺃﻥ ﻧﺒﺤﺚ ﻋﻦ ﺍﳌﻠﻒ‬‫ﻭﻗﺒﻞ ﲢﻤﻴﻞ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻓﺎﻧﻪ ﳚﺐ ﻋﻠﻴﻨﺎ ﺃﻭﻻﹰ ﻣﻌﺮﻓﺔ ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻗﻄﺎﻉ ﻓﻴﻪ ﻭﺣﺴﺎﺏ ﻋﺪﺩ ﺍﻟﻘﻄﺎﻋﺎﺕ ﺍﻟﱵ ﻳﺸﻐﻠﻬﺎ‬‫( ﻟﻜﻲ ﻳﺘﻢ ﻧﻘﻞ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﺍﻟﻴﻬﺎ. ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ‬Buffer) ‫ﻫﺬﺍ ﺍﳉﺪﻭﻝ ، ﻛﺬﻟﻚ ﳚﺐ ﲢﺪﻳﺪ ﺍﳌﺴﺎﺣﺔ ﺍﳋﺎﻟﻴﺔ‬ .‫ﺗﻮﺿﺢ ﻛﻴﻔﻴﺔ ﻋﻤﻞ ﺫﻟﻚ‬ Example ٣.١٠: Load Root directory١ ;−−−−−−−−−−−−−− −−−−−−−−−−−−−−−٢ ; Compute Root Directory Size٣ ;−−−−−−−−−−−−−− −−−−−−−−−−−−−−−٤٥ xor cx,cx٦ mov ax,32 ; every root entry size are 32 byte.٧ mul word[root directory] ; dx:ax = 32∗224 bytes٨ div word[bytes per sector]٩ xchg ax,cx ; cx = number of sectors to load.١٠١١ ;−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−−١٢ ; Get start sector of root directory١٣ ;−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−−١٤١٥ mov al,byte[total fats] ; there are 2 fats.١٦ mul word[sectors per fat] ; 9∗2 sectors١٧ add ax,word[reserved sectors] ; ax = start sector of root directory.١٨١٩ mov word[data region],ax٢٠ add word[data region],cx ; data region = start sector of data.٢١٢٢٢٣ ;−−−−−−−−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−−−٢٤ ; Load Root Dir at 0x07c0:0x0200 above bootloader.٢٥ ;−−−−−−−−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−−−٢٦٢٧ mov bx,0x0200 ; es:bs = 0x07c0:0x0200.٢٨ call read sectors٥٧
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﺑﻌﺪ ﲢﻤﻴﻞ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﳚﺐ ﺍﻟﺒﺤﺚ ﻓﻴﻪ ﻋﻦ ﺍﺳﻢ ﻣﻠﻒ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﻣﻦ ﰒ ﺣﻔﻆ ﺭﻗﻢ ﺃﻭﻝ‬‫ﻛﻠﺴﺘﺮ ﻟﻪ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳌﻠﻒ ﻣﻮﺟﻮﺩﴽ ، ﺃﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻠﻒ ﻏﲑ ﻣﻮﺟﻮﺩ ﻓﻨﺼﺪﺭ ﺭﺳﺎﻟﺔ ﺧﻄﺄ ﻭﻧﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ‬ .‫ﻋﻦ ﺍﻟﻌﻤﻞ. ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﺫﻟﻚ‬ Example ٣.١١: Find Stage2 Bootloader١ ;−−−−−−−−− −−−−−−−−−−٢ ; Find stage2.sys٣ ;−−−−−−−−− −−−−−−−−−−٤٥ mov di,0x0200 ; di point to first entry in root dir.٦ mov cx,word[root directory] ; loop 224 time.٧٨ find stage2:٩١٠ mov si,kernel loader name١١ push cx١٢ push di١٣ mov cx,11 ; file name are 11 char long.١٤١٥ rep cmpsb١٦ pop di١٧ je find successfully١٨١٩ mov di,32 ; point to next entry.٢٠ pop cx٢١٢٢ loop find stage2٢٣٢٤ ; no found ?٢٥ jmp find fail٢٦٢٧ find successfully:٢٨ ;−−−−−−−−−− −−−−−−−−−−−٢٩ ; Get first Cluster.٣٠ ;−−−−−−−−−− −−−−−−−−−−−٣١٣٢ mov ax,word[di+26] ; 27 byte in the di entry are cluster number.٣٣ mov word[cluster number],ax ٥٨
    • ‫21‪FAT‬‬ ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬ ‫ﲢﻤﻴﻞ ﺟﺪﻭﻝ ‪ FAT‬ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺟﺪﻭﻝ ‪ FAT‬ﻳﻮﺿﺢ ﺣﺎﻟﺔ ﻛﻞ ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﺳﻮﺍءﺍ ﻛﺎﻧﺖ ﺧﺎﻟﻴﺔ ﺃﻡ ﻣﻌﻄﻮﺑﺔ ﺃﻡ ﺍ‪‬ﺎ‬‫ﻣﺴﺘﺨﺪﻣﺔ ، ﻭﳚﺐ ﲢﻤﻴﻞ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻲ ﻧﺴﺘﻄﻴﻊ ﻋﻦ ﻃﺮﻳﻖ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻟﺬﻱ ﲢﺼﻠﻨﺎ ﻋﻠﻴﻪ‬‫ﻣﻦ ﺟﺪﻭﻝ ‪ Root Directory‬ﺃﻥ ﳓﻤﻞ ﲨﻴﻊ ﻛﻠﺴﺘﺮﺍﺕ ﺍﳌﻠﻒ. ﻭﺑﻨﻔﺲ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﱵ ﻗﻤﻨﺎ ‪‬ﺎ ﻟﺘﺤﻤﻴﻞ ﺟﺪﻭﻝ‬‫‪ Root Directory‬ﺳﻴﺘﻢ ‪‬ﺎ ﲢﻤﻴﻞ ﺟﺪﻭﻝ ‪ FAT‬ﺣﻴﺚ ﳚﺐ ﲢﺪﺩ ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻗﻄﺎﻉ ﻟﻠﺠﺪﻭﻝ ﻭ ﻋﺪﺩ ﺍﻟﻘﻄﺎﻋﺎﺕ‬‫ﺍﻟﱵ ﻳﺸﻐﻠﻬﺎ ﺍﳉﺪﻭﻝ ، ﻭﻛﺬﻟﻚ ﺍﳌﺴﺎﺣﺔ ﺍﳋﺎﻟﻴﺔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻲ ﻳﺘﻢ ﺣﻔﻆ ﺍﳊﺪﻭﻝ ‪‬ﺎ . ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ‬ ‫ﺫﻟﻚ.‬ ‫‪Example‬‬ ‫‪٣.١٢: Load FAT Table‬‬‫١‬ ‫−−−−−−−−−−;‬ ‫−−−−−−−−−−−‬‫٢‬ ‫‪; Compute FAT size‬‬‫٣‬ ‫−−−−−−−−−−;‬ ‫−−−−−−−−−−−‬‫٤‬‫٥‬ ‫‪xor cx,cx‬‬‫٦‬ ‫‪xor ax,ax‬‬‫٧‬ ‫‪xor dx,dx‬‬‫٨‬‫٩‬ ‫]‪mov al,byte[total fats‬‬ ‫.‪; there are 2 fats‬‬‫٠١‬ ‫]‪mul word[sectors per fat‬‬ ‫‪; 9∗2 sectors‬‬‫١١‬ ‫‪xchg ax,cx‬‬‫٢١‬‫٣١‬ ‫−−−−−−−−−−−−;‬ ‫−−−−−−−−−−−−−‬‫٤١‬ ‫‪; Get start sector of FAT‬‬‫٥١‬ ‫−−−−−−−−−−−−;‬ ‫−−−−−−−−−−−−−‬‫٦١‬‫٧١‬ ‫]‪add ax,word[reserved sectors‬‬‫٨١‬‫٩١‬ ‫−−−−−−−−−−−−−−−−−−−−−−−−−−−;‬ ‫−−−−−−−−−−−−−−−−−−−−−−−−−−−‬‫٠٢‬ ‫0020‪; Load FAT at 0x07c0:0x‬‬‫١٢‬ ‫.‪; Overwrite Root dir with FAT, no need to Root Dir now‬‬‫٢٢‬ ‫−−−−−−−−−−−−−−−−−−−−−−−−−−−;‬ ‫−−−−−−−−−−−−−−−−−−−−−−−−−−−‬‫٣٢‬‫٤٢‬ ‫0020‪mov bx,0x‬‬‫٥٢‬ ‫‪call read sectors‬‬‫٩٥‬
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬ ‫ﲢﻤﻴﻞ ﻛﻠﺴﺘﺮﺍﺕ ﺍﳌﻠﻒ‬‫ﻭﺣﺪﺓ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻟﻠﻘﺮﺹ ﺍﳌﺮﻥ ﻫﻲ ﺑﺎﻟﻘﻄﺎﻉ ‪ Sector‬ﻟﻜﻦ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ 21‪ FAT‬ﻳﺘﻌﺎﻣﻞ ﻣﻊ ﳎﻤﻮﻋﺔ ﻣﻦ‬‫ﺍﻟﻘﻄﺎﻋﺎﺕ ﻛﻜﺘﻠﺔ ﻭﺍﺣﺪﺓ ‪ ،Cluster‬ﻭﻛﻠﻤﺎ ﻛﱪ ﺣﺠﻢ ﺍﻟﻜﻠﺴﺘﺮ ﺯﺍﺩﺕ ﺍﳌﺴﺎﺣﺎﺕ ﺍﳋﺎﻟﻴﺔ ﺑﺪﺍﺧﻠﻪ ‪Internel‬‬‫‪ Fragmenta on‬ﻟﺬﻟﻚ ﳚﺐ ﺍﺧﺘﻴﺎﺭ ﺣﺠﻢ ﻣﻼﺋﻢ ، ﻭﰲ ﺗﻨﻔﻴﺬ ﻧﻈﺎﻡ 21‪ FAT‬ﻋﻠﻰ ﻗﺮﺹ ﻣﺮﻥ ﺃﺧﺘﺮﻧﺎ ﺃﻥ ﻛﻞ‬‫ﻛﻠﺴﺘﺮ ﻳﻘﺎﺑﻞ ﻗﻄﺎﻉ ﻭﺍﺣﺪ ﻓﻘﻂ ﻣﻦ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ. ﺍﳌﺸﻜﻠﺔ ﺍﻟﱵ ﺳﺘﻮﺍﺟﻬﻨﺎ ﻫﻲ ﻛﻴﻔﻴﺔ ﻗﺮﺍءﺓ ﻛﻠﺴﺘﺮ ﻣﻦ ﺍﻟﻘﺮﺹ‬‫، ﻓﺎﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻻ ﻳﻘﺮﺃ ﺍﻱ ﻗﻄﺎﻉ ﺍﻻ ﺑﺘﺤﺪﻳﺪ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻖ ﻟﻪ ‪ Absolute Address‬ﻭﻟﺬﻟﻚ ﳚﺐ ﲢﻮﻳﻞ ﺭﻗﻢ‬ ‫ﺍﻟﻜﻠﺴﺘﺮ ﺍﱃ ﻋﻨﻮﺍﻥ ﻣﻄﻠﻖ ﻭﲢﻮﻳﻞ ﻋﻨﻮﺍﻥ ‪ LBA‬ﺃﻳﻀﺎ ﺍﱃ ﻋﻨﻮﺍﻥ ﻣﻄﻠﻖ.‬ ‫ﺍﻟﺘﺤﻮﻳﻞ ﻣﻦ ﺭﻗﻢ ‪ Cluster‬ﺍﱃ ﻋﻨﻮﺍﻥ ‪ LBA‬ﻳﺘﻢ ﻛﺎﻻﰐ:‬ ‫‪Example‬‬ ‫‪٣.١٣: Convert Cluster number to LBA‬‬‫; ١‬ ‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗‬‫‪٢ ; cluster to lba: convert cluster number to LBA‬‬‫; ٣‬ ‫:‪input‬‬‫; ٤‬ ‫.‪ax: Cluster number‬‬‫:‪٥ ; output‬‬‫; ٦‬ ‫.‪ax: lba number‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٧‬‫:‪٨ cluster to lba‬‬‫٩‬‫٠١‬ ‫‪; lba = (cluster − 2)∗ sectors per cluster‬‬‫١١‬ ‫.2 ‪; the first cluster is always‬‬‫٢١‬‫٣١‬ ‫2,‪sub ax‬‬‫٤١‬‫٥١‬ ‫‪xor cx,cx‬‬‫٦١‬ ‫]‪mov cl, byte[sectors per cluster‬‬‫٧١‬ ‫‪mul cx‬‬‫٨١‬‫٩١‬ ‫]‪add ax,word[data region‬‬ ‫.‪; cluster start from data area‬‬‫٠٢‬ ‫‪ret‬‬‫ﺣﻴﺚ ﻳﺘﻢ ﻃﺮﺡ ﺍﻟﻌﺪﺩ 2 ﻣﻦ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻭﻫﺬﺍ ﺑﺴﺒﺐ ﺃﻥ ﺃﻭﻝ ﺭﻗﻢ ﻛﻠﺴﺘﺮ ﰲ ﻧﻈﺎﻡ 21‪ FAT‬ﻫﻮ 2 - ﻛﻤﺎ‬ ‫ﺳﻨﺮﻯ ﺫﻟﻚ ﻻﺣﻘﺎ-.‬ ‫ﻭﻟﻠﺘﺤﻮﻳﻞ ﻣﻦ ﻋﻨﻮﺍﻥ ‪ LBA‬ﺍﱃ ﻋﻨﻮﺍﻥ ‪: Absolute Address‬‬ ‫‪Example‬‬ ‫‪٣.١٤: Convert LBA to CHS‬‬‫; ١‬ ‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗‬‫.‪٢ ; lba to chs: Convert LBA to CHS‬‬ ‫٠٦‬
    • FAT12 ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬٣ ; input:٤ ; ax: LBA.٥ ; output:٦ ; absolute sector٧ ; absolute track٨ ; absolute head٩ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١٠ lba to chs:١١١٢ ; absolute sector = (lba % sectors per track) + 1١٣ ; absolute track = (lba / sectors per track) / number of heads١٤ ; absolute head = (lba / sectors per track) % number of heads١٥١٦ xor dx,dx١٧ div word[sectors per track]١٨ inc dl١٩ mov byte[absolute sector],dl٢٠٢١ xor dx,dx٢٢ div word[number of heads]٢٣ mov byte[absolute track],al٢٤ mov byte[absolute head],dl٢٥٢٦ ret‫ﻭﺑﻌﺪ ﺫﻟﻚ ﻧﻘﻮﻡ‬ Root Directory ‫ﻭﻟﺘﺤﻤﻴﻞ ﻛﻠﺴﺘﺮ ﻣﻦ ﺍﻟﻘﺮﺹ ﳚﺐ ﺃﻭﻻ ﺍﳊﺼﻮﻝ ﻋﻠﻰ ﺭﻗﻤﻪ ﻣﻦ ﺟﺪﻭﻝ‬Abolsute Address ‫ ﺍﱃ ﻋﻨﻮﺍﻥ ﻣﻄﻠﻖ‬LBA ‫ ﻭﺑﻌﺪﻫﺎ ﻧﻘﻮﻡ ﺑﺘﺤﻮﻳﻞ ﻋﻨﻮﺍﻥ‬LBA ‫ﺑﺘﺤﻮﻳﻞ ﻫﺬﺍ ﺍﻟﺮﻗﻢ ﺍﱃ ﻋﻨﻮﺍﻥ‬.‫ ﻟﻘﺮﺍءﺓ ﺍﻟﻘﻄﺎﻋﺎﺕ ﻣﻦ ﺍﻟﻘﺮﺹ، ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﺫﻟﻚ‬int 0x13 ‫ﻭﻣﻦ ﰒ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ‬ Example ٣.١٥: Load Cluster١ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−٢ ; Load all clusters(stage2.sys)٣ ; At address 0x050:0x0٤ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−٥٦ xor bx,bx٧ mov ax,0x0050٨ mov es,ax٩١٠ load cluster:٦١
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬١١١٢ mov ax,word[cluster number] ; ax = cluster number١٣ call cluster to lba ; convert cluster number to LBA addressing.١٤١٥ xor cx,cx١٦ mov cl,byte[sectors per cluster] ; cx = 1 sector١٧١٨ call read sectors bios ; load cluster.‫ ﻭﻫﻲ ﺗﻌﻤﻞ ﻓﻘﻂ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ‬int 0x13 ‫ﻭﺩﺍﻟﺔ ﻗﺮﺍءﺓ ﺍﻟﻘﻄﺎﻋﺎﺕ ﻣﻦ ﺍﻟﻘﺮﺹ ﺗﺴﺘﺨﺪﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ‬ .32-bit ‫ﻭﳚﺐ ﺍﺳﺘﺒﺪﺍﳍﺎ ﻻﺣﻘﺎ ﻋﻨﺪ ﺍﻟﺘﺤﻮﻳﻞ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺑﺪﺍﻟﺔ ﺍﺧﺮﻯ‬ Example ٣.١٦: Read Sectors Rou ne١ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢ ; read sectors bios: load sector from floppy disk٣ ; input:٤ ; es:bx : Buffer to load sector.٥ ; ax: first sector number ,LBA.٦ ; cx: number of sectors.٧ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٨ read sectors bios:٩١٠ begin:١١ mov di,5 ; try 5 times to load any sector.١٢١٣ load sector:١٤١٥ push ax١٦ push bx١٧ push cx١٨١٩ call lba to chs٢٠٢١ mov ah,0x2 ; load sector routine number.٢٢ mov al,0x1 ; 1 sector to read.٢٣ mov ch,byte[absolute track] ; absolute track number.٢٤ mov cl,byte[absolute sector] ; absolute sector number.٢٥ mov dh,byte[absolute head] ; absolute head number.٢٦ mov dl,byte[drive number] ; floppy drive number. ٦٢
    • FAT12 ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬٢٧٢٨ int 0x13 ; call BIOS.٢٩٣٠ jnc continue ; if no error jmp.٣١٣٢ ; reset the floppy and try read again.٣٣٣٤ mov ah,0x0 ; reset routine number.٣٥ mov dl,0x0 ; floppy drive number.٣٦ int 0x13 ; call BIOS.٣٧٣٨ pop cx٣٩ pop bx٤٠ pop ax٤١٤٢ dec di٤٣ jne load sector٤٤٤٥ ; error.٤٦ int 0x18٤٧٤٨ continue:٤٩٥٠ mov si,progress msg٥١ call puts16٥٢٥٣ pop cx٥٤ pop bx٥٥ pop ax٥٦٥٧ add ax,1 ; next sector٥٨ add bx,word[bytes per sector] ; point to next empty block in buffer.٥٩٦٠٦١ loop begin ; cx time٦٢٦٣ ret‫ ﻭﻗﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ‬FAT ‫ﻭﻟﺘﺤﻤﻴﻞ ﺑﻘﻴﺔ ﻛﻠﺴﺘﺮﺍﺕ ﺍﳌﻠﻒ ﳚﺐ ﺃﺧﺬ ﺭﻗﻢ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ﻭﺍﻟﺬﻫﺎﺏ ﺑﻪ ﺍﱃ ﺟﺪﻭﻝ‬٦٣
    • ‫‪Bootloader‬‬ ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﺍﳌﻘﺎﺑﻠﺔ ﻟﻪ ﻭﺍﻟﱵ ﺳﺘﺪﻝ ﻋﻠﻰ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﻫﺬﺍ ﺁﺧﺮ ﻛﻠﺴﺘﺮ ﺃﻡ ﺃﻥ ﻫﻨﺎﻟﻚ ﻛﻠﺴﺘﺮﺍﺕ ﺍﺧﺮﻯ ﳚﺐ ﲢﻤﻴﻠﻬﺎ.ﻭﻳﻠﺰﻡ‬‫ﺍﻷﺧﺬ ﺑﺎﻻﻋﺘﺒﺎﺭ ﺑﻨﻴﺔ ﺟﺪﻭﻝ ‪ FAT‬ﻭﺍﻧﻪ ﻳﺘﻜﻮﻥ ﻣﻦ ﺳﺠﻼﺕ ﺑﻄﻮﻝ 21 ﺑﺖ ﻭﺗﻌﺎﺩﻝ ﺑﺎﻳﺖ ﻭﻧﺼﻒ ، ﺃﻱ ﺃﻧﻪ ﺍﺫﺍ‬‫ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ 0 ﻓﺎﻧﻨﺎ ﳚﺐ ﺃﻥ ﻧﻘﺮﺃ ﺍﻟﺴﺠﻞ ﺍﻻﻭﻝ ﻣﻦ ﺟﺪﻭﻝ ‪ FAT‬ﻭﺑﺴﺒﺐ ﺍﻧﻪ ﻻ ﳝﻜﻦ ﻗﺮﺍءﺓ 21‬‫ﺑﺖ ﻓﺴﻮﻑ ﺗﺘﻢ ﻗﺮﺍءﺓ 61 ﺑﺖ )ﺍﻟﺴﺠﻞ ﺍﻻﻭﻝ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﻧﺼﻒ ﺍﻟﺴﺠﻞ ﺍﻟﺜﺎﱐ( ﻭﻋﻤﻞ ‪ mask‬ﻻﺧﺮ 4 ﺑﺖ‬‫)ﻻﺯﺍﻟﺔ ﻣﺎ ﰎ ﻗﺮﺍﺋﺘﻪ ﻣﻦ ﺍﻟﺴﺠﻞ ﺍﻟﺜﺎﱐ(. ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ 1 ﻓﻴﺠﺐ ﻗﺮﺍءﺓ ﺍﻟﺴﺠﻞ ﺍﻟﺜﺎﱐ ﻣﻦ‬‫ﺟﺪﻭﻝ ‪ FAT‬ﻭﺍﻟﺬﻱ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﺒﺖ 21-32 ﻭﺑﺴﺒﺐ ﺃﻧﻪ ﻻ ﳝﻜﻦ ﻗﺮﺍءﺓ 21 ﺑﺖ ﺳﻨﻘﻮﻡ ﺑﻘﺮﺍءﺓ 61 ﺑﺖ ﺃﻱ ﻣﻦ‬ ‫ﺍﻟﺒﺖ 8-32 ﻭﺍﺯﺍﻟﺔ ﺃﻭﻝ 4 ﺑﺖ.‬ ‫ﻭﺑﺎﺧﺘﺼﺎﺭ، ﻟﻘﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻘﺎﺑﻠﺔ ﻟﺮﻗﻢ ﻛﻠﺴﺘﺮ ﻣﺎ ﻓﻴﺠﺐ ﺃﻭﻻ ﺗﻄﺒﻴﻖ ﺍﻟﻘﺎﻧﻮﻥ :‬ ‫)2/‪cluster = cluster + (cluster‬‬‫ﻭﻗﺮﺍءﺓ 61 ﺑﺖ ، ﻭﰲ ﺣﺎﻟﺔ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺭﻗﻢ ﺯﻭﺟﻲ ﻓﻴﺠﺐ ﻋﻤﻞ ‪ Mask‬ﻻﺧﺮ 4 ﺑﺖ ، ﺃﻣﺎ‬‫ﺍﺫﺍ ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻓﺮﺩﻱ ﻓﻴﺠﺐ ﺍﺯﺍﻟﺔ ﺃﻭﻝ 4 ﺑﺖ . ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻛﻴﻔﻴﺔ ﲢﻤﻴﻞ ﲨﻴﻊ ﻛﻠﺴﺘﺮﺍﺕ‬ ‫ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ .‬ ‫‪Example‬‬ ‫‪٣.١٧: Read FAT entry‬‬‫١‬ ‫:‪read cluster fat entry‬‬‫٢‬‫٣‬ ‫]‪mov ax,word[cluster number‬‬‫٤‬‫٥‬ ‫;‬ ‫.)‪Every FAT entry are 12−bit long( byte and half one‬‬‫٦‬ ‫;‬ ‫.‪so we must map the cluster number to this entry‬‬‫٧‬ ‫;‬ ‫.]0[‪to read cluster 0 we need to read fat‬‬‫٨‬ ‫;‬ ‫.]1[‪cluster 1 −> fat‬‬‫٩‬ ‫;‬ ‫.‪cluster 2 −> fat[3],...etc‬‬‫٠١‬‫١١‬ ‫‪mov‬‬ ‫‪cx,ax‬‬ ‫.‪; cx = cluster number‬‬‫٢١‬ ‫‪shr‬‬ ‫1,‪cx‬‬ ‫.2 ‪; divide cx by‬‬‫٣١‬ ‫‪add‬‬ ‫‪cx,ax‬‬ ‫.)2/‪; cx = ax + (ax‬‬‫٤١‬ ‫‪mov‬‬ ‫‪di,cx‬‬‫٥١‬ ‫‪add‬‬ ‫0020‪di,0x‬‬‫٦١‬ ‫‪mov‬‬ ‫.‪dx,word[di] ; read 16−bit form FAT‬‬‫٧١‬‫٨١‬‫٩١‬ ‫4 ‪; Now, because FAT entry are 12−bit long, we should remove‬‬ ‫.‪bits‬‬‫٠٢‬ ‫‪; if the cluster number are even, we must mask the last four‬‬ ‫.‪bits‬‬‫١٢‬ ‫.‪; if it odd, we must do four right shift‬‬ ‫٤٦‬
    • FAT12 ‫٣.٥. ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ‬٢٢٢٣ test ax,1٢٤ jne odd cluster٢٥٢٦ even cluster:٢٧٢٨ and dx,0x0fff٢٩ jmp next cluster٣٠٣١ odd cluster:٣٢٣٣ shr dx,4٣٤٣٥٣٦ next cluster:٣٧ mov word[cluster number],dx ; next cluster to load.٣٨٣٩ cmp dx,0x0ff0 ; check end of file, last cluster?٤٠ jb load cluster ; no, load the next cluster.٤١٤٢٤٣ ; yes jmp to end٤٤ jmp end of first stage٤٥٤٦ find fail:٤٧٤٨ mov si,fail msg٤٩ call puts16٥٠٥١ mov ah,0x0٥٢ int 0x16 ; wait keypress.٥٣ int 0x19 ; warm boot.٥٤٥٥٥٦ end of first stage:٥٧٥٨ ; jump to stage2 and begin execute.٥٩ push 0x050 ; segment number.٦٠ push 0x0 ; offset number.٦١٦٢ retf ; cs:ip = 0x050:0x0٦٥
    • Bootloader ‫٣. ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ‬٦٣٦٤ times 510−($−$$ ) db 0 ; append zeros.٦٥٦٦ ; finally the boot signature 0xaa55٦٧ db 0x55٦٨ db 0xaa ٦٦
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫ﺑﺴﺒﺐ ﺍﻟﻘﻴﻮﺩ ﻋﻠﻰ ﺣﺠﻢ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻓﺎﻥ ﻫﺬﺍ ﻗﺪ ﺃﺩﻯ ﺍﱃ ﺗﻘﺴﻴﻢ ﺍﳌﻬﻤﺔ ﺍﱃ ﻣﺮﺣﻠﺘﲔ ﺣﻴﺚ ﺍﻗﺘﺼﺮﺕ ﻣﻬﻤﺔ‬‫ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ ﻋﻠﻰ ﲢﻤﻴﻞ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﺍﳌﺤﻤﻞ ، ﺃﻣﺎ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ 2 ‪ stage‬ﻓﻼ ﻗﻴﻮﺩ ﻋﻠﻴﻬﺎ ﻭﻏﺎﻟﺒﺎ ﻣﺎ ﻳﺘﻢ‬ ‫ﺗﻨﻔﻴﺬ ﺍﳌﻬﻤﺎﺕ ﺍﻟﺘﺎﻟﻴﺔ ﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ:‬ ‫ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‪.PMode‬‬ ‫•‬ ‫ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ 02‪ A‬ﻟﺪﻋﻢ ﺫﺍﻛﺮﺓ ﺣﱴ 4 ﺟﻴﺠﺎ ﺑﺎﻳﺖ.‬ ‫•‬ ‫ﺗﻮﻓﲑ ﺩﻭﺍﻝ ﻟﻠﺘﻌﺎﻣﻞ ﻣﻊ ﺍﳌﻘﺎﻃﻌﺎﺕ ‪.Interrupt Handler‬‬ ‫•‬ ‫ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﻭﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ.‬ ‫•‬ ‫ﺗﻮﻓﲑ ﺧﺼﺎﺋﺺ ﺃﺛﻨﺎء ﺍﻹﻗﻼﻉ ﻣﺜﻞ ‪.Safe Mode‬‬ ‫•‬ ‫‪ Mul‬ﻭﺫﻟﻚ ﻋﱪ ﻣﻠﻔﺎﺕ ﺍﻟﺘﻬﻴﺌﺔ.‬ ‫‪Boot‬‬ ‫ﺩﻋﻢ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ‬ ‫•‬ ‫٤.١. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬‫ﺍﳌﺸﻜﻠﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ‪ Real Mode‬ﻫﻲ ﻋﺪﻡ ﺗﻮﻓﺮ ﲪﺎﻳﺔ ﻟﻠﺬﺍﻛﺮﺓ ﺣﻴﺚ ﳝﻜﻦ ﻷﻱ ﺑﺮﻧﺎﻣﺞ ﻳﻌﻤﻞ‬‫ﺃﻥ ﻳﺼﻞ ﻷﻱ ﺟﺰء ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ، ﻛﺬﻟﻚ ﺃﻗﺼﻰ ﺣﺠﻢ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﻟﻪ ﻫﻮ 1 ﻣﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ، ﻭﻻ ﻳﻮﺟﺪ‬ ‫ﺩﻋﻢ ﻟﺘﻘﻨﻴﺔ ‪ Paging‬ﻭﻻ ﻟﻠﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ ‪ Virtual Memory‬ﺣﱴ ﺗﻌﺪﺩ ﺍﻟﱪﺍﻣﺞ ﻻ ﻳﻮﺟﺪ ﺩﻋﻢ ﻟﻪ.‬‫ﻛﻞ ﻫﺬﻩ ﺍﳌﺸﺎﻛﻞ ﰎ ﺣﻠﻬﺎ ﺑﺎﺿﺎﻓﺔ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺍﱃ ﺍﳌﻌﺎﰿ ﻭﳝﻜﻦ ﺍﻻﻧﺘﻘﺎﻝ ﺑﺴﻬﻮﻟﺔ ﺍﱃ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻋﻦ‬‫ﻃﺮﻳﻖ ﺗﻔﻌﻴﻞ ﺍﻟﺒﺖ ﺍﻻﻭﻝ ﰲ ﺍﳌﺴﺠﻞ 0‪ ، cr‬ﻭﻟﻜﻦ ﺑﺴﺒﺐ ﺃﻥ ﺍﳌﻌﺎﰿ ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻳﺴﺘﺨﺪﻡ ﻃﺮﻳﻘﺔ ﻋﻨﻮﻧﺔ‬‫ﻟﻠﺬﺍﻛﺮﺓ ﲣﺘﻠﻒ ﻋﻦ ﺍﻟﻄﺮﻳﻘﺔ ﺍﳌﺴﺘﺨﺪﻣﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻓﺎﻧﻪ ﳚﺐ ﲡﻬﻴﺰ ﺑﻌﺾ ﺍﳉﺪﺍﻭﻝ ﺗﺴﻤﻰ ﺟﺪﺍﻭﻝ‬‫ﺍﻟﻮﺍﺻﻔﺎﺕ ‪ Descriptor Table‬ﻭﺑﺪﻭﻥ ﲡﻬﻴﺰ ﻫﺬﻩ ﺍﳉﺪﺍﻭﻝ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻴﺼﺪﺭ ﺍﺳﺘﺜﻨﺎء ‪General Protec on‬‬ ‫‪ Fault‬ﻭﺍﺧﺘﺼﺎﺭﴽ ‪ GPF‬ﻭﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻳﺆﺩﻱ ﺍﱃ ﺣﺪﻭﺙ ‪ triple fault‬ﻭﺗﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ.‬‫ﺃﺣﺪ ﻫﺬﻩ ﺍﳉﺪﺍﻭﻝ ﻭﻳﺴﻤﻰ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ )‪ (Global Descriptor Table‬ﻭﺍﺧﺘﺼﺎﺭﴽ ‪ GDT‬ﻭﻇﻴﻔﺘﻪ‬‫ﺍﻻﺳﺎﺳﻴﺔ ﻫﻲ ﺗﻌﺮﻳﻒ ﻛﻴﻔﻴﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﺬﺍﻛﺮﺓ ، ﺣﻴﺚ ﳛﺪﺩ ﻣﺎ ﻫﻮ ﺍﻟﻘﺴﻢ ﺍﻟﺬﻱ ﺳﻴﻨﻔﺬ ﻛﺸﻔﺮﺓ ؟ ﻭﻣﺎ ﻫﻮ‬‫ﺍﻟﻘﺴﻢ ﺍﻟﺬﻱ ﳚﺐ ﺃﻥ ﳛﻮﻱ ﺑﻴﺎﻧﺎﺕ ؟ ﻭﳛﺪﺩ ﺃﻳﻀﺎ ﺑﺪﺍﻳﺔ ﻭ‪‬ﺎﻳﺔ ﻛﻞ ﻗﺴﻢ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺻﻼﺣﻴﺔ ﺍﻟﻮﺻﻮﻝ ﺍﱃ‬ ‫ﺫﻟﻚ ﺍﻟﻘﺴﻢ.‬‫٧٦‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬ ‫‪Global Descriptor Table‬‬ ‫٤.١.١. ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ‬‫‪GDT‬‬ ‫ﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ‪ PMode‬ﻓﺎﻥ ﺃﻱ ﻋﻤﻠﻴﺔ ﻭﺻﻮﻝ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺗﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﻫﺬﺍ ﺍﳉﺪﻭﻝ‬‫، ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﻌﻤﻞ ﻋﻠﻰ ﲪﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺫﻟﻚ ﺑﻔﺤﺺ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﺮﺍﺩ ﺍﻟﻮﺻﻮﻝ ﺍﻟﻴﻪ ﻭﺍﻟﺘﺄﻛﺪ ﻣﻦ ﻋﺪﻡ ﳐﺎﻟﻔﺘﻪ‬‫ﻟﺒﻴﺎﻧﺎﺕ ﻫﺬﺍ ﺍﳉﺪﻭﻝ.ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﲢﺪﺩ ﺍﻟﻘﺴﻢ ﺍﻟﺬﻱ ﳝﻜﻦ ﺃﻥ ﻳﻨﻔﺬ ﻛﺸﻔﺮﺓ )‪ (Code‬ﻭﺍﻟﻘﺴﻢ ﺍﻟﺬﻱ ﻻ ﻳﻨﻔﺬ‬ ‫)‪ (Data‬ﻛﺬﻟﻚ ﲢﺪﺩ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﻛﻤﺎ ﺳﻨﺮﺍﻫﺎ ﺍﻻﻥ.‬ ‫ﻭﻋﺎﺩﺓ ﻳﺘﻜﻮﻥ ﺟﺪﻭﻝ ‪ GDT‬ﻣﻦ ﺛﻼﺙ ﻭﺍﺻﻔﺎﺕ ‪) Descriptors‬ﺣﺠﻢ ﻛ ٌ ﻣﻨﻬﺎ ﻫﻮ 46 ﺑﺖ( ﻭﻫﻢ:‬ ‫ﻞ‬ ‫‪ :Null Descriptor‬ﺗﻜﻮﻥ ﻓﺎﺭﻏﺔ ﰲ ﺍﻟﻌﺎﺩﺓ.‬ ‫•‬ ‫‪ :Code Descriptor‬ﺗﺼﻒ ﺧﺼﺎﺋﺺ ﺍﳌﻘﻄﻊ ﺃﻭ ﺍﻟﻘﺴﻢ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﻳﻨﻔﺬ ﻛﺸﻔﺮﺓ ‪.Code‬‬ ‫•‬‫‪ :Data Descriptor‬ﺗﺼﻒ ﺧﺼﺎﺋﺺ ﺍﳌﻘﻄﻊ ﺃﻭ ﺍﻟﻘﺴﻢ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﻻ ﻳﻨﻔﺬ ﻭﳛﻮﻱ ﺑﻴﺎﻧﺎﺕ ‪.Data‬‬ ‫•‬ ‫ﺑﻴﺎﻧﺎﺕ ﺃﻱ ﻭﺍﺻﻔﺔ ‪ Descriptor‬ﺗﺄﺧﺬ ﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ:‬ ‫ﺍﻟﺒﺘﺎﺕ 0-51: ﲢﻮﻱ ﺃﻭﻝ ﺑﺎﻳﺘﲔ )ﻣﻦ ﺑﺖ 0 -51( ﻣﻦ ﺣﺠﻢ ﺍﳌﻘﻄﻊ.‬ ‫•‬ ‫ﺍﻟﺒﺘﺎﺕ 61-93: ﲢﻮﻱ ﺃﻭﻝ ﺛﻼﺙ ﺑﺎﻳﺘﺎﺕ ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ‪.Base Address‬‬ ‫•‬ ‫ﺍﻟﺒﺖ 04: ﺑﺖ ﺍﻟﻮﺻﻮﻝ ‪) Access Bit‬ﻳﺴﺘﺨﺪﻡ ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ ‪.(Virtual Memory‬‬ ‫•‬ ‫ﺍﻟﺒﺘﺎﺕ 34-14: ﻧﻮﻉ ﺍﻟﻮﺍﺻﻔﺔ ‪:Descriptor Type‬‬ ‫•‬ ‫– ﺍﻟﺒﺖ 14: ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ:‬ ‫∗ ‪ :Data Descriptor‬ﺍﻟﻘﻴﻤﺔ 0 ﻟﻠﻘﺮﺍءﺓ ﻓﻘﻂ ﻭﺍﻟﻘﻴﻤﺔ 1 ﻟﻠﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ.‬ ‫∗ ‪ :Code Descriptor‬ﺍﻟﻘﻴﻤﺔ 0 ﻟﻠﺘﻨﻔﻴﺬ ﻓﻘﻂ ‪ execute‬ﻭﺍﻟﻘﻴﻤﺔ 1 ﻟﻠﻘﺮﺍءﺓ ﻭﺍﻟﺘﻨﻔﻴﺬ.‬ ‫– ﺍﻟﺒﺖ 24: )‪.Expansion direc on (Data segments), conforming (Code Segments‬‬ ‫– ﺍﻟﺒﺖ 34: ﻗﺎﺑﻠﻴﺔ ﺍﻟﺘﻨﻔﻴﺬ:‬ ‫∗ 0: ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ ﻋﺒﺎﺭﺓ ﻋﻦ ﺑﻴﺎﻧﺎﺕ.‬ ‫∗ 1: ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ ﻋﺒﺎﺭﺓ ﻋﻦ ﺷﻔﺮﺓ.‬ ‫ﺍﻟﺒﺖ 44: ‪:Descriptor Bit‬‬ ‫•‬ ‫– 0:‪.System descriptor‬‬ ‫– 1: ‪.Code or Data Descriptor‬‬ ‫ﺍﻟﺒﺘﺎﺕ 54-64: ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ‪Privilege Level‬‬ ‫•‬ ‫– 0: ‪.(Ring 0) Highest‬‬ ‫– 3: ‪.(Ring 3) Lowest‬‬ ‫٨٦‬
    • ‫٤.١. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬ .Segment is in memory (Used with Virtual Memory) :47 ‫ﺍﻟﺒﺖ‬ • .‫ﺍﻟﺒﺘﺎﺕ 84-15: ﲢﻮﻱ ﺍﻟﺒﺖ 61 -91 ﻣﻦ ﺣﺠﻢ ﺍﳌﻘﻄﻊ‬ • .‫ﺍﻟﺒﺖ 25: ﳏﺠﻮﺯﺓ‬ • .‫ﺍﻟﺒﺖ 35: ﳏﺠﻮﺯﺓ‬ • :Segment type ‫ﺍﻟﺒﺖ 45: ﻧﻮﻉ ﺍﳌﻘﻄﻊ‬ • .‫– 0: ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ 61 ﺑﺖ‬ .‫– 1: ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ 23 ﺑﺖ‬ :Granularity :55 ‫ﺍﻟﺒﺖ‬ • .None :0 – .Limit gets mul plied by 4K :1 – .Base Address ‫ﺍﻟﺒﺘﺎﺕ 65-36: ﲢﻮﻱ ﺍﻟﺒﺖ 32 -23 ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ‬ •،Code and Data Descriptor ‫ﻭﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﺳﻨﻘﻮﻡ ﺑﺒﻨﺎء ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻭﻳﺘﻜﻮﻥ ﻣﻦ ﻭﺍﺻﻔﺔ ﻟﻠﻜﻮﺩ ﻭﻟﻠﺒﻴﺎﻧﺎﺕ‬ .0xffffffff ‫ﲝﻴﺚ ﳝﻜﻦ ﺍﻟﻘﺮﺍءﺓ ﻭ ﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﺃﻭﻝ ﺑﺎﻳﺖ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﺍﱃ ﺁﺧﺮ ﺍﻟﺬﺍﻛﺮﺓ‬ Example ٤.١: GDT١ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢ ; Global Descriptor Table٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤٥ begin of gdt:٦٧ ; Null Descriptor: start at 0x0.٨٩ dd 0x0 ; fill 8 byte with zero.١٠ dd 0x0١١١٢ ; Code Descriptor: start at 0x8.١٣١٤ dw 0xffff ; limit low.١٥ dw 0x0 ; base low.١٦ db 0x0 ; base middle.١٧ db 10011010b ; access byte.١٨ db 11001111b ; granularity byte.١٩ db 0x0 ; base high.٦٩
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫٠٢‬‫.01‪٢١ ; Data Descriptor: start at 0x‬‬‫٢٢‬‫٣٢‬ ‫‪dw‬‬ ‫‪0xffff‬‬ ‫.‪; limit low‬‬‫٤٢‬ ‫‪dw‬‬ ‫0‪0x‬‬ ‫;‬ ‫.‪base low‬‬‫٥٢‬ ‫‪db‬‬ ‫0‪0x‬‬ ‫;‬ ‫.‪base middle‬‬‫٦٢‬ ‫‪db‬‬ ‫‪10010010b‬‬ ‫.‪; access byte‬‬‫٧٢‬ ‫‪db‬‬ ‫‪11001111b‬‬ ‫.‪; granularity byte‬‬‫٨٢‬ ‫‪db‬‬ ‫0‪0x‬‬ ‫;‬ ‫.‪base high‬‬‫٩٢‬‫:‪٣٠ end of gdt‬‬‫ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﺒﺪﺃ ﺑﺎﻟﻮﺍﺻﻔﺔ ﺍﳋﺎﻟﻴﺔ ‪ Null Descriptor‬ﻭﺣﺠﻤﻬﺎ 8 ﺑﺎﻳﺖ ﻭﻣﺘﺤﻮﻳﺎ‪‬ﺎ ﺗﻜﻮﻥ ﺻﻔﺮﴽ ﰲ ﺍﻟﻌﺎﺩﺓ ، ﺃﻣﺎ‬‫ﺍﻟﻮﺍﺻﻔﺔ ﺍﻟﺘﺎﻟﻴﺔ ﳍﺎ ﻓﻬﻲ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﺸﻔﺮﺓ ‪ Code Descriptor‬ﻭﺗﻮﺿﺢ ﺍﳌﻘﻄﻊ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﺳﻴﺘﺴﺨﺪﻡ‬‫ﻛﺸﻔﺮﺓ ﻭﻣﺎ ﻫﻲ ﺑﺪﺍﻳﺘﻪ ﻭﺣﺠﻤﻪ ﻭﺻﻼﺣﻴﺎﺕ ﺍﺳﺘﺨﺪﺍﻣﻪ ﺣﻴﺚ ﳝﻜﻦ ﺃﻥ ﻧﺴﻤﺢ ﻓﻘﻂ ﻟﻠﱪﺍﻣﺞ ﺍﻟﱵ ﺗﻌﻤﻞ ﻋﻠﻰ‬‫ﻣﺴﺘﻮﻯ ﺍﻟﻨﻮﺍﺓ ‪ Kernel Mode‬ﺑﺎﻟﺪﺧﻮﻝ ﺍﱃ ﻫﺬﺍ ﺍﳌﻘﻄﻊ.ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺷﺮﺡ ﳌﺤﺘﻮﻳﺎﺕ ﻫﺬﻩ ﺍﻟﻮﺍﺻﻔﺔ ﻭﳝﻜﻨﻚ‬ ‫ﺍﳌﻄﺎﺑﻘﺔ ﻣﻊ ﺍﳉﺪﻭﻝ ﺍﻟﺬﻱ ﻳﻮﺿﺢ ﺍﻟﺸﻜﻞ ﺍﻟﻌﺎﻡ ﻟﻜﻞ ﻭﺍﺻﻔﺔ.‬‫ﺗﺒﺪﺃ ﻭﺍﺻﻔﺔ ﺍﻟﻜﻮﺩ ‪ Code Descriptor‬ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 8‪ 0x‬ﻭﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻬﻢ ﺟﺪﺍ ﺣﻴﺚ ﺳﻴﻜﻮﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ‬‫ﻫﻮ ﻗﻴﻤﺔ ﺍﳌﺴﺠﻞ ‪ ، CS‬ﻭﺍﻟﺒﺘﺎﺕ ﻣﻦ 0-51 ﲢﺪﺩ ﺣﺠﻢ ﺍﳌﻘﻄﻊ ‪ Segment Limit‬ﻭﺍﻟﻘﻴﻤﺔ ﻫﻲ ‪ 0xffff‬ﺗﺪﻝ‬ ‫ﻋﻠﻰ ﺃﻥ ﺃﻛﱪ ﺣﺠﻢ ﳝﻜﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ ﻫﻮ ‪.0xffff‬‬‫ﺍﻟﺒﺘﺎﺕ ﻣﻦ 61-93 ﲤﺜﻞ ﺍﻟﺒﺘﺎﺕ 0-32 ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ‪ Base Address‬ﻭﺍﻟﻘﻴﻤﺔ ﺍﻟﱵ ﰎ ﺍﺧﺘﻴﺎﺭﻫﺎ ﻫﻲ‬ ‫0‪ 0x‬ﻭﺑﺎﻟﺘﺎﱄ ﻧﻌﺮﻑ ﺃﻥ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﻫﻮ 0‪ 0x‬ﻭﻋﻨﻮﺍﻥ ﺍﻟﻨﻬﺎﻳﺔ ‪. 0xffff‬‬‫ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 6 ﻭﻳﺴﻤﻰ ‪ Access Byte‬ﳛﺪﺩ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺗﻮﺿﻴﺢ ﳌﻌﲎ ﻛﻞ ﺑﺖ ﻣﻮﺟﻮﺩﺓ‬ ‫ﻓﻴﻪ:‬ ‫• ﺍﻟﺒﺖ 0: ‪ Access Bit‬ﻭﻳﺴﺘﺨﺪﻡ ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ ﻟﺬﻟﻚ ﺍﺧﺘﺮﻧﺎ ﺍﻟﻘﻴﻤﺔ 0.‬‫ﺍﻟﺒﺖ 1: ﺑﺖ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ، ﻭﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1 ﻟﺬﺍ ﳝﻜﻦ ﻗﺮﺍءﺓ ﻭﺗﻨﻔﻴﺬ ﺃﻱ ﺑﺎﻳﺖ ﻣﻮﺟﻮﺩﺓ ﰲ‬ ‫•‬ ‫ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﻣﻦ 0‪.0xffff-0x‬‬ ‫‪ expansion direc‬ﻻ ﻳﻬﻢ ﺣﺎﻟﻴﺎ ﻟﺬﺍ ﺍﻟﻘﻴﻤﺔ ﻫﻲ 0.‬ ‫2: ‪on‬‬ ‫ﺍﻟﺒﺖ‬ ‫•‬ ‫ﺍﻟﺒﺖ 3: ﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1 ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﻣﻘﻄﻊ ﺷﻔﺮﺓ ‪.Code Segment‬‬ ‫•‬ ‫ﺍﻟﺒﺖ 4: ﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1 ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﻣﻘﻄﻊ ﻟﻠﺸﻔﺮﺓ ﺍﻭ ﻟﻠﺒﻴﺎﻧﺎﺕ ﻭﻟﻴﺲ ﻟﻠﻨﻈﺎﻡ.‬ ‫•‬‫ﺍﻟﺒﺘﺎﺕ 5-6: ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ﻭﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 0 ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻳﺴﺘﺨﺪﻡ ﻓﻘﻂ ﰲ ﺍﳊﻠﻘﺔ‬ ‫•‬ ‫ﺻﻔﺮ 0‪ Ring‬ﺃﻭ ﻣﺎ ﻳﺴﻤﻰ ‪.Kernel Mode‬‬ ‫ﺍﻟﺒﺖ 7: ﺗﺴﺘﺨﺪﻡ ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ ﻟﺬﺍ ﰎ ﺍﳘﺎﳍﺎ.‬ ‫•‬ ‫٠٧‬
    • ‫٤.١. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬‫ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 7 ﻭﻳﺴﻤﻰ ‪ granularity‬ﳛﺪﺩ ﺃﻳﻀﺎ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ، ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺗﻮﺿﻴﺢ ﳌﻌﲎ ﻛﻞ ﺑﺖ ﻣﻮﺟﻮﺩﺓ‬ ‫ﻓﻴﻪ:‬‫ﺍﻟﺒﺘﺎﺕ 0-3: ﲤﺜﻞ ﺍﻟﺒﺘﺎﺕ ﻣﻦ 61-91 ﻣﻦ ‪‬ﺎﻳﺔ ﺣﺠﻢ ﺍﳌﻘﻄﻊ ‪ Segment Limit‬ﻭﺍﻟﻘﻴﻤﺔ ﻫﻲ ‪، 0xf‬‬ ‫•‬‫ﻭ‪‬ﺬﺍ ﻳﻜﻮﻥ ﺃﻗﺼﻰ ﻋﻨﻮﺍﻥ ﻟﻠﻤﻘﻄﻊ ﻫﻮ ‪ 0xfffff‬ﺃﻱ 1 ﻣﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ، ﻭﻻﺣﻘﴼ ﻋﻨﺪﻣﺎ ﻳﺘﻢ ﺗﻔﻌﻴﻞ‬ ‫ﺑﻮﺍﺑﺔ 02‪ A‬ﺳﻨﺘﻤﻜﻦ ﻣﻦ ﺍﻟﻮﺻﻮﻝ ﺣﱴ 4 ﺟﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ.‬ ‫ﺍﻟﺒﺘﺎﺕ 4-5: ﳏﺠﻮﺯﺓ ﻟﻠﻨﻈﺎﻡ ﻟﺬﺍ ﰎ ﺍﳘﺎﳍﺎ.‬ ‫•‬ ‫ﺍﻟﺒﺖ 6: ﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1 ﺩﻻﻟﺔ ﻋﻠﻰ ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻫﻮ 23 ﺑﺖ.‬ ‫•‬ ‫4.‬ ‫‪KB‬‬ ‫ﺍﻟﺒﺖ 7: ﺑﺎﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1 ﺳﻴﺘﻢ ﺇﺣﺎﻃﺔ ﺍﳌﻘﻄﻊ ﺏ‬ ‫•‬‫ﺍﻟﺒﺎﻳﺖ ﺍﻻﺧﲑ ﰲ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ )ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 8( ﳝﺜﻞ ﺍﻟﺒﺘﺎﺕ ﻣﻦ 42-23 ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ‬ ‫ﻭﺍﻟﻘﻴﻤﺔ ﻫﻲ 0‪ 0x‬ﻭﺑﺎﻟﺘﺎﱄ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﺍﻟﻜﻠﻲ ﻫﻮ 0‪ 0x‬ﺃﻱ ﻣﻦ ﺃﻭﻝ ﺑﺎﻳﺖ ﰲ ﺍﻟﺬﺍﻛﺮﺓ.‬‫ﺇﺫﴽ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ‪ Code Descriptor‬ﺣﺪﺩﺕ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﻭ‪‬ﺎﻳﺘﻪ ﻭﻛﺬﻟﻚ ﺻﻼﺣﻴﺔ ﺍﻟﺘﻨﻔﻴﺬ‬ ‫ﻭﺣﺪﺩﺕ ﺑﺄﻥ ﺍﳌﻘﻄﻊ ﻫﻮ ﻣﻘﻄﻊ ﻛﻮﺩ ‪.Code Segment‬‬‫ﺍﻟﻮﺍﺻﻔﺔ ﺍﻟﺘﺎﻟﻴﺔ ﻫﻲ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪ Data Descriptor‬ﻭﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ﺭﻗﻢ 01‪ 0x‬ﻭﻫﻲ ﻣﺸﺎ‪‬ﺔ ﲤﺎﻣﺎ‬ ‫ﻟﻮﺍﺻﻔﺔ ﺍﻟﻜﻮﺩ ﺑﺎﺳﺘﺜﻨﺎء ﺍﻟﺒﺖ ﺭﻗﻢ 34 ﺣﻴﺚ ﳛﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ ﻛﻮﺩ ﺃﻡ ﺑﻴﺎﻧﺎﺕ.‬‫ﻭﺑﻌﺪ ﺇﻧﺸﺎء ﻫﺬﺍ ﺍﳉﺪﻭﻝ )‪ (GDT‬ﰲ ﺍﻟﺬﺍﻛﺮﺓ ، ﳚﺐ ﺃﻥ ﻳ‪‬ﺤﻤِﻞ ﺍﳌﺴﺠﻞ ‪ gdtr‬ﻋﻠﻰ ﺣﺠﻢ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻧﺎﻗﺼﺎ‬‫ﻭﺍﺣﺪ ﻭﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳉﺪﻭﻝ، ﻭﻳﺘﻢ ﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﺇﻧﺸﺎء ﻣﺆﺷﺮﺍ ﺍﱃ ﺟﺪﻭﻝ ‪ GDT‬ﻭﻣﻦ ﰒ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻻﻣﺮ‬ ‫‪) lgdt‬ﻭﻫﻮ ﺃﻣﺮ ﻳﻌﻤﻞ ﻓﻘﻂ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ 0‪ ، (Ring‬ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﺫﻟﻚ.‬ ‫‪Example‬‬ ‫‪٤.٢: Load GDT into GDTR‬‬‫١‬‫‪٢ bits‬‬ ‫61‬ ‫.‪; real mode‬‬‫٣‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٤‬‫.‪٥ ; load gdt: Load GDT into GDTR‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٦‬‫٧‬‫:‪٨ load gdt‬‬‫٩‬‫٠١‬ ‫‪cli‬‬ ‫.‪; clear interrupt‬‬‫١١‬ ‫‪pusha‬‬ ‫‪; save registers‬‬‫٢١‬ ‫]‪lgdt [gdt ptr‬‬ ‫‪; load gdt into gdtr‬‬‫٣١‬ ‫‪sti‬‬ ‫‪; enable interrupt‬‬‫٤١‬ ‫‪popa‬‬ ‫.‪; restore registers‬‬‫٥١‬‫١٧‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫٦١‬ ‫‪ret‬‬‫٧١‬‫٨١‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٩١‬‫‪٢٠ ; gdt ptr: data structure used by gdtr‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ١٢‬‫٢٢‬‫:‪٢٣ gdt ptr‬‬‫٤٢‬‫٥٢‬ ‫1 − ‪dw end of gdt − begin of gdt‬‬ ‫1− ‪; size‬‬‫٦٢‬ ‫‪dd begin of gdt‬‬ ‫‪; base of gdt‬‬ ‫‪PMode Memory Addressing‬‬ ‫٤.١.٢. ﺍﻟﻌﻨﻮﻧﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬‫ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻳﺴﺘﺨﺪﻡ ﺍﳌﻌﺎﰿ ﻋﻨﻮﻧﺔ ‪ Segment:Offset‬ﻭﺫﻟﻚ ﺑﺄﻥ ﺗﻜﻮﻥ ﺃﻱ ﻣﻦ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ‬‫)‪ (Segments Registers‬ﲢﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ، ﻭﻣﺴﺠﻼﺕ ﺍﻟﻌﻨﺎﻭﻳﻦ ﲢﻮﻱ ﺍﻟﻌﻨﻮﺍﻥ ﺩﺍﺧﻞ ﻣﻘﻄﻊ ﻣﺎ ،‬‫ﻭﻳﺘﻢ ﺿﺮﺏ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﺑﺎﻟﻌﺪﺩ 01‪ 0x‬ﻭﲨﻊ ﺍﻝ ‪ offset‬ﺍﻟﻴﻪ ﻟﻠﺤﺼﻮﻝ ﻋﻠﻰ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻨﻬﺎﺋﻲ ﻭﺍﻟﺬﻱ ﺳﻴﻤﺮ‬ ‫ﺑﺪﺍﺧﻞ ﻣﺴﺎﺭ ﺍﻟﻌﻨﻮﺍﻥ ‪.Address Bus‬‬‫ﺃﻣﺎ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ‪ PMode‬ﻓﺎﻧﻪ ﻳﺴﺘﺨﺪﻡ ﻋﻨﻮﻧﺔ ‪ Descriptor:Offset‬ﻭﺫﻟﻚ ﺑﺄﻥ ﺗﻜﻮﻥ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﲢﻮﻱ‬‫ﻋﻨﻮﺍﻥ ﺃﺣﺪ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﱵ ﻗﻤﻨﺎ ﺑﺒﻨﺎﺋﻬﺎ )ﻣﺜﻼ ﻣﺴﺠﻞ ‪ CS‬ﳛﻮﻱ ﺍﻟﻌﻨﻮﺍﻥ 8‪ 0x‬ﻭﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪ DS‬ﳛﻮﻱ‬‫ﺍﻟﻌﻨﻮﺍﻥ 01‪ ، (0x‬ﻭﺍﻝ ‪ offset‬ﺳﻴﺘﻢ ﲨﻌﻬﺎ ﺍﱃ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ‪ Base Address‬ﻭﺍﻟﺬﻱ ﻗﻤﻨﺎ ﺑﺘﺤﺪﻳﺪﻩ ﰲ‬‫ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﻛﺬﻟﻚ ﺳﻴﺘﻢ ﺍﻟﺘﺄﻛﺪ ﻣﻦ ﺃﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻻ ﻳﺘﺠﺎﻭﺯ ﺣﺠﻢ ﺍﳌﻘﻄﻊ ‪ Segment Limit‬ﺃﻳﻀﺎ‬‫ﺳﻴﺘﻢ ﺍﻟﺘﺄﻛﺪ ﻣﻦ ﻣﺴﺘﻮﻯ ﺍﻟﺼﻼﺣﻴﺔ ﻭﺃﻧﻪ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﻟﻠﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻮﺏ. ﻭﻧﻈﺮﴽ ﻻﻥ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﳝﻜﻦ‬ ‫ﺍﺳﺘﺨﺪﺍﻡ ﻣﺴﺠﻼﺕ ‪ 32-bit‬ﻓﺎﻧﻪ ﳝﻜﻦ ﻋﻨﻮﻧﺔ 4 ﺟﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ١.‬ ‫٤.١.٣. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬‫ﺑﻌﺪ ﺇﻧﺸﺎء ﺟﺪﻭﻝ ‪ GDT‬ﻭﲢﻤﻴﻞ ﻣﺴﺠﻞ ‪ GDTR‬ﳝﻜﻦ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻋﻦ ﻃﺮﻳﻖ ﺗﻔﻌﻴﻞ ﺍﻟﺒﺖ ﺍﻻﻭﻝ‬‫ﰲ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ 0‪ ،cr‬ﻭﻛﻤﺎ ﻫﻮ ﻣﻌﺮﻭﻑ ﺃﻥ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻻ ﻳﺴﺘﺨﺪﻡ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﻟﺬﺍ ﳚﺐ ﺗﻌﻄﻴﻞ‬ ‫ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻗﺒﻞ ﺍﻻﻧﺘﻘﺎﻝ ﺣﱴ ﻻ ﲢﺪﺙ ﺃﻱ ﻣﺸﺎﻛﻞ.‬‫ﻭﺑﻌﺪ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﺎﻥ ﳚﺐ ﺗﻌﻴﲔ ﺍﻟﻮﺍﺻﻔﺔ ﺍﻟﱵ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ ﳌﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ، ﻭﺑﺎﻟﻨﺴﺒﺔ‬‫ﳌﺴﺠﻞ ‪ CS‬ﻓﺎﻧﻪ ﳝﻜﻦ ﺗﻌﺪﻳﻞ ﻗﻴﻤﺘﻪ ﻭﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﺗﻨﻔﻴﺬ ‪، far jump‬ﻭﺍﻟﻜﻮﺩ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻃﺮﻳﻘﺔ ﺍﻻﻧﺘﻘﺎﻝ‬ ‫ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﺗﻌﺪﻳﻞ ﻗﻴﻢ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ.‬ ‫١ﺑﻔﺮﺽ ﺃﻥ ﺑﻮﺍﺑﺔ 02‪ A‬ﰎ ﺗﻔﻌﻴﻠﻬﺎ.‬ ‫٢٧‬
    • ‫٤.١. ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬ Example ٤.٣: Switching to Protected Mode١ ;−−−−−−−−−− −−−−−−−−−−٢ ; Load gdt into gdtr.٣ ;−−−−−−−−−− −−−−−−−−−−٤٥ call load gdt٦٧ ;−−−−−−−− −−−−−−−−٨ ; Go to PMode.٩ ;−−−−−−−− −−−−−−−−١٠ ; just set bit 0 from cr0 (Control Register 0).١١١٢ cli ; important.١٣ mov eax,cr0١٤ or eax,0x1١٥ mov cr0,eax ; entering pmode.١٦١٧١٨ ;−−−−−−−−− −−−−−−−−−−١٩ ; Fix CS value٢٠ ;−−−−−−−−−− −−−−−−−−−−٢١ ; select the code descriptor٢٢ jmp 0x8:stage3٢٣٢٤٢٥ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٦ ; entry point of stage3٢٧ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٨٢٩ bits 32 ; code now 32−bit٣٠٣١ stage3:٣٢٣٣ ; − − − − − − − −; −−−−−−−−٣٤ ; Set Registers.٣٥ ; − − − − − − − −; −−−−−−−−٣٦٣٧ mov ax,0x10 ; address of data descriptor.٣٨ mov ds,ax٣٩ mov ss,ax٧٣
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫٠٤‬ ‫‪mov es,ax‬‬‫١٤‬ ‫00009‪mov esp,0x‬‬ ‫.00009‪; stack begin from 0x‬‬‫٢٤‬‫٣٤‬‫٤٤‬ ‫; −−−−−−−−;‬ ‫−−−−−−−−−‬‫٥٤‬ ‫.‪; Hlat the system‬‬‫٦٤‬ ‫; −−−−−−−−;‬ ‫−−−−−−−−−‬‫٧٤‬ ‫‪cli‬‬ ‫.‪; clear interrupt‬‬‫٨٤‬ ‫‪hlt‬‬ ‫.‪; halt the system‬‬ ‫02‪A‬‬ ‫٤.٢. ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ‬‫ﺑﻮﺍﺑﺔ ‪ A20 Gate‬ﻫﻲ ﻋﺒﺎﺭﺓ ﻋﻦ ‪ OR Gate‬ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﻧﺎﻗﻞ ﺍﻟﻨﻈﺎﻡ ‪٢ System Bus‬ﻭﺍﳍﺪﻑ ﻣﻨﻬﺎ ﻫﻮ ﺍﻟﺘﺤﻜﻢ ﰲ‬‫ﻋﺪﺩ ﺧﻄﻮﻁ ﺍﻟﻌﻨﺎﻭﻳﻦ ‪ ،Address Line‬ﺣﻴﺚ ﻛﺎﻧﺖ ﺍﻻﺟﻬﺰﺓ ﻗﺪﳝﺎ )ﺫﺍﺕ ﺍﳌﻌﺎﳉﺎﺕ ﺍﻟﱵ ﺗﺴﺒﻖ ﻣﻌﺎﰿ 68208(‬‫ﲢﻮﻱ ﻋﻠﻰ 02 ﺑﺖ )ﺧﻂ( ﻟﻠﻌﻨﺎﻭﻳﻦ )‪ ، (20 address line‬ﻭﻋﻨﺪﻣﺎ ﺻﺪﺭﺕ ﺍﺟﻬﺰﺓ ‪ IBM PC‬ﻭﺍﻟﱵ ﺍﺣﺘﻮﺕ‬‫ﻋﻠﻰ ﻣﻌﺎﰿ 68208 ﰎ ﺯﻳﺎﺩﺓ ﺧﻂ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﱃ 23 ﺧﻂ ﻭﻫﻜﺬﺍ ﺃﺻﺒﺢ ﻣﻦ ﺍﳌﻤﻜﻦ ﻋﻨﻮﻧﺔ 4 ﺟﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ‬‫، ﻭﺣﱴ ﻳﺘﻢ ﺍﳊﻔﺎﻅ ﻋﻠﻰ ﺍﻟﺘﻮﺍﻓﻘﻴﺔ ﻣﻊ ﺍﻻﺟﻬﺰﺓ ﺍﻟﺴﺎﺑﻘﺔ ﻓﺎﻧﻪ ﳝﻜﻦ ﺍﻟﺘﺤﻜﻢ ﰲ ﺑﻮﺍﺑﺔ 02‪ A‬ﻣﻦ ﻓﺘﺢ ﺍﳋﻄﻮﻁ‬ ‫02‪ A31-A‬ﻭﺍﻏﻼﻗﻬﺎ.‬‫ﻫﺬﻩ ﺍﻟﺒﻮﺍﺑﺔ ﻣﺮﺗﺒﻄﺔ ﻣﻊ ﻣﺘﺤﻜﻢ 2408 ﻭﻫﻮ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )‪ ، (Keyboard Controller‬ﻭﻋﻨﺪ ﺗﻔﻌﻴﻞ‬‫ﺍﻟﺒﺖ ﺭﻗﻢ 1 ﰲ ﻣﻨﻔﺬ ﺧﺮﻭﺝ ﺍﻟﺒﻴﺎﻧﺎﺕ )‪ (output data port‬ﺍﻟﺘﺎﺑﻊ ﳌﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻓﺎﻥ ﻫﺬﺍ ﻳﻔﺘﺢ ﺑﻮﺍﺑﺔ‬ ‫02‪ A‬ﻭ‪‬ﺬﺍ ﻧﺴﺘﻄﻴﻊ ﺍﻟﻮﺻﻮﻝ ﺍﱃ 4 ﺟﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ، ﺍﺑﺘﺪﺍءﴽ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0‪0xffffffff-0x‬‬‫ﻭﻋﻨﺪ ﺍﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ ﻳﻘﻮﻡ ﺑﺘﻔﻌﻴﻞ ﻫﺬﻩ ﺍﻟﺒﻮﺍﺑﺔ ﻷﻏﺮﺍﺽ ﺣﺴﺎﺏ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﺧﺘﺒﺎﺭﻫﺎ ﻭﻣﻦ‬ ‫ﰒ ﻳﻘﻮﻡ ﺑﻐﻠﻘﻬﺎ ﳎﺪﺩﴽ ﻟﻠﺤﻔﺎﻅ ﻋﻠﻰ ﺍﻟﺘﻮﺍﻓﻘﻴﺔ ﻣﻊ ﺍﻻﺟﻬﺰﺓ ﺍﻟﻘﺪﳝﺔ.‬‫ﻭﺗﻮﺟﺪ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﻄﺮﻕ ﻟﺘﻔﻌﻴﻞ ﻫﺬﻩ ﺍﻟﺒﻮﺍﺑﺔ ، ﺍﻟﻌﺪﻳﺪ ﻣﻨﻬﺎ ﻳﻌﻤﻞ ﻋﻠﻰ ﺃﺟﻬﺰﺓ ﻣﻌﻴﻨﺔ ﻟﺬﻟﻚ ﺳﻴﺘﻢ ﺫﻛﺮ ﺍﻟﻌﺪﻳﺪ‬ ‫ﻣﻦ ﺍﻟﻄﺮﻕ ﻭﺍﺳﺘﺨﺪﺍﻡ ﺃﻛﺜﺮ ﺍﻟﻄﺮﻕ ﳏﻤﻮﻟﻴﺔ ﻋﻠﻰ ﺻﻌﻴﺪ ﺍﻻﺟﻬﺰﺓ ﺍﳌﺨﺘﻠﻔﺔ.‬ ‫02‪A‬‬ ‫٤.٢.١. ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ 2408 ﻭﺍﻟﺒﻮﺍﺑﺔ‬‫ﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ )‪ (PMode‬ﻓﺎﻧﻪ ﻟﻦ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﻭﳚﺐ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ‬‫ﻣﺘﺤﻜﻢ ﺃﻱ ﻋﺘﺎﺩ ﻭﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﻣﺴﺠﻼﺕ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺪﺍﺧﻠﻴﺔ . ﻭﺑﺴﺒﺐ ﺍﺭﺗﺒﺎﻁ ﺑﻮﺍﺑﺔ 02‪ A‬ﻣﻊ ﻣﺘﺤﻜﻢ‬‫ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻓﺎﻧﻪ ﻻ ﺑﺪ ﻣﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﻟﺘﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ ، ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺍﺳﺘﺨﺪﺍﻡ ﺃﻭﺍﻣﺮ‬ ‫ﺍﳌﻌﺎﰿ ‪ in‬ﻭﺍﻻﻣﺮ ‪.out‬‬ ‫02‬ ‫٢ﺗﻮﺟﺪ ﺍﻟﺒﻮﺍﺑﺔ ﲢﺪﻳﺪﴽ ﻋﻠﻰ ﺧﻂ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺭﻗﻢ‬ ‫٤٧‬
    • ‫02‪A‬‬ ‫٤.٢. ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ‬‫ﻭﲞﺼﻮﺹ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﻣﺘﺤﻜﻢ 2408( ﻓﻐﺎﻟﺒﺎ ﻣﺎ ﺗﺄﰐ ﻋﻠﻰ ﺷﻜﻞ ﺷﺮﳛﺔ ‪ Integrated Circuit‬ﺃﻭ‬‫ﺗﻜﻮﻥ ﻣﻀﻤﻨﺔ ﺩﺍﺧﻞ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ )‪ (Motherboard‬ﻭﺗﻜﻮﻥ ﰲ ﺍﻝ ‪.South Bridge‬ﻭﻳﺮﺗﺒﻂ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﻣﻊ‬‫ﻣﺘﺤﻜﻢ ﺁﺧﺮ ﺑﺪﺍﺧﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ، ﻭﻋﻨﺪ ﺍﻟﻀﻐﻂ ﻋﻠﻰ ﺯﺭ ﻣﺎ ﻓﺎﻧﻪ ﻳﺘﻢ ﺗﻮﻟﻴﺪ ‪ Make Code‬ﻭُﺮﺳﻞ ﺍﱃ‬ ‫ﻳ‬‫ﺍﳌﺘﺤﻜﻢ ﺍﳌﻮﺟﻮﺩ ﺑﺪﺍﺧﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﺍﻟﺬﻱ ﺑﺪﺭﻭﻩ ﻳﻘﻮﻡ ﺑﺎﺭﺳﺎﻟﻪ ﺍﱃ ﻣﺘﺤﻜﻢ 2408 ﻋﻦ ﻃﺮﻳﻖ ﻣﻨﻔﺬ ﺍﳊﺎﺳﺐ‬‫)‪. (Hardware Port‬ﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ ﻣﺘﺤﻜﻢ 2408 ﺣﻴﺚ ﻳﻘﻮﻡ ﺑﺘﺤﻮﻳﻞ ‪ Make code‬ﺍﱃ ‪ Scan Code‬ﻭﳛﻔﻈﻬﺎ‬‫ﰲ ﻣﺴﺠﻼﺗﻪ ﺍﻟﺪﺍﺧﻠﻴﺔ ‪ Buffer‬ﻫﺬﺍ ﺍﳌﺴﺠﻞ ﳛﻤﻞ ﺍﻟﺮﻗﻢ 06‪ 0x‬ﰲ ﺃﺟﻬﺰﺓ ‪ ،IBM and Compa ble PC‬ﻭﻫﺬﺍ‬ ‫ﻳﻌﲏ ﺃﻧﻪ ﰲ ﺣﺎﻟﺔ ﻗﺮﺍءﺓ ﻫﺬﺍ ﺍﳌﺴﺠﻞ )ﻋﻦ ﻃﺮﻳﻖ ﺍﻷﻣﺮ ‪ (in‬ﻓﺎﻧﻪ ﳝﻜﻦ ﻗﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ ﺍﳌﺪﺧﻠﺔ.‬‫ﻭﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﻣﻦ ﺳﻴﺘﻢ ﻣﻨﺎﻗﺸﺔ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﺑﺎﻟﺘﻔﺼﻴﻞ ، ﻭﺳﻨﻜﺘﻔﻲ ﻫﻨﺎ ﻓﻘﻂ ﺑﺘﻮﺿﻴﺢ ﺍﻷﺟﺰﺍء ﺍﳌﺘﻌﻠﻘﺔ‬ ‫ﺑﺘﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ 02‪.A‬‬ ‫02‪A‬‬ ‫٤.٢.٢. ﻃﺮﻕ ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ‬ ‫29‪System Control Port 0x‬‬ ‫ﺑﻮﺍﺳﻄﺔ‬‫ﰲ ﺑﻌﺾ ﺍﻻﺟﻬﺰﺓ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﺃﺣﺪ ﻣﻨﺎﻓﺬ ﺍﻻﺩﺧﺎﻝ ﻭﺍﻻﺧﺮﺍﺝ ﻭﻫﻮ 29‪ I/O part 0x‬ﻟﺘﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ 02‪، A‬‬‫ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺳﻬﻮﻟﺔ ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻻ ﺃ‪‬ﺎ ﺗﻌﺘﱪ ﺃﻗﻞ ﳏﻤﻮﻟﻴﺔ ﻭﺑﻌﺾ ﺍﻻﺟﻬﺰﺓ ﻻ ﺗﺪﻋﻤﻬﺎ ، ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺗﻮﺿﻴﺢ‬ ‫ﻟﻠﺒﺘﺎﺕ ﻋﻠﻰ ﻫﺬﺍ ﺍﳌﻨﻔﺬ:‬ ‫ﺍﻟﺒﺖ 0: ﺗﻔﻌﻴﻞ ﻫﺬﺍ ﺍﻟﺒﺖ ﻳﺆﺩﻱ ﺍﱃ ﻋﻤﻞ ‪ reset‬ﻟﻠﻨﻈﺎﻡ ﻭﺍﻟﻌﻮﺩﺓ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ.‬ ‫•‬ ‫ﺍﻟﺒﺖ 1: ﺍﻟﻘﻴﻤﺔ 0 ﻟﺘﻌﻄﻴﻞ ﺑﻮﺍﺑﺔ 02‪ ، A‬ﻭﺍﻟﻘﻴﻤﺔ 1 ﻟﺘﻔﻌﻴﻠﻬﺎ.‬ ‫•‬ ‫ﺍﻟﺒﺖ 2: ﻻ ﺗﺴﺘﺨﺪﻡ.‬ ‫•‬ ‫ﺍﻟﺒﺖ 3: ‪power on password bytes‬‬ ‫•‬ ‫ﺍﻟﺒﺘﺎﺕ 4-5: ﻻ ﺗﺴﺘﺨﺪﻡ.‬ ‫•‬ ‫‪.on‬‬ ‫ﺍﻟﺒﺘﺎﺕ 6-7: ‪ : HDD ac vity LED‬ﺍﻟﻘﻴﻤﺔ 0: ‪ ،off‬ﺍﻟﻘﻴﻤﺔ 1:‬ ‫•‬ ‫ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻃﺮﻳﻘﺔ ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ .‬‫‪Example‬‬ ‫29‪٤.٤: Enable A20 by System Control Port 0x‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ١‬‫:29‪٢ ; enable a20 port 0x‬‬‫; ٣‬ ‫29‪Enable A20 with System Control port 0x‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٤‬‫٥‬‫:29‪٦ enable a20 port 0x‬‬‫٧‬‫٥٧‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫٨‬ ‫‪push ax‬‬ ‫.‪; save register‬‬‫٩‬‫٠١‬ ‫2,‪mov al‬‬ ‫02‪; set bit 2 to enable A‬‬‫١١‬ ‫‪out 0x92,al‬‬‫٢١‬‫٣١‬ ‫‪pop ax‬‬ ‫.‪; restore register‬‬‫٤١‬ ‫‪ret‬‬‫ﻭﳚﺐ ﻣﻼﺣﻈﺔ ﺃﻥ ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﻻ ﺗﻌﻤﻞ ﰲ ﻛﻞ ﺍﻻﺟﻬﺰﺓ ﻭﺭﲟﺎ ﻳﻜﻮﻥ ﻫﻨﺎﻙ ﺍﺭﻗﺎﻡ ﳐﺘﻠﻔﺔ ﻟﻠﻤﻨﺎﻓﺬ ، ﻭﻳﻌﺘﻤﺪ ﰲ‬ ‫ﺍﻵﺧﺮ ﻋﻠﻰ ﻣﺼﻨﻌﻲ ﺍﻟﻠﻮﺣﺎﺕ ﺍﻻﻡ ﻭﳚﺐ ﻗﺮﺍءﺓ ﻛﺘﻴﺒﺎ‪‬ﺎ ﳌﻌﺮﻓﺔ ﺍﻟﻌﻨﺎﻭﻳﻦ.‬ ‫ﺑﻮﺍﺳﻄﺔ ﺍﻟﺒﺎﻳﻮﺱ‬‫0042‪0x‬‬ ‫ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 51‪ int 0x‬ﺍﻟﺪﺍﻟﺔ 1042‪ 0x‬ﻟﺘﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ 02‪ ، A‬ﻭﺍﻟﺪﺍﻟﺔ‬‫ﻟﺘﻌﻄﻴﻠﻬﺎ.ﻣﻊ ﺍﻟﺘﺬﻛﲑ ﺑﺄﻥ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﺍﳌﻌﺎﰿ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﺳﺘﺪﻋﺎء ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ،‬ ‫ﻭﺍﻟﻜﻮﺩ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻃﺮﻳﻘﺔ ﺍﻟﺘﻔﻌﻴﻞ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺍﻟﺒﺎﻳﻮﺱ.‬ ‫‪Example‬‬ ‫51‪٤.٥: Enable A20 by BIOS int 0x‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ١‬‫:‪٢ ; enable a20 bios‬‬‫; ٣‬ ‫1042‪Enable A20 with BIOS int 0x15 routine 0x‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٤‬‫٥‬‫:‪٦ enable a20 bios‬‬‫٧‬‫٨‬ ‫‪pusha‬‬ ‫‪; save all registers‬‬‫٩‬‫٠١‬ ‫.‪mov ax,0x2401 ; Enable A20 routine‬‬‫١١‬ ‫51‪int 0x‬‬‫٢١‬‫٣١‬ ‫‪popa‬‬ ‫‪; restore registers‬‬‫٤١‬ ‫‪ret‬‬ ‫ﺑﻮﺍﺳﻄﺔ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬‫‪Output‬‬ ‫ﻳﻮﺟﺪ ﻣﻨﻔﺬﻳﻦ ﳌﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ: ﺍﳌﻨﻔﺬ 06‪ 0x‬ﻭﻫﻮ ﳝﺜﻞ ﺍﻝ ‪) buffer‬ﰲ ﺣﺎﻟﺔ ﺍﻟﻘﺮﺍءﺓ ﻣﻨﻪ ﻳﺴﻤﻰ‬‫‪ Buffer‬ﻭﰲ ﺣﺎﻟﺔ ﺍﻟﻜﺘﺎﺑﺔ ﻳﺴﻤﻰ ‪ ،Input Buffer‬ﻭﺍﳌﻨﻔﺬ 46‪ 0x‬ﻭﻫﻮ ﻹﺭﺳﺎﻝ ﺍﻻﻭﺍﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﻭﻟﻘﺮﺍءﺓ ﺣﺎﻟﺔ‬ ‫٦٧‬
    • ‫02‪A‬‬ ‫٤.٢. ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ‬‫ﺍﳌﺘﺤﻜﻢ )‪ .(Status‬ﺣﻴﺚ ﻳﺘﻢ ﺍﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﻋﻦ ﻃﺮﻳﻖ ﺍﳌﻨﻔﺬ 46‪ 0x‬ﻭﺍﺫﺍ ﻛﺎﻥ ﻫﻨﺎﻙ ﻭﺳﺎﺋﻂ‬ ‫ﳍﺬﺍ ﺍﻷﻣﺮ ﻓﺘﺮﺳﻞ ﺍﱃ ﺍﻝ ‪) buffer‬ﺍﳌﻨﻔﺬ 06‪ (0x‬ﻭﻛﺬﻟﻚ ﺗﻘﺮﺃ ﺍﻟﻨﺘﺎﺋﺞ ﻣﻦ ﺍﳌﻨﻔﺬ 06‪.0x‬‬‫ﻭﺣﻴﺚ ﺍﻥ ﺗﻨﻔﻴﺬ ﺃﻭﺍﻣﺮ ﺍﻟﱪﻧﺎﻣﺞ )ﻋﻦ ﻃﺮﻳﻖ ﺍﳌﻌﺎﰿ( ﺃﺳﺮﻉ ﺑﻜﺜﲑ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ‬‫ﺍﳌﻔﺎﺗﻴﺢ )ﻭﺑﺸﻜﻞ ﻋﺎﻡ ﺍﱃ ﺃﻱ ﻣﺘﺤﻜﻢ ﻟﻌﺘﺎﺩ ﻣﺎ( ﻓﺎﻧﻪ ﳚﺐ ﺍﻥ ﻧﻮﻓﺮ ﻃﺮﻗﴼ ﻻﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﻗﺒﻞ ﺍﻟﻌﻮﺩﺓ ﺍﱃ‬ ‫ﺍﻟﱪﻧﺎﻣﺞ ﻻﺳﺘﻜﻤﺎﻝ ﺍﻟﺘﻨﻔﻴﺬ .‬‫ﻭﳝﻜﻦ ﻋﻦ ﻃﺮﻳﻖ ﻗﺮﺍءﺓ ﺣﺎﻟﺔ ﺍﳌﺘﺤﻜﻢ )ﻋﻦ ﻃﺮﻳﻖ ﻗﺮﺍءﺓ ﺍﳌﻨﻔﺬ 46‪ (0x‬ﺃﻥ ﻧﻌﺮﻑ ﻣﺎ ﺍﺫﺍ ﰎ ﺗﻨﻔﻴﺬ ﺍﻻﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ‬ ‫ﺍﻡ ﻻ ، ﻭﻛﺬﻟﻚ ﻫﻞ ﻫﻨﺎﻙ ﻧﺘﻴﺠﺔ ﻟﻜﻲ ﻳﺘﻢ ﻗﺮﺍﺋﺘﻬﺎ ﰲ ﺍﻟﱪﻧﺎﻣﺞ ﺍﻡ ﻻ.‬ ‫ﻭﻣﺎ ﻳﻬﻤﻨﺎ ﻣﻦ ﺍﻟﺒﺘﺎﺕ ﻋﻨﺪ ﻗﺮﺍءﺓ ﺣﺎﻟﺔ ﺍﳌﺘﺤﻜﻢ ﺣﺎﻟﻴﺎ ﻫﻮ ﺃﻭﻝ ﺑﺘﲔ ﻓﻘﻂ ، ﻭﻭﻇﻴﻔﺘﻬﻤﺎ ﻫﻲ:‬ ‫ﺍﻟﺒﺖ 0: ﺣﺎﻟﺔ ﺍﻝ ‪:Output Buffer‬‬ ‫•‬ ‫– ﺍﻟﻘﻴﻤﺔ 0: ﺍﻝ ‪ Output Buffer‬ﺧﺎﱄ )ﻻ ﺗﻮﺟﺪ ﻧﺘﻴﺠﺔ ، ﻻ ﺗﻘﺮﺃ ﺍﻻﻥ(.‬ ‫– ﺍﻟﻘﻴﻤﺔ 1: ﺍﻝ ‪ Output Buffer‬ﳑﺘﻠﺊ )ﺗﻮﺟﺪ ﻧﺘﻴﺠﺔ ، ﻗﻢ ﺑﺎﻟﻘﺮﺍءﺓ ﺍﻻﻥ(.‬ ‫ﺍﻟﺒﺖ 1: ﺣﺎﻟﺔ ﺍﻝ ‪:Input Buffer‬‬ ‫•‬ ‫– ﺍﻟﻘﻴﻤﺔ 0: ﺍﻝ ‪ Input Buffer‬ﺧﺎﱄ )ﻻ ﺗﻮﺟﺪ ﺃﻭﺍﻣﺮ ﻏﲑ ﻣﻨﻔﺬﺓ ، ﳝﻜﻦ ﺍﻟﻜﺘﺎﺑﺔ ﺍﻻﻥ(.‬ ‫– ﺍﻟﻘﻴﻤﺔ 1: ﺍﻝ ‪ Input Buffer‬ﳑﺘﻠﺊ )ﺗﻮﺟﺪ ﺃﻭﺍﻣﺮ ﻏﲑ ﻣﻨﻔﺬﺓ ، ﻻ ﺗﻜﺘﺐ ﺍﻻﻥ(.‬‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺍﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﺣﱴ ﻳﻨﻔﺬ ﺍﻻﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﻪ ﺍﻟﻴﻪ )‪ (wait input‬ﻭﻛﻴﻔﻴﺔ ﺍﻧﺘﻈﺎﺭ‬ ‫ﺍﳌﺘﺤﻜﻢ ﺍﱃ ﺍﻥ ﻳﺄﰐ ﺑﻨﺘﻴﺠﺔ ﻣﺎ )‪.(wait output‬‬ ‫‪Example‬‬ ‫‪٤.٦: Wait Input/Output‬‬‫١‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٢‬‫.‪٣ ; wait output: wait output buffer to be full‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٤‬‫٥‬‫:‪٦ wait output‬‬‫٧‬‫٨‬ ‫46‪in al,0x‬‬ ‫‪; read status‬‬‫٩‬ ‫1‪test al,0x‬‬ ‫?‪; is output buffer is empty‬‬‫٠١‬ ‫.‪je wait output ; yes, hang‬‬‫١١‬‫٢١‬ ‫‪ret‬‬ ‫.‪; no,there is a result‬‬‫٣١‬‫٤١‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٥١‬‫.‪١٦ ; wait input: wait input buffer to be empty‬‬‫٧٧‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫٧١‬ ‫.‪command executed already‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٨١‬‫٩١‬‫:‪٢٠ wait input‬‬‫١٢‬‫٢٢‬ ‫46‪in al,0x‬‬ ‫‪; read status‬‬‫٣٢‬ ‫2‪test al,0x‬‬ ‫?‪; is input buffer is full‬‬‫٤٢‬ ‫.‪jne wait input ; yes, hang‬‬‫٥٢‬‫٦٢‬ ‫‪ret‬‬ ‫.‪; no,command executed‬‬‫ﻭﻹﺭﺳﺎﻝ ﺍﻭﺍﻣﺮ ﺍﱄ ﺍﳌﺘﺤﻜﻢ ﻓﺎﻥ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﻨﻔﺬ 46‪ 0x‬ﻭﺗﻮﺟﺪ ﺍﻟﻜﺜﲑ ﻣﻦ ﺍﻷﻭﺍﻣﺮ ، ﻭﻧﻈﺮﺍ ﻻﻥ ﻫﺬﺍ ﺍﳉﺰء‬‫ﻏﲑ ﳐﺼﺺ ﻟﱪﳎﺔ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻓﺎﻧﻨﺎ ﺳﻨﻨﺎﻗﺶ ﻓﻘﻂ ﺍﻻﻭﺍﻣﺮ ﺍﻟﱵ ‪‬ﻤﻨﺎ ﺣﺎﻟﻴﺎ ، ﻭﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺩﺱ‬ ‫ﺳﻨﻌﻮﺩ ﺍﱃ ﺍﳌﻮﺿﻮﻉ ﺑﺎﻟﺘﻔﺼﻴﻞ ﺍﻥ ﺷﺎء ﺍﷲ.‬ ‫ﻭﻗﺎﺋﻤﺔ ﺍﻻﻭﺍﻣﺮ ﺣﺎﻟﻴﺎ:‬ ‫• ﺍﻷﻣﺮ ‪ :0xad‬ﺗﻌﻄﻴﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.‬ ‫ﺍﻷﻣﺮ ‪ :0xae‬ﺗﻔﻌﻴﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.‬ ‫•‬ ‫ﺍﻷﻣﺮ 0‪ :0xd‬ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ‪.Output Port‬‬ ‫•‬ ‫ﺍﻷﻣﺮ 1‪ :0xd‬ﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ‪.Output Port‬‬ ‫•‬ ‫ﺍﻷﻣﺮ ‪ :0xdd‬ﺗﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ 02‪.A‬‬ ‫•‬ ‫ﺍﻷﻣﺮ ‪ :0xdf‬ﺗﻌﻄﻴﻞ ﺑﻮﺍﺑﺔ 02‪.A‬‬ ‫•‬‫ﻭﻋﻦ ﻃﺮﻳﻖ ﺍﻷﻣﺮ ‪ 0xdd‬ﻓﺎﻧﻪ ﳝﻜﻦ ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ 02‪ A‬ﺑﺴﻬﻮﻟﺔ ﻛﻤﺎ ﰲ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ، ﻟﻜﻦ ﺃﻳﻀﺎ ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ‬ ‫ﻻ ﺗﻌﻤﻞ ﻋﻠﻰ ﻛﻞ ﺍﻻﺟﻬﺰﺓ ﺣﻴﺚ ﻫﻨﺎﻙ ﺑﻌﺾ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻻ ﺗﺪﻋﻢ ﻫﺬﺍ ﺍﻷﻣﺮ.‬ ‫‪Example‬‬ ‫‪٤.٧: Enable A20 by Send 0xdd‬‬‫١‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٢‬‫:‪٣ ; enable a20 keyboard controller‬‬‫; ٤‬ ‫‪Enable A20 with command 0xdd‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٥‬‫٦‬‫:‪٧ enable a20 keyboard controller‬‬‫٨‬‫٩‬ ‫‪;cli‬‬ ‫٨٧‬
    • ‫02‪A‬‬ ‫٤.٢. ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ‬‫٠١‬ ‫‪push ax‬‬ ‫.‪; save register‬‬‫١١‬‫٢١‬ ‫‪mov al,0xdd‬‬ ‫.‪; Enable A20 Keyboard Controller Command‬‬‫٣١‬ ‫‪out 0x64,al‬‬‫٤١‬‫٥١‬ ‫‪pop ax‬‬ ‫.‪; restore register‬‬‫٦١‬ ‫‪ret‬‬‫ﻭﺗﻮﺟﺪ ﻃﺮﻳﻘﺔ ﺃﺧﺮﻯ ﺃﻛﺜﺮ ﳏﻤﻮﻟﻴﺔ ﻭﻫﻲ ﻋﻦ ﻃﺮﻳﻖ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ ‪ Output Port‬ﰲ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬ ‫ﻭﳝﻜﻦ ﻗﺮﺍءﺓ ﻫﺬﺍ ﺍﳌﻨﻔﺬ ﻭﺍﻟﻜﺘﺎﺑﺔ ﺍﻟﻴﻪ ﻋﻦ ﻃﺮﻳﻖ ﺍﺭﺳﺎﻝ ﺍﻻﻭﺍﻣﺮ 0‪ 0xd‬ﻭ 1‪ 0xd‬ﻋﻠﻰ ﺍﻟﺘﻮﺍﱄ.‬ ‫ﻭﻋﻨﺪ ﻗﺮﺍءﺓ ﻫﺬﺍ ﺍﳌﻨﻔﺬ )ﺑﺎﺭﺳﺎﻝ ﺍﻻﻣﺮ 0‪ d‬ﺍﱃ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ( ﻓﺎﻥ ﺍﻟﻘﻴﻢ ﺗﻌﲏ:‬ ‫ﺍﻟﺒﺖ 0: ‪:System Reset‬‬ ‫•‬ ‫– ﺍﻟﻘﻴﻤﺔ 0: ‪.Reset Computer‬‬ ‫– ﺍﻟﻘﻴﻤﺔ 1: ‪.Normal Opera on‬‬ ‫ﺍﻟﺒﺖ 1: ﺑﻮﺍﺑﺔ 02‪:A‬‬ ‫•‬ ‫– ﺍﻟﻘﻴﻤﺔ 0: ﺗﻌﻄﻴﻞ.‬ ‫– ﺍﻟﻘﻴﻤﺔ 1: ﺗﻔﻌﻴﻞ.‬ ‫ﺍﻟﺒﺘﺎﺕ 2-3: ﻏﲑ ﻣﻌﺮﻑ.‬ ‫•‬ ‫ﺍﻟﺒﺖ 4: ‪.Input Buffer Full‬‬ ‫•‬ ‫ﺍﻟﺒﺖ 5: ‪.Output Buffer Empty‬‬ ‫•‬ ‫ﺍﻟﺒﺖ 6: ‪:Keyboard Clock‬‬ ‫•‬ ‫– ﺍﻟﻘﻴﻤﺔ 0: ‪.High-Z‬‬ ‫– ﺍﻟﻘﻴﻤﺔ 1: ‪.Pull Clock Low‬‬ ‫ﺍﻟﺒﺖ 7: ‪:Keyboard Data‬‬ ‫•‬ ‫– ﺍﻟﻘﻴﻤﺔ 0: ‪.High-Z‬‬ ‫– ﺍﻟﻘﻴﻤﺔ 1: ‪.Pull Data Low‬‬‫ﻭﻋﻨﺪ ﺗﻔﻌﻴﻞ ﺍﻟﺒﺖ ﺭﻗﻢ 1 ﻓﺎﻥ ﻫﺬﺍ ﻳﻔﻌﻞ ﺑﻮﺍﺑﺔ 02‪ A‬ﻭﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻻﻣﺮ ‪ or‬ﺣﱴ ﻳﺘﻢ ﺍﳊﻔﺎﻅ ﻋﻠﻰ ﺑﻘﻴﺔ ﺍﻟﺒﺘﺎﺕ‬ ‫.ﻭﺑﻌﺪ ﺫﻟﻚ ﳚﺐ ﻛﺘﺎﺑﺔ ﺍﻟﻘﻴﻢ ﺍﱃ ﻧﻔﺲ ﺍﳌﻨﻔﺬ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺍﻻﻣﺮ 1‪. 0xd‬‬‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺗﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ 02‪ A‬ﻋﻦ ﻃﺮﻳﻖ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ ‪ Output Port‬ﳌﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.‬‫٩٧‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬ Example ٤.٨: Enable A20 by write to output port of Keyboard Controller١٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٣ ; enable a20 keyboard controller output port:٤ ; Enable A20 with write to keyboard output port.٥ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٦٧ enable a20 keyboard controller output port:٨٩ cli١٠ pusha ; save all registers١١١٢ call wait input ; wait last operation to be finished.١٣١٤ ;−−−−−−−−− −−−−−−−−−١٥ ; Disable Keyboard١٦ ;−−−−−−−−− −−−−−−−−−١٧ mov al,0xad ; disable keyboard command.١٨ out 0x64,al١٩ call wait input٢٠٢١ ;−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−٢٢ ; send read output port command٢٣ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−٢٤ mov al,0xd0 ; read output port command٢٥ out 0x64,al٢٦ call wait output ; wait output to come.٢٧ ; we dont need to wait input bescause when output came we know that operation are executed.٢٨٢٩ ;−−−−−−−−−−− −−−−−−−−−−−٣٠ ; read input buffer٣١ ;−−−−−−−−−−− −−−−−−−−−−−٣٢ in al,0x60٣٣ push eax ; save data.٣٤ call wait input٣٥٣٦ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−٣٧ ; send write output port command.٣٨ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−− ٨٠
    • ‫‪VGA‬‬ ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬‫٩٣‬ ‫1‪mov al,0xd‬‬ ‫.‪; write output port command‬‬‫٠٤‬ ‫‪out 0x64,al‬‬‫١٤‬ ‫‪call wait input‬‬‫٢٤‬‫٣٤‬ ‫−−−−−−;‬ ‫−−−−−−‬‫٤٤‬ ‫.02‪; enable a‬‬‫٥٤‬ ‫−−−−−−;‬ ‫−−−−−−‬‫٦٤‬ ‫‪pop eax‬‬‫٧٤‬ ‫2,‪or al‬‬ ‫.2 ‪; set bit‬‬‫٨٤‬ ‫‪out 0x60,al‬‬‫٩٤‬ ‫‪call wait input‬‬‫٠٥‬‫١٥‬ ‫−−−−−−−−;‬ ‫−−−−−−−−−‬‫٢٥‬ ‫.‪; Enable Keyboard‬‬‫٣٥‬ ‫−−−−−−−−;‬ ‫−−−−−−−−−‬‫٤٥‬ ‫‪mov al,0xae‬‬ ‫.‪; Enable Keyboard command‬‬‫٥٥‬ ‫‪out 0x64,al‬‬‫٦٥‬ ‫‪call wait input‬‬‫٧٥‬‫٨٥‬‫٩٥‬ ‫‪popa‬‬ ‫‪; restore registers‬‬‫٠٦‬ ‫‪sti‬‬‫١٦‬‫٢٦‬ ‫‪ret‬‬‫ﺣﻴﺚ ﰲ ﺍﻟﺒﺪﺍﻳﺔ ﰎ ﺗﻌﻄﻴﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﻋﻦ ﻃﺮﻳﻖ ﺍﺭﺳﺎﻝ ﺍﻻﻣﺮ ‪ (0xad‬ﻭﺍﺳﺘﺪﻋﺎء ﺍﻟﺪﺍﻟﺔ ‪ wait input‬ﻟﻠﺘﺄﻛﺪ‬‫ﻣﻦ ﺃﻥ ﺍﻻﻣﺮ ﻗﺪ ﰎ ﺗﻨﻔﻴﺬﻩ ﻭﻣﻦ ﰒ ﰎ ﺍﺭﺳﺎﻝ ﺃﻣﺮ ﻗﺮﺍءﺓ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ ﳌﺘﺤﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﺍﻻﻣﺮ ‪(0xda‬‬‫ﻭﺍﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﺣﱴ ﻳﻨﺘﻬﻲ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻻﻣﺮ ، ﻭﻗﺪ ﰎ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﺪﺍﻟﺔ ‪ wait output‬ﻻﻧﺘﻈﺎﺭ ﻗﻴﻤﺔ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ‬‫، ﻭﺑﻌﺪﻫﺎ ﰎ ﻗﺮﺍءﺓ ﻫﺬﻩ ﺍﻟﻘﻴﻤﺔ ﻭﺣﻔﻈﻬﺎ ﰲ ﺍﳌﻜﺪﺱ )‪، (Stack‬ﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﺍﺭﺳﺎﻝ ﺃﻣﺮ ﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ‬‫ﳌﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﺍﻻﻣﺮ 1‪ (0xd‬ﻭﺍﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﺣﻰ ﻳﻨﺘﻬﻲ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻻﻣﺮ ﻭﻣﻦ ﻗﻤﻨﺎ ﺑﺎﺭﺳﺎﻝ ﻗﻴﻤﺔ‬‫ﺍﳌﻨﻔﺬ ﺍﳋﺮﻭﺝ ﺍﳉﺪﻳﺪﺓ ﺑﻌﺪ ﺃﻥ ﰎ ﺗﻔﻌﻴﻞ ﺍﻟﺒﺖ ﺭﻗﻢ 1 ﻭﻫﻮ ﺍﻟﺒﺖ ﺍﻟﺬﻱ ﻳﻔﻌﻞ ﺑﻮﺍﺑﺔ 02‪ ، A‬ﻭﰲ ﺍﻻﺧﲑ ﰎ ﺗﻔﻌﻴﻞ‬ ‫ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﳎﺪﺩﺍ.‬ ‫‪VGA‬‬ ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬‫ﰲ ﻋﺎﻡ 7891 ﻗﺎﻣﺖ ‪ IBM‬ﺑﺘﻄﻮﻳﺮ ﻣﻘﻴﺎﺱ ﳌﺘﺤﻜﻤﺎﺕ ﺷﺎﺷﺔ ﺍﳊﺎﺳﺐ ﻭﻫﻮ ‪ Video Graphics Array‬ﻭﺍﺧﺘﺼﺎﺭﴽ‬‫‪ VGA‬ﻭﺟﺎﺋﺖ ﺗﺴﻤﻴﺘﻪ ﺏ ‪ Array‬ﻧﻈﺮﺍ ﻻﻧﻪ ﰎ ﺗﻄﻮﻳﺮﻩ ﻛﺸﺮﳛﺔ ﻭﺍﺣﺪﺓ ‪ signle chip‬ﺣﻴﺚ ﺍﺳﺘﺒﺪﻟﺖ ﺍﻟﻌﺪﻳﺪ‬‫ﻣﻦ ﺍﻟﺸﺮﺍﺋﺢ ﻭﺍﻟﱵ ﻛﺎﻧﺖ ﺗﺴﺘﺨﺪﻡ ﰲ ﻣﻘﺎﻳﻴﺲ ﺍﺧﺮﻯ ﻣﺜﻞ ‪ MDA‬ﻭ ‪ CGA‬ﻭ ‪ ، EGA‬ﻭﻳﺘﻜﻮﻥ ﺍﻝ ‪ VGA‬ﻣﻦ‬‫١٨‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫‪A ribute‬‬ ‫‪ Graphics Controller , Sequencer unit , CRT Controller , Video DAC ,Video Buffer‬ﻭ‬ ‫‪.٣ Controller‬‬‫ﺍﻝ ‪ Video Buffer‬ﻫﻮ ﻣﻘﻄﻊ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ‪ segment of memory‬ﻳﻌﻤﻞ ﻛﺬﺍﻛﺮﺓ ﻟﻠﺸﺎﺷﺔ ‪Memory Mapped‬‬‫، ﻭﻋﻨﺪ ﺑﺪﺍﻳﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ ﳜﺼﺺ ﻣﺴﺎﺣﺔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺑﺪءﺍ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0000‪ 0xa‬ﻛﺬﺍﻛﺮﺓ ﻟﻠﺸﺎﺷﺔ‬‫ﻭﰲ ﺣﺎﻟﺔ ﰎ ﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ﻫﺬﻩ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻥ ﻫﺬﺍ ﺳﻮﻑ ﻳﻐﲑ ﰲ ﺍﻟﺸﺎﺷﺔ ، ﻫﺬﺍ ﺍﻟﺮﺑﻂ ﻳﺴﻤﻰ ‪،Memory Mapping‬‬‫ﺃﻣﺎ ﺍﻝ ‪ Graphics Controller‬ﻓﻬﻮ ﺍﻟﺬﻱ ﻳﻘﻮﻡ ﺑﺘﺤﺪﻳﺚ ﳏﺘﻮﻳﺎﺕ ﺍﻟﺸﺎﺷﺔ ﺑﻨﺎءﴽ ﻋﻠﻰ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﺍﻝ‬ ‫‪.Video buffer‬‬‫ﻭﺗﺪﻋﻢ ﺍﻝ ‪ VGA‬ﳕﻄﲔ ﻟﻠﻌﺮﺽ ﺍﻻﻭﻝ ﻫﻮ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ ‪ Text Mode‬ﻭﺍﻻﺧﺮ ﻫﻮ ﺍﻟﻨﻤﻂ ﺍﻟﺮﺳﻮﻣﻲ ‪APA Graphics‬‬ ‫‪ Mode‬ﻭﳛﺪﺩ ﺍﻟﻨﻤﻂ ﻃﺮﻳﻘﺔ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻝ ‪ Video buffer‬ﻭﻛﻴﻔﺔ ﻋﺮﺽ ﺍﻟﺒﻴﺎﻧﺎﺕ.‬‫ﺍﻟﻨﻤﻂ ﺍﻟﺮﺳﻮﻣﻲ ‪ All Point Addressable Graphics Mode‬ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺒﻜﺴﻼﺕ ، ﺣﻴﺚ ﳝﻜﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ‬‫ﻛﻞ ﺑﺴﻜﻞ ﻣﻮﺟﻮﺩ ﻋﻠﻰ ﺣﺪﺓ . ﻭﺍﻟﺒﻜﺴﻞ ﻫﻮ ﺃﺻﻐﺮ ﻭﺣﺪﺓ ﰲ ﺍﻟﺸﺎﺷﺔ ﻭﺗﻌﺎﺩﻝ ﻧﻘﻄﺔ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ. ﺃﻣﺎ ﺍﻟﻨﻤﻂ‬‫ﺍﻟﻨﺼﻲ ‪ Text Mode‬ﻓﻴﻌﺘﻤﺪ ﻋﻠﻰ ﺍﳊﺮﻭﻑ ‪ ، Characters‬ﻭﻟﺘﻄﺒﻴﻖ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻓﺎﻥ ﻣﺘﺤﻜﻢ ﺍﻟﺸﺎﺷﺔ ‪Video‬‬‫‪ Controller‬ﻳﺴﺘﺨﺪﻡ ﺫﺍﻛﺮﺗﲔ ‪ two buffers‬ﺍﻻﻭﱃ ﻭﻫﻲ ﺧﺮﻳﻄﺔ ﺍﳊﺮﻭﻑ ‪ Character Map‬ﻭﻫﻲ ﺗﻌﺮﻑ‬‫ﺍﻟﺒﻜﺴﻼﺕ ﻟﻜﻞ ﺣﺮﻑ ﻭﳝﻜﻦ ﺗﻐﻴﲑ ﻫﺬﻩ ﺍﳋﺮﻳﻄﺔ ﻟﺪﻋﻢ ﺃﻧﻈﻤﺔ ﳏﺎﺭﻑ ﺃﺧﺮﻯ، ﺃﻣﺎ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺜﺎﻧﻴﺔ ﻓﻬﻲ‪Screen‬‬ ‫‪ Buffer‬ﻭﲟﺠﺮﺩ ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻴﻬﺎ ﻓﺎﻥ ﺍﻟﺘﺄﺛﲑ ﺳﻴﻈﻬﺮ ﻣﺒﺎﺷﺮﺓ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ.‬‫ﻭﻣﻘﻴﺎﺱ ‪ VGA‬ﻫﻮ ﻣﺒﲏ ﻋﻠﻰ ﺍﳌﻘﺎﻳﻴﺲ ﺍﻟﺴﺎﺑﻘﺔ ، ﺍﺑﺘﺪﺍءﺍ ﻣﻦ ﻣﻘﻴﺎﺱ ‪ Monochrome Display Adapter‬ﻭﻳﺴﻤﻰ‬‫ﺍﺧﺘﺼﺎﺭﺍ ‪ MDA‬ﻭﺍﻟﺬﻱ ﻃﻮﺭﺗﻪ ‪ IBM‬ﰲ ﻋﺎﻡ 1891 ، ﻭ ‪ MDA‬ﻻ ﺗﺪﻋﻢ ﺍﻟﻨﻤﻂ ﺍﻟﺮﺳﻮﻣﻲ ﻭﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ ‪‬ﺎ‬‫)ﻳﺴﻤﻰ 7 ‪ (Mode‬ﻳﺪﻋﻢ 08 ﻋﻤﻮﺩ ﻭ 42 ﺻﻒ ) 08*52(. ﻭﰲ ﻧﻔﺲ ﺍﻟﻌﺎﻡ ﻗﺎﻣﺖ ‪ IBM‬ﺑﺘﻄﻮﻳﺮ ﻣﻘﻴﺎﺱ‬‫‪) Color Graphics Adapter‬ﻭﺍﺧﺘﺼﺎﺭﺍ ‪ (CGA‬ﺍﻟﺬﻱ ﻛﺎﻥ ﺃﻭﻝ ﻣﺘﺤﻜﻢ ﻳﺪﻋﻢ ﺍﻻﻟﻮﺍﻥ ﺣﻴﺚ ﳝﻜﻦ ﻋﺮﺽ 61‬ ‫ﻟﻮﻥ ﳐﺘﻠﻒ.ﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﺗﻄﻮﻳﺮ ‪.Enhanced Graphics Adapter‬‬‫ﻭﳚﺪﺭ ﺑﻨﺎ ﺍﻟﺘﺬﻛﲑ ﺑﺎﻥ ﻣﺘﺤﻜﻤﺎﺕ ‪ VGA‬ﻣﺘﻮﺍﻓﻘﺔ ﻣﻊ ﺍﳌﻘﺎﻳﻴﺲ ﺍﻟﺴﺎﺑﻘﺔ ‪ Backward Compa ble‬ﻓﻌﻨﺪﻣﺎ ﻳﺒﺪﺃ‬‫ﺍﳊﺎﺳﺐ ﰲ ﺍﻟﻌﻤﻞ ﻓﺎﻥ ﺍﻟﻨﻤﻂ ﺳﻴﻜﻮﻥ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ 7 ‪) Mode‬ﺍﻟﺬﻱ ﻇﻬﺮ ﰲ ‪ ، (MDA‬ﻭﻫﺬﺍ ﻳﻌﲏ ﺍﻧﻨﺎ ﺳﻨﺘﻌﺎﻣﻞ‬ ‫ﻣﻊ 08 ﻋﻤﻮﺩ ﻭ 52 ﺻﻒ.‬ ‫‪VGA‬‬ ‫٤.٣.١. ﻋﻨﻮﻧﺔ ﺍﻟﺬﺍﻛﺮﺓ ﰲ ﻣﺘﺤﻜﻤﺎﺕ‬‫ﻋﻨﺪﻣﺎ ﻳﺒﺪﺃ ﺍﳊﺎﺳﺐ ﺑﺎﻟﻌﻤﻞ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ ﳜﺼﺺ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻣﻦ 0000‪ 0xa‬ﺍﱃ ‪ 0xbffff‬ﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ‬ ‫‪) Video memroy‬ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﻣﺘﺤﻜﻢ ‪ ، (VGA‬ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻣﻘﺴﻤﺔ ﻛﺎﻻﰐ:‬ ‫ﻣﻦ 0000‪ 0xb‬ﺍﱃ 7777‪ :0xb‬ﻟﻠﻨﻤﻂ ﺍﻟﻨﺼﻲ ﺃﺣﺎﺩﻱ ﺍﻟﻠﻮﻥ ‪.Monochrome Text Mode‬‬ ‫•‬ ‫ﻣﻦ 0008‪ 0xb‬ﺍﱃ ‪.Color Text Mode :0xbffff‬‬ ‫•‬‫ﻭﻋﻨﺪ ﺍﻟﻜﺘﺎﺑﺔ ﰲ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻓﺎﻥ ﻫﺬﺍ ﺳﻮﻑ ﻳﺆﺛﺮ ﰲ ﺍﻟﺸﺎﺷﺔ ﻭﺍﻇﻬﺎﺭ ﺍﻟﻘﻴﻢ ﺍﻟﱵ ﰎ ﻛﺘﺎﺑﺘﻬﺎ ، ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ‬ ‫ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﻛﺘﺎﺑﺔ ﺣﺮﻑ ‪ A‬ﺑﻠﻮﻥ ﺃﺑﻴﺾ ﻭﺧﻠﻔﻴﺔ ﺳﻮﺩﺍء.‬ ‫٣ﺷﺮﺡ ﻫﺬﻩ ﺍﳌﻜﻮﻧﺎﺕ ﺳﻴﻜﻮﻥ ﻻﺣﻘﺎ ﺑﺎﺫﻥ ﺍﷲ ، ﻭﺳﻴﺘﻢ ﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﺑﻌﺾ ﺍﻻﺷﻴﺎء ﲝﺴﺐ ﺍﳊﺎﺟﺔ ﺣﺎﻟﻴﺎ.‬ ‫٢٨‬
    • ‫‪VGA‬‬ ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬‫‪Example‬‬ ‫‪٤.٩: Print A character on screen‬‬‫١‬‫‪٢ %define VIDEO MEMORY‬‬ ‫0008‪0xb‬‬ ‫‪; Base Address of Mapped Video‬‬ ‫.‪Memory‬‬‫‪٣ %define CHAR ATTRIBUTE‬‬ ‫7‪0x‬‬ ‫.‪; White chracter on black background‬‬‫٤‬‫‪٥ mov edi,VIDEO MEMORY‬‬‫٦‬‫‪٧ mov [edi],A‬‬ ‫‪; print A‬‬‫‪٨ mov [edi+1],CHAR ATTRIBUTE‬‬ ‫‪; in white foreground black‬‬ ‫.‪background‬‬ ‫٤.٣.٢. ﻃﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ‬‫ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ ﺍﱃ ﻋﻨﻮﺍﻥ ﺍﻝ ‪ Video Memory‬ﻭﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﻃﺒﺎﻋﺔ‬‫ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳊﺮﻭﻑ ﻓﺎﻧﻪ ﳚﺐ ﺍﻧﺸﺎء ﻣﺘﻐﲑﺍﻥ )‪ (x,y‬ﳊﻔﻆ ﺍﳌﻜﺎﻥ ﺍﳊﺎﱄ ﻟﻠﺼﻒ ﻭﺍﻟﻌﻤﻮﺩ ﻭﻣﻦ ﰒ ﲢﻮﻳﻞ ﻫﺬﺍ‬‫ﺍﳌﻜﺎﻥ ﺍﱃ ﻋﻨﻮﺍﻥ ﰲ ﺍﻝ ‪ .Video Memoey‬ﻭﰲ ﺍﻟﺒﺪﺍﻳﺔ ﺳﺘﻜﻮﻥ ﻗﻴﻢ )‪ (x,y‬ﻫﻲ )0,0( ﺃﻱ ﺍﻥ ﺍﳊﺮﻑ ﺳﻴﻜﻮﻥ‬‫ﰲ ﺍﳉﺰء ﺍﻻﻋﻠﻲ ﻣﻦ ﺍﻟﻴﺴﺎﺭ ﰲ ﺍﻟﺸﺎﺷﺔ ﻭﳚﺐ ﺍﺭﺳﺎﻝ ﻫﺬﺍ ﺍﳊﺮﻑ ﺍﱃ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﻝ ‪ Video Memory‬ﻭﻫﻮ‬‫0008‪ .(Color text Mode) 0xb‬ﻭﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ ﺁﺧﺮ ﻓﺎﻥ ﻗﻴﻢ )‪ (x,y‬ﻟﻪ ﻫﻲ )1,0( ﻭﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ‬‫ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 1008‪ ، 0xb‬ﻭﺳﻨﺴﺘﺨﺪﻡ ﺍﻟﻌﻼﻗﺔ ﺍﻟﺘﺎﻟﻴﺔ ﻟﻠﺘﺤﻮﻳﻞ ﺑﲔ ﻗﻴﻢ )‪ (x,y‬ﺍﱃ ﻋﻨﺎﻭﻳﻦ ﻟﺬﺍﻛﺮﺓ ﺍﻟﻌﺮﺽ ‪Video‬‬ ‫‪:Memory‬‬‫0000‪videomemory = 0xb‬‬‫08 ∗ ‪videomemory+ = x + y‬‬‫ﻭﺑﺴﺒﺐ ﺃﻥ ﻫﻨﺎﻙ 08 ﺣﺮﻑ ﰲ ﻛﻞ ﻋﻤﻮﺩ ﻓﺎﻧﻪ ﳚﺐ ﺿﺮﺏ ﻗﻴﻤﺔ ‪ y‬ﺏ 08 . ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ‬ ‫ﻃﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻨﺪ )4,4( .‬‫08 ∗ ‪address = x + y‬‬‫423 = 08 ∗ 4 + 4 = ‪address‬‬‫.‪; now add the base address of video memory‬‬‫4418‪address = 324 + 0xb8000 = 0xb‬‬‫ﻭﺑﺎﺭﺳﺎﻝ ﺍﳊﺮﻑ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 4418‪ 0xb‬ﻓﺎﻥ ﺍﳊﺮﻑ ﺳﻮﻑ ﻳﻈﻬﺮ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ ﰲ ﺍﻟﺼﻒ ﺍﳋﺎﻣﺲ ﻭﺍﻟﻌﻤﻮﺩ‬ ‫ﺍﳋﺎﻣﺲ )ﺍﻟﺘﺮﻗﻴﻢ ﻳﺒﺪﺃ ﻣﻦ ﺻﻔﺮ ﻭﺃﻭﻝ ﺻﻒ ﻭﻋﻤﻮﺩ ﺭﻗﻤﻬﺎ ﺻﻔﺮ(.‬‫ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺍﻥ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ 7 ‪ Mode‬ﻫﻮ ﺍﻟﺬﻱ ﻳﺒﺪﺃ ﺍﳊﺎﺳﺐ ﺑﻪ ، ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻳﺘﻌﺎﻣﻞ ﻣﺘﺤﻜﻢ ﺍﻟﻌﺮﺽ‬‫٣٨‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫ﻣﻊ ﺑﺎﻳﺘﲔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻞ ﺣﺮﻑ ﻳﺮﺍﺩ ﻃﺒﺎﻋﺘﻪ ، ﲟﻌﲎ ﺍﺫﺍ ﻣﺎ ﺃﺭﺩﻧﺎ ﻃﺒﺎﻋﺔ ﺍﳊﺮﻑ ‪ A‬ﻓﺎﻧﻪ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ‬‫ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 0008‪ 0xb‬ﻭﺧﺼﺎﺋﺺ ﺍﳊﺮﻑ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺘﺎﱄ ﻟﻪ 1008‪ 0xb‬ﻭﻫﺬﺍ ﻳﻌﲏ ﺍﻧﻪ ﳚﺐ ﺗﻌﺪﻳﻞ ﻗﺎﻧﻮﻥ‬ ‫ﺍﻟﺘﺤﻮﻳﻞ ﺍﻟﺴﺎﺑﻖ ﻭﺍﻋﺘﺒﺎﺭ ﺃﻥ ﻛﻞ ﺣﺮﻑ ﻳﺄﺧﺬ ﺑﺎﻳﺘﲔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻟﻴﺲ ﺑﺎﻳﺖ ﻭﺍﺣﺪ.‬ ‫ﺍﻟﺒﺎﻳﺖ ﺍﻟﺜﺎﱐ ﻟﻠﺤﺮﻑ ﳛﺪﺩ ﻟﻮﻥ ﺍﳊﺮﻑ ﻭﻛﺜﺎﻓﺔ ﺍﻟﻠﻮﻥ )ﻏﺎﻣﻖ ﻭﻓﺎﺗﺢ( ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻟﺒﺘﺎﺕ ﻓﻴﻪ:‬ ‫ﺍﻟﺒﺘﺎﺕ 0-2: ﻟﻮﻥ ﺍﳊﺮﻑ:‬ ‫•‬ ‫– ﺍﻟﺒﺖ 0: ﺃﲪﺮ.‬ ‫– ﺍﻟﺒﺖ 1: ﺃﺧﻀﺮ.‬ ‫– ﺍﻟﺒﺖ 2: ﺃﺯﺭﻕ.‬ ‫ﺍﻟﺒﺖ 3: ﻛﺜﺎﻓﺔ ﻟﻮﻥ ﺍﳊﺮﻑ ) 0 ﻏﺎﻣﻖ ، 1 ﻓﺎﺗﺢ(.‬ ‫•‬ ‫ﺍﻟﺒﺖ 4-6: ﻟﻮﻥ ﺧﻠﻔﻴﺔ ﺍﳊﺮﻑ:‬ ‫•‬ ‫– ﺍﻟﺒﺖ 0: ﺃﲪﺮ.‬ ‫– ﺍﻟﺒﺖ 1: ﺃﺧﻀﺮ.‬ ‫– ﺍﻟﺒﺖ 2: ﺃﺯﺭﻕ.‬ ‫ﺍﻟﺒﺖ 7: ﻛﺜﺎﻓﺔ ﻟﻮﻥ ﺧﻠﻔﻴﺔ ﺍﳊﺮﻑ ) 0 ﻏﺎﻣﻖ ، 1 ﻓﺎﺗﺢ(.‬ ‫•‬ ‫ﻭﻫﻜﺬﺍ ﺗﻮﺟﺪ 4 ﺑﺖ ﻟﺘﺤﺪﻳﺪ ﺍﻟﻠﻮﻥ ، ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻫﺬﻩ ﺍﻷﻟﻮﺍﻥ:‬ ‫.‪• 0: Black‬‬ ‫.‪• 1: Blue‬‬ ‫.‪• 2: Green‬‬ ‫.‪• 3: Cyan‬‬ ‫.‪• 4: Red‬‬ ‫.‪• 5: Magneta‬‬ ‫.‪• 6: Brown‬‬ ‫.‪• 7: Light gray‬‬ ‫.‪• 8: Dark Gray‬‬ ‫.‪• 9: Light Blue‬‬ ‫.‪• 10: Light Green‬‬ ‫.‪• 11: Light Cyan‬‬ ‫٤٨‬
    • VGA ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬ • 12: Light Red. • 13: Light Magneta. • 14: Light Brown. • 15: White.‫ ﻓﺎﻧﻪ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ ﻭﺧﺼﺎﺋﺼﻪ ﺍﱃ ﺫﺍﻛﺮﺓ ﺍﻟﻌﺮﺽ ، ﻛﻤﺎ ﳚﺐ‬Mode 7 ‫ﺍﺫﴽ ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﻨﻤﻂ‬(‫ ﻳﻈﻬﺮ ﻭﳜﺘﻔﻲ ﻟﻠﺪﻻﻟﺔ ﻋﻠﻰ ﺍﳌﻮﻗﻊ ﺍﳊﺎﱄ‬underline ‫ )ﻫﻮ ﺧﻂ‬Cursor ‫ﻣﺮﺍﻋﺎﺓ ﺑﻌﺾ ﺍﻻﻣﻮﺭ ﻣﻦ ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ‬‫ﻭ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺼﻒ ﺍﻟﺘﺎﱄ ﰲ ﺣﺎﻟﺔ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺍﺧﺮ ﺣﺮﻑ ﰲ ﺍﻟﻌﻤﻮﺩ ﺃﻭ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳊﺮﻑ ﺍﳌﺮﺍﺩ ﻃﺒﺎﻋﺘﻪ‬‫ ﻭﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ‬putch32 ‫0 . ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻟﺪﺍﻟﺔ‬xa ‫ﻫﻮ ﺣﺮﻑ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺳﻄﺮ ﺟﺪﻳﺪ‬ .PMode ‫ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬ Example ٤.١٠: putch32 rou ne١٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٣ ; putch32: print character in protected mode.٤ ; input:٥ ; bl: character to print.٦ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٧٨ bits 32٩١٠ %define VIDEO MEMORY 0xb8000 ; Base Address of Mapped Video Memory.١١ %define COLUMNS 80 ; text mode (mode 7) has 80 columns,١٢ %define ROWS 25 ; and 25 rows.١٣ %define CHAR ATTRIBUTE 31 ; white on blue.١٤١٥ x pos db 0 ; current x position.١٦ y pos db 0 ; current y position.١٧١٨ putch32:١٩٢٠ pusha ; Save Registers.٢١٢٢ ;−−−−−−−−−−−−− −−−−−−−−−−−−−−٢٣ ; Check if bl is new line ?٢٤ ;−−−−−−−−−−−−− −−−−−−−−−−−−−−٢٥٨٥
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬٢٦ cmp bl,0xa ; if character is newline ?٢٧ je new row ; yes, jmp at end.٢٨٢٩ ;−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−٣٠ ; Calculate the memory offset٣١ ;−−−−−−−−−−−−−− −−−−−−−−−−−−−−−٣٢ ; because in text mode every character take 2 bytes: one for the character and one for the attribute, we must calculate the memory offset with the follwing formula:٣٣ ; offset = x pos ∗2 + y pos ∗COLUMNS∗2٣٤٣٥ xor eax,eax٣٦٣٧ mov al,2٣٨ mul byte[x pos]٣٩ push eax ; save the first section of formula.٤٠٤١ xor eax,eax٤٢ xor ecx,ecx٤٣٤٤ mov ax,COLUMNS∗2 ; 80∗2٤٥ mov cl,byte[y pos]٤٦ mul ecx٤٧٤٨ pop ecx٤٩ add eax,ecx٥٠٥١ add eax,VIDEO MEMORY ; eax = address to print the character.٥٢٥٣ ;−−−−−−−−−− −−−−−−−−−−−٥٤ ; Print the chracter.٥٥ ;−−−−−−−−−− −−−−−−−−−−−٥٦٥٧ mov edi,eax٥٨٥٩ mov byte[edi],bl ; print the character,٦٠ mov byte[edi+1],CHAR ATTRIBUTE ; with respect to the attribute.٦١٦٢ ;−−−−−−−−−− −−−−−−−−−−−٦٣ ; Update the postions. ٨٦
    • ‫‪VGA‬‬ ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬‫٤٦‬ ‫−−−−−−−−−−;‬ ‫−−−−−−−−−−−‬‫٥٦‬‫٦٦‬ ‫]‪inc byte[x pos‬‬‫٧٦‬ ‫‪cmp byte[x pos],COLUMNS‬‬‫٨٦‬ ‫‪je new row‬‬‫٩٦‬‫٠٧‬ ‫‪jmp putch32 end‬‬‫١٧‬‫٢٧‬‫٣٧‬ ‫:‪new row‬‬‫٤٧‬‫٥٧‬ ‫0,]‪mov byte[x pos‬‬ ‫.‪; clear the x pos‬‬‫٦٧‬ ‫]‪inc byte[y pos‬‬ ‫.‪; increment the y pos‬‬‫٧٧‬‫٨٧‬ ‫:‪putch32 end‬‬‫٩٧‬‫٠٨‬ ‫‪popa‬‬ ‫.‪; Restore Registers‬‬‫١٨‬‫٢٨‬ ‫‪ret‬‬‫ﻭﺗﺒﺪﺃ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﺑﻔﺤﺺ ﺍﳊﺮﻑ ﺍﳌﺮﺍﺩ ﻃﺒﺎﻋﺘﻪ )ﻣﻮﺟﻮﺩ ﰲ ﺍﳌﺴﺠﻞ ‪ (bl‬ﻣﻊ ﺣﺮﻑ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺴﻄﺮ ﺍﳉﺪﻳﺪ‬‫‪ 0xa‬ﻭﰲ ﺣﺎﻟﺔ ﺍﻟﺘﺴﺎﻭﻱ ﻳﺘﻢ ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺁﺧﺮ ﺟﺴﻢ ﺍﻟﺪﺍﻟﺔ ﻭﺍﻟﺬﻱ ﻳﻘﻮﻡ ﺑﺘﺼﻔﲑ ﻗﻴﻤﺔ ‪ x‬ﻭﺯﻳﺎﺩﺓ ﻗﻴﻤﺔ ‪y‬‬‫ﺩﻻﻟﺔ ﻋﻠﻰ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺴﻄﺮ ﺍﳉﺪﻳﺪ. ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳊﺮﻑ ﻫﻮ ﺃﻱ ﺣﺮﻑ ﺁﺧﺮ ﻓﺎﻧﻪ ﳚﺐ ﺣﺴﺎﺏ ﺍﻟﻌﻨﻮﺍﻥ‬‫ﺍﻟﺬﻱ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ ﺍﻟﻴﻪ ﺣﱴ ﳝﻜﻦ ﻃﺒﺎﻋﺘﻪ ، ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺃﻥ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ 7 ‪ Mode‬ﻳﺴﺘﺨﺪﻡ ﺑﺎﻳﺘﲔ‬ ‫ﻟﻜﻞ ﺣﺮﻑ ﻟﺬﺍ ﺳﻴﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻼﻗﺔ ﺍﻟﺘﺎﻟﻴﺔ ﻟﻠﺘﺤﻮﻳﻞ ﻣﺎ ﺑﲔ )‪ (x,y‬ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻮﺏ.‬‫0000‪videomemory = 0xb‬‬‫2 ∗ 08 ∗ ‪videomemory+ = x ∗ 2 + y‬‬‫ﻭﻛﻤﺎ ﻳﻈﻬﺮ ﰲ ﺍﻟﻜﻮﺩ ﺍﻟﺴﺎﺑﻖ ﻓﻘﺪ ﰎ ﺣﺴﺎﺏ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻭﺣﻔﻈﻪ ﰲ ﺍﳌﺴﺠﻞ ‪ eax‬ﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﻃﺒﺎﻋﺔ‬‫ﺍﳊﺮﻑ ﺍﳌﻄﻠﻮﺏ ﺑﺎﳋﺼﺎﺋﺺ ﺍﻟﱵ ﰎ ﲢﺪﻳﺪﻫﺎ ﻣﺴﺒﻘﺎ ﻛﺜﺎﺑﺖ. ﻭﺁﺧﺮ ﺧﻄﻮﺓ ﰲ ﺍﻟﺪﺍﻟﺔ ﻫﻲ ﺯﻳﺎﺩﺓ ﻗﻴﻢ )‪ (x,y‬ﻟﻠﺪﺍﻟﺔ‬‫ﺍﱃ ﺍﳌﻜﺎﻥ ﺍﻟﺘﺎﱄ ، ﻭﻫﺬﺍ ﻳﺘﻢ ﺑﺰﻳﺎﺩﺓ ‪ x‬ﻓﻘﻂ ﻭﰲ ﺣﺎﻟﺔ ﺗﺴﺎﻭﺕ ﺍﻟﻘﻴﻤﺔ ﻣﻊ ﻗﻴﻤﺔ ﺁﺧﺮ ﻋﻤﻮﺩ ﰲ ﺍﻟﺼﻒ ﻓﺎﻧﻪ ﻳﺘﻢ‬ ‫ﺯﻳﺎﺩﺓ ﻗﻴﻤﺔ ‪ y‬ﻭﺗﺼﻔﲑ ‪ x‬ﺩﻻﻟﺔ ﻋﻠﻰ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺼﻒ ﺍﻟﺘﺎﱄ.‬ ‫‪strings‬‬ ‫٤.٣.٣. ﻃﺒﺎﻋﺔ ﺍﻟﺴﻼﺳﻞ ﺍﻟﻨﺼﻴﺔ‬‫ﻟﻄﺒﺎﻋﺔ ﺳﻠﺴﻠﺔ ﻧﺼﻴﺔ ﺳﻨﺴﺘﺨﺪﻡ ﺩﺍﻟﺔ ﻃﺒﺎﻋﺔ ﺍﳊﺮﻑ ﻭﺳﻨﻘﻮﻡ ﺑﺄﺧﺬ ﺣﺮﻑ ﺣﺮﻑ ﻣﻦ ﺍﻟﺴﻠﺴﺔ ﻭﺍﺭﺳﺎﳍﺎ ﺍﱃ ﺩﺍﻟﺔ‬ ‫ﻃﺒﺎﻋﺔ ﺍﳊﺮﻑ ﺣﱴ ﺗﻨﺘﻬﻲ ﺍﻟﺴﻠﺴﻠﺔ ، ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﺍﻟﺪﺍﻟﺔ 23‪ puts‬ﻟﻄﺒﺎﻋﺔ ﺳﻠﺴﻠﺔ ﻧﺼﻴﺔ.‬ ‫‪Example‬‬ ‫‪٤.١١: puts32 rou‬‬ ‫‪ne‬‬‫٧٨‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬١٢٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٤ ; puts32: print string in protected mode.٥ ; input:٦ ; ebx: point to the string٧ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٨٩ bits 32١٠١١ puts32:١٢١٣ pusha ; Save Registers.١٤١٥ mov edi,ebx١٦١٧ @loop:١٨ mov bl,byte[edi] ; read character.١٩٢٠ cmp bl,0x0 ; end of string ?٢١ je puts32 end ; yes, jmp to end.٢٢٢٣ call putch32 ; print the character.٢٤٢٥ inc edi ; point to the next character.٢٦٢٧ jmp @loop٢٨٢٩ puts32 end:٣٠٣١ ;−−−−−−−−−−−−−− −−−−−−−−−−−−−−٣٢ ; Update the Hardware Cursor.٣٣ ;−−−−−−−−−−−−−− −−−−−−−−−−−−−−−٣٤ ; After print the string update the hardware cursor.٣٥٣٦ mov bl,byte[x pos]٣٧ mov bh,byte[y pos]٣٨٣٩ call move cursor٤٠٤١ popa ; Restore Registers. ٨٨
    • ‫‪VGA‬‬ ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬‫٢٤‬‫٣٤‬ ‫‪ret‬‬‫ﰲ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﺣﺮﻑ ﺣﺮﻑ ﻣﻦ ﺍﻟﺴﻠﺴﺔ ﺍﻟﻨﺼﻴﺔ ﻭﻃﺒﺎﻋﺘﻪ ﺍﱃ ﺃﻥ ﻧﺼﻞ ﺍﱃ ‪‬ﺎﻳﺔ ﺍﻟﺴﻠﺴﻠﺔ )ﺍﻟﻘﻴﻤﺔ‬‫0‪ ، (0x‬ﻭﺑﻌﺪ ﺫﻟﻚ ﺳﻴﺘﻢ ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ ﻭﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﻣﺘﺤﻜﻢ ‪ CRT Controller‬ﻭﻧﻈﺮﴽ ﻻﻥ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ‬ ‫ﺑﻄﺊ ﻗﻠﻴﻼ ﻓﺎﻥ ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ ﺳﻴﻜﻮﻥ ﺑﻌﺪ ﻃﺒﺎﻋﺔ ﺍﻟﺴﻠﺴﻠﺔ ﻭﻟﻴﺲ ﺑﻌﺪ ﻃﺒﺎﻋﺔ ﻛﻞ ﺣﺮﻑ .‬ ‫‪Hardware Cursor‬‬ ‫٤.٣.٤. ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ‬‫ﻋﻨﺪ ﻃﺒﺎﻋﺔ ﺣﺮﻑ ﺍﻭ ﺳﻠﺴﻠﺔ ﻧﺼﻴﺔ ﻓﺎﻥ ﻣﺆﺷﺮ ﺍﻟﻜﺘﺎﺑﺔ ﻻ ﻳﺘﺤﺮﻙ ﻣﻦ ﻣﻜﺎﻧﻪ ﺍﻻ ﻋﻨﺪ ﲢﺪﻳﺪﻩ ﻳﺪﻭﻳﺎ ، ﻭﻫﺬﺍ ﻳﺘﻢ‬‫ﻋﻦ ﻃﺮﻳﻖ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﻣﺘﺤﻜﻢ ‪ . CRT Controller‬ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﳛﻮﻱ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﻭﻟﻜﻨﻨﺎ ﺳﻮﻑ‬ ‫ﻧﺮﻛﺰ ﻋﻠﻰ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪ Data Register‬ﻭﻣﺴﺠﻞ ﻧﻮﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪.Index Register‬‬‫ﻭﻻﺭﺳﺎﻝ ﺑﻴﺎﻧﺎﺕ ﺍﱃ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ، ﻓﻴﺠﺐ ﺍﻭﻻ ﲢﺪﻳﺪ ﻧﻮﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺫﻟﻚ ﺑﺎﺭﺳﺎﳍﺎ ﺍﱃ ﻣﺴﺠﻞ ‪Index‬‬‫‪ Register‬ﻭﻣﻦ ﰒ ﺍﺭﺳﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪ ، Data Register‬ﻭﰲ ﺣﻮﺍﺳﻴﺐ 68‪ x‬ﻓﺎﻥ ﻣﺴﺠﻞ‬ ‫ﺍﻟﺒﻴﺎﻧﺎﺕ ﻳﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ 5‪ 0x3d‬ﻭﻣﺴﺠﻞ ‪ Index Register‬ﻳﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ 4‪.0x3d‬‬ ‫ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻟﻘﻴﻢ ﺍﻟﱵ ﳝﻜﻦ ﺍﺭﺳﺎﳍﺎ ﺍﱃ ﻣﺴﺠﻞ ﻧﻮﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪.Index Register‬‬ ‫.‪• 0x0: Horizontal Total‬‬ ‫.‪• 0x1: Horizontal Display Enable End‬‬ ‫.‪• 0x2: Start Horizontal Blanking‬‬ ‫.‪• 0x3: End Horizontal Blanking‬‬ ‫.‪• 0x4: Start Horizontal Retrace Pulse‬‬ ‫.‪• 0x5: End Horizontal Retrace‬‬ ‫.‪• 0x6: Ver cal Total‬‬ ‫.‪• 0x7: Overflow‬‬ ‫.‪• 0x8: Preset Row Scan‬‬ ‫.‪• 0x9: Maximum Scan Line‬‬ ‫.‪• 0xa: Cursor Start‬‬ ‫.‪• 0xb: Cursor End‬‬ ‫.‪• 0xc: Start Address High‬‬‫٩٨‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬ ‫.‪• 0xd: Start Address Low‬‬ ‫.‪• 0xe: Cursor Loca on High‬‬ ‫.‪• 0xf : Cursor Loca on Low‬‬ ‫.‪• 0x10: Ver cal Retrace Start‬‬ ‫.‪• 0x11: Ver cal Retrace End‬‬ ‫.‪• 0x12: Ver cal Display Enable End‬‬ ‫.‪• 0x13: Offset‬‬ ‫.‪• 0x14: Underline Loca on‬‬ ‫.‪• 0x15: Start Ver cal Blanking‬‬ ‫.‪• 0x16: End Ver cal Blanking‬‬ ‫.‪• 0x17: CRT Mode Control‬‬ ‫.‪• 0x18: Line Compare‬‬‫ﻭﻋﻨﺪ ﺍﺭﺳﺎﻝ ﺃﻱ ﻣﻦ ﺍﻟﻘﻴﻢ ﺍﻟﺴﺎﺑﻘﺔ ﺍﱃ ﻣﺴﺠﻞ ‪ Index Reigster‬ﻓﺎﻥ ﻫﺬﺍ ﺳﻴﺤﺪﺩ ﻧﻮﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﱵ ﺳﺘﺮﺳﻞ‬‫ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪ .Data Register‬ﻭﻣﻦ ﺍﳉﺪﻭﻝ ﺍﻟﺴﺎﺑﻖ ﺳﻨﺠﺪ ﺃﻥ ﺍﻟﻘﻴﻤﺔ ‪ 0xf‬ﺳﺘﺤﺪﺩ ﻗﻴﻤﺔ ‪ x‬ﻟﻠﻤﺆﺷﺮ ،‬‫ﻭﺍﻟﻘﻴﻤﺔ ‪ 0xe‬ﺳﺘﺤﺪﺩ ﻗﻴﻤﺔ ‪ y‬ﻟﻠﻤﺆﺷﺮ.ﻭﺑﻌﺪ ﺫﻟﻚ ﳚﺐ ﺍﺭﺳﺎﻝ ﻗﻴﻢ ‪ x,y‬ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻋﻠﻰ ﺍﻟﺘﻮﺍﱄ ﻣﻊ‬‫ﻣﻼﺣﻈﺔ ﺃﻥ ﻣﺘﺤﻜﻢ ‪ CRT‬ﻳﺘﻌﺎﻣﻞ ﻣﻊ ﺑﺎﻳﺖ ﻭﺍﺣﺪ ﻟﻜﻞ ﺣﺮﻑ ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻧﻨﺎ ﺳﻨﺴﺘﺨﺪﻡ ﺍﻟﻘﺎﻧﻮﻥ ﺍﻟﺘﺎﱄ ﻟﻠﺘﺤﻮﻳﻞ‬ ‫ﻣﻦ ﻗﻴﻢ )‪ (x,y‬ﺍﱃ ﻋﻨﺎﻭﻳﻦ.‬‫08 ∗ ‪videomemory = x + y‬‬ ‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻋﻤﻞ ﺍﻟﺪﺍﻟﺔ ‪ move cursor‬ﻭﺍﻟﱵ ﺗﻌﻤﻞ ﻋﻠﻰ ﲢﺮﻳﻚ ﺍﳌﺆﺷﺮ.‬ ‫‪Example‬‬ ‫‪٤.١٢: Move Hardware Cursor‬‬‫١‬‫; ٢‬ ‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗‬‫.‪٣ ; move cursor: Move the Hardware Cursor‬‬‫; ٤‬ ‫:‪input‬‬‫; ٥‬ ‫.‪bl: x pos‬‬‫; ٦‬ ‫.‪bh: y pos‬‬‫; ٧‬ ‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗‬‫٨‬‫‪٩ bits‬‬ ‫23‬‫٠١‬ ‫٠٩‬
    • VGA ‫٤.٣. ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ‬١١ move cursor:١٢١٣ pusha ; Save Registers.١٤١٥ ;−−−−−−−−−−− −−−−−−−−−−−١٦ ; Calculate the offset.١٧ ;−−−−−−−−−−− −−−−−−−−−−−١٨ ; offset = x pos + y pos ∗COLUMNS١٩٢٠ xor ecx,ecx٢١ mov cl,byte[x pos]٢٢٢٣ mov eax,COLUMNS٢٤ mul byte[y pos]٢٥٢٦ add eax,ecx٢٧ mov ebx,eax٢٨٢٩ ;−−−−−−−−−− −−−−−−−−−−٣٠ ; Cursor Location Low.٣١ ;−−−−−−−−−− −−−−−−−−−−−٣٢٣٣ mov al,0xf٣٤ mov dx,0x3d4٣٥ out dx,al٣٦٣٧ mov al,bl٣٨ mov dx,0x3d5٣٩ out dx,al٤٠٤١ ;−−−−−−−−−−− −−−−−−−−−−−٤٢ ; Cursor Location High.٤٣ ;−−−−−−−−−−− −−−−−−−−−−−٤٤٤٥ mov al,0xe٤٦ mov dx,0x3d4٤٧ out dx,al٤٨٤٩ mov al,bh٥٠ mov dx,0x3d5٥١ out dx,al٩١
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬٥٢٥٣٥٤ popa ; Restore Registers.٥٥٥٦ ret Clear Screen ‫٤.٣.٥. ﺗﻨﻈﻴﻒ ﺍﻟﺸﺎﺷﺔ‬‫( ﻭ ﺗﺼﻔﲑ‬Mode 7 ‫ﺗﻨﻈﻴﻒ ﺍﻟﺸﺎﺷﺔ ﻫﻲ ﻋﻤﻠﻴﺔ ﺍﺭﺳﺎﻝ ﺣﺮﻑ ﺍﳌﺴﺎﻓﺔ ﺑﻌﺪﺩ ﺍﳊﺮﻭﻑ ﺍﳌﻮﺟﻮﺩﺓ )08*52 ﰲ ﳕﻂ‬ .‫( . ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺗﻨﻈﻴﻒ ﺍﻟﺸﺎﺷﺔ ﻭﲢﺪﻳﺪ ﺍﻟﻠﻮﻥ ﺍﻻﺯﺭﻕ ﻛﺨﻠﻔﻴﺔ ﻟﻜﻞ ﺣﺮﻑ‬x,y) ‫ﻗﻴﻢ‬ Example ٤.١٣: Clear Screen١٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٣ ; clear screen: Clear Screen in protected mode.٤ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٥٦ bits 32٧٨ clear screen:٩١٠ pusha ; Save Registers.١١ cld١٢١٣ mov edi,VIDEO MEMORY ; base address of video memory.١٤ mov cx,2000 ; 25∗80١٥ mov ah,CHAR ATTRIBUTE ; 31 = white character on blue background.١٦ mov al, ١٧١٨ rep stosw١٩٢٠ mov byte[x pos],0٢١ mov byte[y pos],0٢٢٢٣ popa ; Restore Registers.٢٤٢٥ ret ٩٢
    • ‫٤.٤. ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ‬ ‫٤.٤. ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ‬‫ﺍﱃ ﻫﻨﺎ ﺗﻨﺘﻬﻲ ﻣﻬﻤﺔ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ‪ Second Stage Bootloader‬ﻭﻳﺘﺒﻘﻰ ﻓﻘﻂ ﺍﻟﺒﺤﺚ ﻋﻦ‬‫ﺍﻟﻨﻮﺍﺓ ﻭﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ ٤. ﻭﰲ ﻫﺬﺍ ﺍﳉﺰء ﺳﻴﺘﻢ ﻛﺘﺎﺑﺔ ﻧﻮﺍﺓ ﲡﺮﻳﺒﻴﺔ ‪‬ﺪﻑ ﺍﻟﺘﺄﻛﺪ ﻣﻦ ﻋﻤﻠﻴﺔ ﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﱃ‬ ‫ﺍﻟﻨﻮﺍﺓ ﻭﻛﺬﻟﻚ ‪‬ﺪﻑ ﺇﻋﺎﺩﺓ ﻛﺘﺎﺑﺔ ﺷﻔﺮﺓ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺑﺸﻜﻞ ﺃﻓﻀﻞ.‬‫ﻭﺳﻴﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻟﻜﺘﺎﺑﺔ ﻫﺬﻩ ﺍﻟﻨﻮﺍﺓ ﺍﻟﺘﺠﺮﻳﺒﻴﺔ ﺣﻴﺚ ﺃﻥ ﺍﳌﻠﻒ ﺍﻟﻨﺎﺗﺞ ﺳﻴﻜﻮﻥ ‪ Pure Binary‬ﻭﻻ‬‫ﳛﺘﺎﺝ ﺍﱃ ﳏﻤﻞ ﺧﺎﺹ ، ﻭﺍﺑﺘﺪﺍءﴽ ﻣﻦ ﺍﻟﻔﺼﻞ ﺍﻟﻘﺎﺩﻡ ﺳﻨﺘﺮﻙ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺟﺎﻧﺒﺎ ﻭﻧﺒﺪﺃ ﺍﻟﻌﻤﻞ ﺑﻠﻐﺔ ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++‬ ‫.‬‫ﻭﲟﺎ ﺃﻧﻨﺎ ﻧﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ‪ PMode‬ﻓﻼ ﳝﻜﻨﻨﺎ ﺃﻥ ﻧﺴﺘﺨﺪﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 31‪ int 0x‬ﻟﺘﺤﻤﻴﻞ‬‫ﻗﻄﺎﻋﺎﺕ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ، ﻭﳚﺐ ﺃﻥ ﻧﻘﻮﻡ ﺑﻜﺘﺎﺑﺔ ﺩﺭﺍﻳﻔﺮ ﳌﺤﺮﻙ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺃﻭ ﻧﻘﻮﻡ ﺑﺘﺤﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺍﱃ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﻗﺒﻞ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﻫﺬﺍ ﻣﺎ ﺳﻨﻔﻌﻠﻪ ﺍﻻﻥ ، ﻭﺳﻨﺘﺮﻙ ﺟﺰﺋﻴﺔ ﺑﺮﳎﺔ ﳏﺮﻙ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻻﺣﻘﺎ.‬‫ﻭﺣﻴﺚ ﺃﻥ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻳﺴﻤﺢ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺫﺍﻛﺮﺓ ﺣﱴ 4 ﺟﻴﺠﺎ ، ﻓﺎﻥ ﺍﻟﻨﻮﺍﺓ ﺳﻨﻘﻮﻡ ﺑﺘﺤﻤﻴﻠﻬﺎ ﻋﻠﻰ ﺍﻟﻌﻨﻮﺍﻥ‬‫000001‪ 0x‬ﺃﻱ ﻋﻨﺪ 1 ﻣﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ .ﻟﻜﻦ ﻋﻠﻴﻨﺎ ﺍﻟﺘﺬﻛﺮ ﺑﺄﻥ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻻ ﻳﺪﻋﻢ ﺍﻟﻮﺻﻮﻝ ﺍﱃ‬‫ﺍﻟﻌﻨﻮﺍﻥ 000001‪ 0x‬ﻟﺬﻟﻚ ﺳﻨﻘﻮﻡ ﺑﺘﺤﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺃﻭﻻ ﰲ ﺃﻱ ﻋﻨﻮﺍﻥ ﺧﺎﱄ ﻭﻟﻴﻜﻦ 0003‪ 0x‬ﻭﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ‬ ‫ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺳﻨﻘﻮﻡ ﺑﻨﺴﺨﻬﺎ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 000001‪ 0x‬ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﻭﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ.‬ ‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻧﻮﺍﺓ ﺗﺮﺣﻴﺒﻴﺔ.‬ ‫‪Example‬‬ ‫‪٤.١٤: Hello Kernel‬‬‫١‬‫‪٢ org‬‬ ‫000001‪0x‬‬ ‫.‪; kernel will load at 1 MB‬‬‫٣‬‫‪٤ bits‬‬ ‫23‬ ‫.‪; PMode‬‬‫٥‬‫‪٦ jmp kernel entry‬‬‫٧‬‫"‪٨ %include "stdio.inc‬‬‫٩‬‫٠١‬‫١١‬‫‪١٢ kernel message‬‬ ‫‪db‬‬ ‫",‪0xa,0xa,0xa‬‬ ‫1.0‪eqraOS v‬‬ ‫"‪Copyright (C) 2010 Ahmad Essam‬‬‫٣١‬ ‫‪db‬‬ ‫,‪0xa,0xa‬‬ ‫"‬ ‫‪University of Khartoum − Faculty‬‬ ‫0,".‪of Mathematical Sceinces‬‬‫٤١‬‫٥١‬ ‫٤ﺍﻟﻔﺼﻞ ﺍﻟﺘﺎﱄ ﺳﻴﺘﻨﺎﻭﻝ ﻣﻮﺿﻮﻉ ﺍﻟﻨﻮﺍﺓ ﻭﻛﻴﻔﻴﺔ ﺑﺮﳎﺘﻬﺎ ﺑﺎﻟﺘﻔﺼﻴﻞ.‬‫٣٩‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬١٦ logo message db 0xa,0xa,0xa," / / /"١٧ db 0xa, " / − ) `/ / `/ / / / / "١٨ db 0xa, " / , / / , / // / "١٩ db 0xa, " / / ",0٢٠ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢١ ; Entry point.٢٢ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٣٢٤ kernel entry:٢٥٢٦ ;−−−−−−− −−−−−−−−٢٧ ; Set Registers٢٨ ;−−−−−−− −−−−−−−−٢٩٣٠ mov ax,0x10 ; data selector.٣١ mov ds,ax٣٢ mov es,ax٣٣ mov ss,ax٣٤ mov esp,0x90000 ; set stack.٣٥٣٦ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−٣٧ ; Clear Screen and print message.٣٨ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−٣٩٤٠ call clear screen٤١٤٢ mov ebx,kernel message٤٣ call puts32٤٤٤٥ mov ebx,logo message٤٦ call puts32٤٧٤٨ ;−−−−−−−− −−−−−−−−−٤٩ ; Halt the system.٥٠ ;−−−−−−−− −−−−−−−−−٥١٥٢ cli ٩٤
    • ‫٤.٤. ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ‬‫٣٥‬ ‫‪hlt‬‬‫ﻭﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺳﺘﻜﻮﻥ ﻫﻲ ﺍﳌﺴﺆﻭﻟﺔ ﻋﻦ ﺍﻟﺒﺤﺚ ﻋﻦ ﺍﻟﻨﻮﺍﺓ ﻭﲢﻤﻴﻠﻬﺎ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ،‬‫ﻭﺳﻴﺘﻢ ﲢﻤﻴﻠﻬﺎ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻗﺒﻞ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﺫﻟﻚ ﺣﱴ ﻧﺘﻜﻤﻦ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ‬‫31‪ int 0x‬ﻭﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺳﻴﺘﻢ ﻧﺴﺦ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﻋﻨﻮﺍﻥ 1 ﻣﻴﺠﺎ ﻭﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﱃ ﺍﻟﻨﻮﺍﺓ.‬‫ﻭﻟﺘﺤﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﳚﺐ ﺃﻭﻻ ﲢﻤﻴﻞ ‪ Root Directory‬ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﻟﺒﺤﺚ ﻋﻦ ﻣﻠﻒ ﺍﻟﻨﻮﺍﺓ ﻭﰲ ﺣﺎﻟﺔ‬‫ﻛﺎﻥ ﺍﳌﻠﻒ ﻣﻮﺟﻮﺩﺍ ﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻪ ، ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﺳﻴﻌﻤﻞ ﻙ ‪ index‬ﰲ ﺟﺪﻭﻝ ‪) FAT‬ﻭﺍﻟﺬﻱ‬‫ﳚﺐ ﲢﻤﻴﻠﻪ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻳﻀﺎ( ﻭﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻘﺎﺑﻠﺔ ﳍﺬﺍ ﺍﻝ ‪ index‬ﻭﺍﻟﱵ ﺳﺘﺨﱪﻧﺎ ﻫﻞ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﻫﺬﺍ‬ ‫ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺁﺧﺮ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ﺃﻡ ﻻ ٥.‬‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻣﻠﻒ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﺍﳌﺤﻤﻞ ‪ ، stage2.asm‬ﻭﰎ ﺗﻘﺴﻴﻢ ﺍﻟﻜﻮﺩ ﺑﺸﻜﻞ ﺃﻛﺜﺮ ﺗﻨﻈﻴﻤﺎ‬‫ﺣﻴﺚ ﰎ ﻧﻘﻞ ﺃﻱ ﺩﺍﻟﺔ ﺗﺘﻌﻠﻖ ﺑﺎﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺍﱃ ﺍﳌﻠﻒ ‪) floppy.inc‬ﻣﻠﻒ ‪ .inc‬ﻫﻮ ﻣﻠﻒ ﻟﻠﺘﻀﻤﲔ ﰲ ﻣﻠﻒ ﺁﺧﺮ(‬‫، ﻭﺍﻟﺪﻭﺍﻝ ﺍﳌﺘﻌﻠﻘﺔ ﺑﻨﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﻠﻒ ‪ fat12.inc‬ﻭﺩﻭﺍﻝ ﺍﻻﺧﺮﺍﺝ ﻣﻮﺟﻮﺩﺓ ﰲ ‪ stdio.inc‬ﻭﺩﻭﺍﻝ‬‫ﺗﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ 02‪ A‬ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﻠﻒ ‪ a20.inc‬ﻭﺩﺍﻟﺔ ﺗﻌﻴﲔ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ﻭﻛﺬﻟﻚ ﺗﻔﺎﺻﻴﻞ ﺍﳉﺪﻭﻝ‬ ‫ﻣﻮﺟﻮﺩﺓ ﰲ ﺍﳌﻠﻒ ‪ ، gdt.inc‬ﺍﺧﲑﺍ ﰎ ﺍﻧﺸﺎء ﻣﻠﻒ ‪ common.inc‬ﳊﻔﻆ ﺑﻌﺾ ﺍﻟﺜﻮﺍﺑﺖ ﺍﳌﺴﺘﺨﺪﻣﺔ ﺩﺍﺋﻤﺎ ٦.‬ ‫‪Example‬‬ ‫‪٤.١٥: Loading and Execu‬‬ ‫‪ng Kernel: Full Example‬‬‫١‬‫٢‬‫61 ‪٣ bits‬‬ ‫.‪; 16−bit real mode‬‬‫005‪٤ org 0x‬‬‫٥‬‫:‪٦ start‬‬ ‫2‪jmp stage‬‬‫٧‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٨‬‫:‪٩ ; include files‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٠١‬‫"‪١١ %include "stdio.inc‬‬ ‫;‬ ‫.‪standard I/O routines‬‬‫"‪١٢ %include "gdt.inc‬‬ ‫;‬ ‫.‪GDT load routine‬‬‫"‪١٣ %include "a20.inc‬‬ ‫;‬ ‫.‪Enable A20 routines‬‬‫"‪١٤ %include "fat12.inc‬‬ ‫;‬ ‫.‪FAT12 driver‬‬‫"‪١٥ %include "common.inc‬‬ ‫;‬ ‫.‪common declarations‬‬‫٦١‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٧١‬‫‪١٨ ; data and variable‬‬‫∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٩١‬‫٠٢‬ ‫٥ﺭﺍﺟﻊ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺑﻖ ﳌﻌﺮﻓﺔ ﺍﻟﺘﻔﺎﺻﻴﻞ.‬ ‫٦ﲨﻴﻊ ﺷﻔﺮﺍﺕ ﺍﳌﻠﻔﺎﺕ ﻣﺮﻓﻘﺔ ﻣﻊ ﺍﻟﺒﺤﺚ ﰲ ﳎﻠﺪ /‪ example/ch3/boot‬ﻭﺷﻔﺮﺓ ﺍﳌﺤﻤﻞ ﺍﻟﻨﻬﺎﺋﻴﺔ ﺳﺘﻜﻮﻥ ﻣﻠﺤﻘﺔ ﰲ ‪‬ﺎﻳﺔ ﺍﻟﺒﺤﺚ.‬‫٥٩‬
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬٢١ hello msg db 0xa,0xd,"Welcome to eqraOS Stage2",0xa,0xd,0٢٢ fail message db 0xa,0xd,"KERNEL.SYS is Missing. press any key to reboot...",0٢٣٢٤٢٥٢٦ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٧ ; entry point of stage2 bootloader.٢٨ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗٢٩٣٠ stage2:٣١٣٢ ;−−−−−−− −−−−−−−−٣٣ ; Set Registers.٣٤ ;−−−−−−− −−−−−−−−٣٥٣٦ cli٣٧٣٨ xor ax, ax٣٩ mov ds, ax٤٠ mov es, ax٤١٤٢ mov ax, 0x0٤٣ mov ss, ax٤٤ mov sp, 0xFFFF٤٥٤٦ sti٤٧٤٨ ;−−−−−−−−−− −−−−−−−−−−٤٩ ; Load gdt into gdtr.٥٠ ;−−−−−−−−−− −−−−−−−−−−٥١٥٢ call load gdt٥٣٥٤ ;−−−−−−−−−− −−−−−−−−−−٥٥ ; Enable A20.٥٦ ;−−−−−−−−−− −−−−−−−−−−٥٧ call enable a20 keyboard controller output port٥٨٥٩ ;−−−−−−−− −−−−−−−−٦٠ ; Display Message. ٩٦
    • ‫٤.٤. ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ‬ ٦١ ;−−−−−−−− −−−−−−−−− ٦٢ mov si,hello msg ٦٣ call puts16 ٦٤ ٦٥ ;−−−−−−−−−− −−−−−−−−−−− ٦٦ ; Load Root Directory ٦٧ ;−−−−−−−−−−− −−−−−−−−−−− ٦٨ call load root ٦٩ ٧٠ ;−−−−−−−−−− −−−−−−−−−−− ٧١ ; Load Kernel ٧٢ ;−−−−−−−−−− −−−−−−−−−−− ٧٣ xor ebx,ebx ٧٤ mov bp,KERNEL RMODE BASE ; bx:bp buffer to load kernel ٧٥ ٧٦ mov si,kernel name ٧٧ call load file ٧٨ ٧٩ mov dword[kernel size],ecx ٨٠ cmp ax,0 ٨١ je enter stage3 ٨٢ ٨٣ mov si,fail message ٨٤ call puts16 ٨٥ ٨٦ mov ah,0 ٨٧ int 0x16 ; wait any key. ٨٨ int 0x19 ; warm boot. ٨٩ cli ; cannot go here! ٩٠ hlt ٩١ ٩٢ ٩٣ ;−−−−−−−− −−−−−−−− ٩٤ ; Go to PMode. ٩٥ ;−−−−−−−− −−−−−−−− ٩٦ ٩٧ enter stage3: ٩٨ ٩٩ ; just set bit 0 from cr0 (Control Register 0).١٠٠١٠١ cli ; important. ٩٧
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬١٠٢ mov eax,cr0١٠٣ or eax,0x1١٠٤ mov cr0,eax ; entering pmode.١٠٥١٠٦١٠٧ ;−−−−−−−−− −−−−−−−−−−١٠٨ ; Fix CS value١٠٩ ;−−−−−−−−−− −−−−−−−−−−١١٠ ; select the code descriptor١١١ jmp CODE DESCRIPTOR:stage3١١٢١١٣١١٤ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١١٥ ; entry point of stage3١١٦ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗١١٧١١٨ bits 32 ; code now 32−bit١١٩١٢٠ stage3:١٢١١٢٢ ; − − − − − − − −; −−−−−−−−١٢٣ ; Set Registers.١٢٤ ; − − − − − − − −; −−−−−−−−١٢٥١٢٦ mov ax,DATA DESCRIPTOR ; address of data descriptor.١٢٧ mov ds,ax١٢٨ mov ss,ax١٢٩ mov es,ax١٣٠ mov esp,0x90000 ; stack begin from 0x90000.١٣١١٣٢ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−١٣٣ ; Clear Screen and print message.١٣٤ ;−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−١٣٥١٣٦ call clear screen١٣٧١٣٨ mov ebx,stage2 message١٣٩ call puts32١٤٠١٤١ mov ebx,logo message١٤٢ call puts32 ٩٨
    • ‫٤.٤. ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ‬١٤٣١٤٤١٤٥١٤٦ ;−−−−−−−−−−−− −−−−−−−−−−−−١٤٧ ; Copy Kernel at 1 MB.١٤٨ ;−−−−−−−−−−− −−−−−−−−−−−−١٤٩ mov eax,dword[kernel size]١٥٠ movzx ebx,word[bytes per sector]١٥١ mul ebx١٥٢ mov ebx,4١٥٣ div ebx١٥٤١٥٥ cld١٥٦١٥٧ mov esi,KERNEL RMODE BASE١٥٨ mov edi,KERNEL PMODE BASE١٥٩ mov ecx,eax١٦٠ rep movsd١٦١١٦٢ ;−−−−−−−−−− −−−−−−−−−−١٦٣ ; Execute the kernel.١٦٤ ;−−−−−−−−−− −−−−−−−−−−١٦٥ jmp CODE DESCRIPTOR:KERNEL PMODE BASE١٦٦١٦٧ ;−−−−−−−− ; −−−−−−−−−١٦٨ ; Hlat the system.١٦٩ ;−−−−−−−− ; −−−−−−−−−١٧٠ cli ; clear interrupt.١٧١ hlt ; halt the system. :‫ﺍﻟﻨﺘﻴﺠﺔ‬ ٩٩
    • ‫٤. ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ - ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ‬‫ﺷﻜﻞ ٤.١.: ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺃﺛﻨﺎء ﺍﻟﻌﻤﻞ‬ ‫ﺷﻜﻞ ٤.٢.: ﺑﺪء ﺗﻨﻔﻴﺬ ﺍﻟﻨﻮﺍﺓ‬ ‫٠٠١‬
    • ‫ﺍﻟﻘﺴﻢ ‪.III‬‬‫‪Kernel‬‬ ‫ﺍﻟﻨﻮﺍﺓ‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﺃﺣﺪ ﺃﻫﻢ ﺍﳌﻜﻮﻧﺎﺕ ﰲ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻫﻲ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ )‪ (Kernel‬ﺣﻴﺚ ﺗﺪﻳﺮ ﻫﺬﻩ ﺍﻟﻨﻮﺍﺓ ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ‬‫ﻭﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ ﻋﺎﻟﻴﺔ ﺗﺴﻤﺢ ﻟﱪﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﻣﻦ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﳌﻮﺍﺭﺩ ﺑﺸﻜﻞ ﺟﻴﺪ.ﻭﺗﻌﺘﱪ ﺑﺮﳎﺔ‬‫ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﻦ ﺃﺻﻌﺐ ﺍﳌﻬﻤﺎﺕ ﺍﻟﱪﳎﻴﺔ ﻋﻠﻰ ﺍﻻﻃﻼﻕ ، ﺣﻴﺚ ﺗﺆﺛﺮ ﻫﻴﻜﻠﺘﻪ ﻭﺗﺼﻤﻴﻤﻪ ﻋﻠﻰ ﻛﺎﻓﺔ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﻭﻫﺬﺍ ﻣﺎ ﳝﻴﺰ ﺑﻌﺾ ﺍﻻﻧﻈﻤﺔ ﻭﳚﻌﻠﻬﺎ ﻗﺎﺑﻠﺔ ﻟﻠﻌﻤﻞ ﰲ ﺃﺟﻬﺰﺓ ﻣﻌﻴﻨﺔ. ﻭﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﺳﻨﻠﻘﻲ ﻧﻈﺮﺓ ﻋﻠﻰ ﺍﻟﻨﻮﺍﺓ‬‫ﻭﺑﺮﳎﺘﻬﺎ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺴﻲ ﻭ ﺍﻟﺴﻲ++ ﻭﻛﺬﻟﻚ ﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﻃﺮﻕ ﺗﺼﻤﻴﻢ ﺍﻟﻨﻮﺍﺓ ﻭﻣﻴﺰﺍﺕ ﻭﻋﻴﻮﺏ‬ ‫ﻛ ٌ ﻋﻠﻰ ﺣﺪﺓ.‬ ‫ﻞ‬ ‫٥.١. ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﺗﻌ ‪‬ﻑ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺑﺄ‪‬ﺎ ﺍﳉﺰء ﺍﻷﺳﺎﺳﻲ ﰲ ﺍﻟﻨﻈﺎﻡ ﻭﺍﻟﺬﻱ ﺗﻌﺘﻤﺪ ﻋﻠﻴﻪ ﺑﻘﻴﺔ ﻣﻜﻮﻧﺎﺕ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ.‬ ‫ﺮ‬‫ﻭﻳﻜﻤﻦ ﺩﻭﺭ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﰲ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ﻭﺇﺩﺍﺭﺗﻪ ﲝﻴﺚ ﺗﻜ ‪‬ﻥ ﻃﺒﻘﺔ ﺑﺮﳎﻴﺔ ﺗﺒﻌﺪ ﺑﺮﺍﻣﺞ‬ ‫ﻮ‬‫ﺍﳌﺴﺘﺨﺪﻡ ﻣﻦ ﺗﻔﺎﺻﻴﻞ ﻭﺗﻌﻘﻴﺪﺍﺕ ﺍﻟﻌﺘﺎﺩ ، ﻭﻻ ﺗﻘﺘﺼﺮ ﻋﻠﻰ ﺫﻟﻚ ﺑﻞ ﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ ﻣﺒﺴﻄﺔ )ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ‬‫ﻣﻦ ﻟﻐﺔ ﺍﻟﱪﳎﺔ ﺍﳌﺪﻋﻮﻣﺔ ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ( ﲝﻴﺚ ﲤﻜﻦ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ . ﻭﰲ ﺍﳊﻘﻴﻘﺔ‬‫ﻻ ﻳﻮﺟﺪ ﻗﺎﻧﻮﻥ ﻳﻨﺺ ﻋﻠﻰ ﺇﻟﺰﺍﻣﻴﺔ ﻭﺟﻮﺩ ﻧﻮﺍﺓ ﻟﻠﻨﻈﺎﻡ ، ﺣﻴﺚ ﳝﻜﻦ ﻟﱪﻧﺎﻣﺞ ﻣﺎ )ﻳﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ( ﺍﻟﺘﻌﺎﻣﻞ‬‫ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﻭﻣﻊ ﻛﻞ ﺍﳉﺪﺍﻭﻝ ﰲ ﺍﳊﺎﺳﺐ ﻭﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﺑﺎﻳﺖ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻦ ﻫﺬﺍ ﻣﺎ ﺳﻴﺠﻌﻞ ﻋﻤﻠﻴﺔ‬‫ﻛﺘﺎﺑﺔ ﺍﻟﱪﺍﻣﺞ ﻋﻤﻠﻴﺔ ﺷﺒﻪ ﻣﺴﺘﺤﻴﻠﺔ ! ﺣﻴﺚ ﳚﺐ ﻋﻠﻰ ﻛﻞ ﻣﱪﻣﺞ ﻳﺮﻳﺪ ﻛﺘﺎﺑﺔ ﺗﻄﺒﻴﻖ ﺑﺴﻴﻂ ﺃﻥ ﳚﻴﺪ ﺑﺮﳎﺔ‬‫ﺍﻟﻌﺘﺎﺩ ﻭﺃﺳﺎﺳﻴﺎﺕ ﺍﻻﻗﻼﻉ ﺣﱴ ﻳﻌﻤﻞ ﺑﺮﻧﺎﳎﻪ ، ﺍﺿﺎﻓﺔ ﻋﻠﻰ ﺫﻟﻚ ﻻ ﳝﻜﻦ ﺗﺸﻐﻴﻞ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﰲ ﻧﻔﺲ‬‫ﺍﻟﻮﻗﺖ ﻧﻈﺮﺍ ﻟﻌﺪﻡ ﻭﺟﻮﺩ ﺑﻨﻴﺔ ﲢﺘﻴﺔ ﺗﻮﻓﺮ ﻣﺜﻞ ﻫﺬﻩ ﺍﳋﺼﺎﺋﺺ ، ﻭﻻﻧﻨﺴﻰ ﺍﻋﺪﺍﺩ ﻭ‪‬ﻴﺌﺔ ﺟﺪﺍﻭﻝ ﺍﻟﻨﻈﺎﻡ ﻭﻛﺘﺎﺑﺔ‬‫ﻭﻇﺎﺋﻒ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﺍﻷﺧﻄﺎء، ﻭﺩﻭﺍﻝ ﺣﺠﺰ ﻭﲢﺮﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻏﲑﻫﺎ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﺍﻟﻀﺮﻭﺭﻳﺔ ﻷﻱ‬‫ﺑﺮﻧﺎﻣﺞ.ﻛﻞ ﻫﺬﺍ ﳚﻌﻞ ﻋﻤﻠﻴﺔ ﺗﻄﻮﻳﺮ ﺑﺮﻧﺎﻣﺞ ﻟﻠﻌﻤﻞ ﻋﻠﻰ ﺣﺎﺳﺐ ﻣﺎ ﺑﺪﻭﻥ ﻧﻮﺍﺓ ﻟﻪ ﺃﻣﺮﴽ ﻏﲑ ﻣﺮﻏﻮﺑﺎ ، ﺧﺎﺻﺔ ﺇﺫﺍ‬‫ﺫﻛﺮﻧﺎ ﺃﻥ ﺍﻟﱪﻧﺎﻣﺞ ﳚﺐ ﲢﺪﻳﺜﻪ ﳎﺪﺩﴽ ﻋﻨﺪ ﻧﻘﻠﻪ ﺍﱃ ﻣﻨﺼﺔ ﺃﺧﺮﻯ ﺫﺍﺕ ﻋﺘﺎﺩ ﳐﺘﻠﻒ. ﺍﺫﴽ ﳝﻜﻦ ﺃﻥ ﻧﻘﻮﻝ ﺃﻥ ﻧﻮﺍﺓ‬‫ﺍﻟﻨﻈﺎﻡ ﻫﻲ ﺍﳉﺰء ﺍﻻﻫﻢ ﰲ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻛﻜﻞ ،ﺣﻴﺚ ﺗﺪﻳﺮ ﺍﻟﻨﻮﺍﺓ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ﻣﻦ ﺍﳌﻌﺎﰿ ﻭﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ‬ ‫ﻭﺍﻷﻗﺮﺍﺹ ﺍﻟﺼﻠﺒﺔ ﻭﺍﳌﺮﻧﺔ ﻭﻏﲑﻫﺎ ﻣﻦ ﺍﻷﺟﻬﺰﺓ ﺍﳌﺤﻴﻄﺔ ﺑﺎﳊﺎﺳﺐ.‬‫ﻭﺣﱴ ﻧﻔﻬﻢ ﻋﻼﻗﺔ ﺍﻟﻨﻮﺍﺓ ﻣﻊ ﺑﻘﻴﺔ ﺃﺟﺰﺍء ﺍﻟﻨﻈﺎﻡ ، ﻓﺎﻧﻪ ﳝﻜﻦ ﺗﻘﺴﻴﻢ ﺍﳊﺎﺳﺐ ﺍﱃ ﻋﺪﺓ ﻣﺴﺘﻮﻳﺎﺕ ﻣﻦ ﺍﻟﺘﺠﺮﻳﺪ‬ ‫ﲝﻴﺚ ﻛﻞ ﻣﺴﺘﻮﻯ ﳜﺪﻡ ﺍﳌﺴﺘﻮﻯ ﺍﻟﺬﻱ ﻳﻠﻴﻪ .‬‫٣٠١‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫٥.١.١. ﻣﺴﺘﻮﻳﺎﺕ ﺍﻟﺘﺠﺮﻳﺪ‬‫ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﱪﳎﻴﺎﺕ ﻳﺘﻢ ﺑﻨﺎﺋﻬﺎ ﻋﻠﻰ ﺷﻜﻞ ﻣﺴﺘﻮﻳﺎﺕ ، ﻭﻇﻴﻔﺔ ﻛﻞ ﻣﺴﺘﻮﻯ ﻫﻮ ﺗﻮﻓﲑ ﻭﺍﺟﻬﺔ ﻟﻠﻤﺴﺘﻮﻯ ﺍﻟﺬﻱ‬‫ﻳﻠﻴﻪ ﲝﻴﺚ ﲣﻔﻲ ﻫﺬﻩ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﺘﻌﻘﻴﺪﺍﺕ ﻭﺍﻟﺘﻔﺎﺻﻴﻞ ﻭﻛﺬﻟﻚ ﺭﲟﺎ ﳛﻤﻲ ﻣﺴﺘﻮﻯ ﻣﺎ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ‬‫ﻣﻦ ﺍﳌﺴﺘﻮﻯ ﺍﻟﺬﻱ ﻳﻠﻴﻪ ، ﻭﻏﺎﻟﺒﺎ ﻣﺎ ﻳﺘﺒﻊ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﳍﺬﺍ ﺍﻟﻨﻮﻉ ﻣﻦ ﺍﻟﱪﳎﻴﺎﺕ ﺣﻴﺚ ﳝﻜﻦ ﺗﻘﺴﻴﻢ ﺍﻟﻨﻈﺎﻡ ﻛﻜﻞ‬ ‫ﺍﱃ ﻋﺪﺓ ﻣﺴﺘﻮﻳﺎﺕ.‬ ‫ﺍﳌﺴﺘﻮﻯ ﺍﻷﻭﻝ: ﻣﺴﺘﻮﻯ ﺍﻟﻌﺘﺎﺩ‬‫ﻣﺴﺘﻮﻯ ﺍﻟﻌﺘﺎﺩ ﻫﻮ ﺃﺩﱏ ﻣﺴﺘﻮﻯ ﳝﻜﻦ ﺃﻥ ﻧﻌﺮﻓﻪ ﻭﻳﻈﻬﺮ ﻋﻠﻰ ﺷﻜﻞ ﻣﺘﺤﻜﻤﺎﺕ ﻟﻌﺘﺎﺩ ﺍﳊﺎﺳﺐ ، ﺣﻴﺚ ﻳﺮﺗﺒﻂ‬‫ﻣﺘﺤﻜﻢ ﻣﺎ ﰲ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ ﻣﻊ ﻣﺘﺤﻜﻢ ﺁﺧﺮ ﰲ ﺍﻟﻌﺘﺎﺩ ﻧﻔﺴﻪ. ﻭﻇﻴﻔﺔ ﺍﳌﺘﺤﻜﻢ ﰲ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ ﻫﻲ ﺍﻟﺘﺨﺎﻃﺐ ﻣﻊ‬‫ﺍﳌﺘﺤﻜﻢ ﺍﻻﺧﺮ ﰲ ﺍﻟﻌﺘﺎﺩ ﻭﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻳﻘﻮﻡ ﺑﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺴﺘﻘﺒﻠﺔ. ﻛﻴﻒ ﻳﻘﻮﻡ ﺍﳌﺘﺤﻜﻢ ﺑﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ؟‬ ‫ﻫﺬﺍ ﻫﻮ ﺩﻭﺭ ﺍﳌﺴﺘﻮﻯ ﺍﻟﺜﺎﱐ.‬ ‫‪Firmware‬‬ ‫ﺍﳌﺴﺘﻮﻯ ﺍﻟﺜﺎﱐ: ﻣﺴﺘﻮﻯ ﺑﺮﺍﻣﺞ ﺍﻟﻌﺘﺎﺩ‬‫ﺑﺮﺍﻣﺞ ﺍﻟﻌﺘﺎﺩ )‪ (Firmware‬ﻫﻲ ﺑﺮﺍﻣﺞ ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺫﺍﻛﺮﺓ ﺑﺪﺍﺧﻞ ﺍﳌﺘﺤﻜﻢ )ﻏﺎﻟﺒﺎ ﺫﺍﻛﺮﺓ ‪ ، (EEPROM‬ﻭﻇﻴﻔﺔ‬‫ﻫﺬﻩ ﺍﻟﱪﺍﻣﺞ ﻫﻲ ﺗﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﺍﳌﺘﺤﻜﻢ. ﻭﻣﻦ ﺍﻻﻣﺜﻠﺔ ﻋﻠﻰ ﻣﺜﻞ ﻫﺬﻩ ﺍﻟﱪﳎﻴﺎﺕ ﺑﺮﻧﺎﻣﺞ ﺍﻟﺒﺎﻳﻮﺱ ﻭﺃﻱ‬ ‫ﺑﺮﻧﺎﻣﺞ ﻣﻮﺟﻮﺩ ﰲ ﺃﻱ ﻣﺘﺤﻜﻢ ﻣﺜﻞ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.‬ ‫ﺍﳌﺴﺘﻮﻯ ﺍﻟﺜﺎﻟﺚ: ﻣﺴﺘﻮﻯ ﺍﻟﻨﻮﺍﺓ )ﺍﳊﻠﻘﺔ ﺻﻔﺮ(‬‫ﺍﻟﻨﻮﺍﺓ ﻭﻫﻲ ﺃﺳﺎﺱ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ، ﻭﻇﻴﻔﺘﻬﺎ ﺍﺩﺍﺭﺓ ﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ﻭﺗﻮﻓﲑ ﻭﺍﺟﻬﺔ ﻟﺒﻘﻴﺔ ﺃﺟﺰﺍء ﺍﻟﻨﻈﺎﻡ ، ﻭﺗﻌﻤﻞ‬ ‫ﺍﻟﻨﻮﺍﺓ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ، ﺍﻱ ﺃﻧﻪ ﳝﻜﻦ ﺗﻨﻔﻴﺬ ﺃﻱ ﺃﻣﺮ ﻭﺍﻟﻮﺻﻮﻝ ﺍﳌﺒﺎﺷﺮ ﺍﱃ ﺃﻱ ﻋﻨﻮﺍﻥ ﰲ ﺍﻟﺬﺍﻛﺮﺓ.‬ ‫ﺍﳌﺴﺘﻮﻯ ﺍﻟﺮﺍﺑﻊ: ﻣﺴﺘﻮﻯ ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ )ﺍﳊﻠﻘﺔ ١ ﻭ ٢(‬‫ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ ﻫﻲ ﻋﺒﺎﺭﺓ ﻋﻦ ﺑﺮﺍﻣﺞ ﻟﻠﻨﻈﺎﻡ ﻭﻇﻴﻔﺘﻬﺎ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﻣﺘﺤﻜﻤﺎﺕ ﺍﻟﻌﺘﺎﺩ )ﻭﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﺍﻟﻨﻮﺍﺓ(‬‫ﺳﻮﺍءﺍ ﻟﻘﺮﺍءﺓ ﺍﻟﻨﺘﺎﺋﺞ ﺍﻭ ﻻﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ، ﻫﺬﻩ ﺍﻟﱪﺍﻣﺞ ﲢﺘﺎﺝ ﺍﱃ ﺃﻥ ﺗﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ١ ﻭ ٢ ﺣﱴ ﺗﺘﻤﻜﻦ ﻣﻦ‬‫ﺗﻨﻔﻴﺬ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻷﻭﺍﻣﺮ ، ﻭﰲ ﺣﺎﻟﺔ ﰎ ﺗﻨﻔﻴﺬﻫﺎ ﻋﻠﻰ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ﻓﺎﻥ ﻫﺬﺍ ﻗﺪ ﻳﺆﺩﻱ ﺍﱃ ﺧﻄﻮﺭﺓ ﺗﻌﻄﻞ ﺍﻟﻨﻈﺎﻡ‬‫ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻫﻨﺎﻙ ﻋﻄﻞ ﰲ ﺍﺣﺪ ﺍﳌﺸﻐﻼﺕ ﻛﺬﻟﻚ ﺳﺘﻜﻮﻥ ﺻﻼﺣﻴﺎﺕ ﺍﳌﺸﻐﻞ ﻋﺎﻟﻴﺔ ﻓﻘﺪ ﻳﻘﻮﻡ ﺃﺣﺪ ﺍﳌﺸﻐﻼﺕ‬ ‫ﺑﺘﻐﻴﲑ ﺃﺣﺪ ﺟﺪﺍﻭﻝ ﺍﳌﻌﺎﰿ ﻣﺜﻞ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ )‪ (GDT‬ﻭﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻗﺪ ﻳﻌﻄﻞ ﺍﻟﻨﻈﺎﻡ.‬ ‫٤٠١‬
    • ‫٥.٢. ﻭﻇﺎﺋﻒ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬ ‫ﺍﳌﺴﺘﻮﻯ ﺍﳋﺎﻣﺲ: ﻣﺴﺘﻮﻯ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ )ﺍﳊﻠﻘﺔ ٣(‬‫ﺍﳌﺴﺘﻮﻯ ﺍﻻﺧﲑ ﻭﻫﻮ ﻣﺴﺘﻮﻯ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﺣﻴﺚ ﻻ ﳝﻜﻦ ﳍﺬﻩ ﺍﻟﱪﺍﻣﺞ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ﻭﺍﳕﺎ ﺗﺘﻌﺎﻣﻞ ﻓﻘﻂ‬ ‫ﻣﻊ ﻭﺍﺟﻬﺔ ﺑﺮﳎﺔ ﺍﻟﺘﻄﺒﻴﻘﺎﺕ )‪ (Applica on Progeamming Interface‬ﻭﺍﻟﱵ ﺗﻌﺮﻑ ﺑﺪﻭﺍﻝ )‪.(API‬‬ ‫٥.٢. ﻭﻇﺎﺋﻒ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬‫ﲣﺘﻠﻒ ﻣﻜﻮﻧﺎﺕ ﻭﻭﻇﺎﺋﻒ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺗﺒﻌﴼ ﻟﻄﺮﻳﻘﺔ ﺍﻟﺘﺼﻤﻴﻢ ﺍﳌﺘﺒﻌﺔ ،ﻓﻬﻨﺎﻙ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﻄﺮﻕ ﻟﺘﺼﻤﻴﻢ‬‫ﺍﻻﻧﻮﻳﺔ ﺑﻌﻀﴼ ﻣﻨﻬﺎ ﳚﻌﻞ ﻣﺎ ﻫﻮ ﻣﺘﻌﺎﺭﻑ ﻋﻠﻴﻪ ﺑﺄﻧﻪ ﻳﺘﺒﻊ ﻟﻨﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﺑﱪﻧﺎﻣﺞ ﻟﻠﻤﺴﺘﺨﺪﻡ )‪١ (User Program‬‬‫ﻭﺍﻟﺒﻌﺾ ﺍﻻﺧﺮ ﻋﻜﺲ ﺫﻟﻚ . ﻟﺬﻟﻚ ﺳﻨﺬﻛﺮ ﺣﺎﻟﻴﴼ ﺍﳌﻜﻮﻧﺎﺕ ﺍﻟﺸﺎﺋﻌﺔ ﰲ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻭﰲ ﺍﻟﻘﺴﻢ ﺍﻟﺘﺎﱄ ﻋﻨﺪ‬‫ﺍﳊﺪﻳﺚ ﻋﻦ ﻫﻴﻜﻠﺔ ﻭﻃﺮﻕ ﺗﺼﻤﻴﻢ ﺍﻷﻧﻮﺑﺔ ﺳﻨﻔﺼﻞ ﺃﻛﺜﺮ ﰲ ﻫﺬﻩ ﺍﳌﻜﻮﻧﺎﺕ ﻭﻧﻘﺴﻤﻬﺎ ﲝﺴﺐ ﻃﺮﻳﻘﺔ ﺍﻟﺘﺼﻤﻴﻢ.‬ ‫٥.٢.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺃﻫﻢ ﻭﻇﻴﻔﺔ ﻟﻨﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻫﻲ ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﺃﻥ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﳚﺐ ﺍﻥ ﻳﺘﻢ ﲢﻤﻠﻴﻪ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻗﺒﻞ‬‫ﺃﻥ ﻳﺘﻢ ﺗﻨﻔﻴﺬﻩ ، ﻟﺬﻟﻚ ﻣﻦ ﻣﻬﺎﻡ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻫﻲ ﻣﻌﺮﻓﺔ ﺍﻷﻣﺎﻛﻦ ﺍﻟﺸﺎﻏﺮﺓ ، ﻭﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﻣﺸﺎﻛﻞ ﺍﻟﺘﺠﺰﺋﺔ‬‫)‪ (Fragmenta on‬ﺣﻴﺚ ﻣﻦ ﺍﳌﻤﻜﻦ ﺃﻥ ﲢﻮﻱ ﺍﻟﺬﺍﻛﺮﺓ ﻋﻠﻰ ﺍﻟﻜﺜﲑ ﻣﻦ ﺍﳌﺴﺎﺣﺎﺕ ﺍﻟﺼﻐﲑﺓ ﻭﺍﻟﱵ ﻻ ﺗﻜﻔﻲ‬‫ﻟﺘﺤﻤﻴﻞ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﺃﻭ ﺣﱴ ﺣﺠﺰ ﻣﺴﺎﺣﺔ ﻟﱪﻧﺎﻣﺞ ﻣﺎ. ﺃﺣﺪ ﺍﳌﺸﺎﻛﻞ ﺍﻟﱵ ﻋﻠﻰ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﻫﻲ‬‫ﻣﻌﺮﻓﺔ ﻣﻜﺎﻥ ﲢﻤﻴﻞ ﺍﻟﱪﻧﺎﻣﺞ ، ﺣﻴﺚ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﺍﻟﱪﻧﺎﻣﺞ ﻣﺴﺘﻘﻼ ﻋﻦ ﺍﻟﻌﻨﻮﺍﻳﻦ )‪(Posi on Independent‬‬‫ﻟﻜﻲ ﻳﺘﻢ ﲢﻤﻠﻴﻪ ﻭﺇﻻ ﻓﻠﻦ ﻧﻌﺮﻑ ﻣﺎ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻟﺒﺪﺍﻳﺔ )‪ (Base Address‬ﳍﺬﺍ ﺍﻟﱪﻧﺎﻣﺞ. ﻓﻠﻮ ﻓﺮﺿﻨﺎ ﺍﻥ ﻟﺪﻳﻨﺎ‬‫ﺑﺮﻧﺎﻣﺞ ‪ binary‬ﻭﻧﺮﻳﺪ ﲢﻤﻴﻠﻪ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻓﻬﻨﺎ ﻟﻦ ﻧﺘﻤﻜﻦ ﻣﻦ ﻣﻌﺮﻓﺔ ﻣﺎ ﻫﻮ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺬﻱ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﻋﻠﻴﻪ‬‫ﺍﻟﱪﻧﺎﻣﺞ ، ﻟﺬﻟﻚ ﻋﺎﺩﺓ ﻓﺎﻥ ﺍﻟﻨﺎﺗﺞ ﻣﻦ ﻋﻤﻠﻴﺔ ﺗﺮﲨﺔ ﻭﺭﺑﻂ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﻫﻮ ﺍ‪‬ﺎ ﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0‪ ،0x‬ﻭﻫﻜﺬﺍ‬‫ﺳﻨﺘﻤﻜﻦ ﺩﻭﻣﺎ ﻣﻦ ﲢﻤﻴﻞ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﰲ ﺑﺪﺍﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ. ‪‬ﺬﺍ ﺍﻟﺸﻜﻞ ﻟﻦ ﻧﺘﻤﻜﻦ ﻣﻦ ﺗﻨﻔﻴﺬ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ‬‫ﻭﺍﺣﺪ ، ﺣﻴﺚ ﺳﻴﻜﻮﻥ ﻫﻨﺎﻙ ﺑﺮﻧﺎﳎﺎ ﻭﺍﺣﺪﺍ ﻓﻘﻂ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0‪ ، 0x‬ﻭﺍﳊﻞ ﳍﺬﻩ ﺍﳌﺸﺎﻛﻞ ﻫﻮ ﺑﺎﺳﺘﺨﺪﺍﻡ‬‫ﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻟﺘﺨﻴﻠﻴﺔ )‪ (Virtual Address Space‬ﺣﻴﺚ ﻳﺘﻢ ﲣﺼﻴﺺ ﻣﺴﺎﺣﺔ ﲣﻴﻠﻴﺔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻞ ﺑﺮﻧﺎﻣﺞ‬‫ﲝﻴﺚ ﺗﺒﺪﺃ ﺍﻟﻌﻨﻮﻧﺔ ﲣﻴﻠﻴﺎ ﻣﻦ 0‪ 0x‬ﻭ‪‬ﺬﺍ ﰎ ﺣﻞ ﻣﺸﻜﻠﺔ ﲢﻤﻴﻞ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﻭﺣﻞ ﻣﺸﻜﻠﺔ ‪.reloca on‬‬‫ﻭﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺘﺨﻴﻠﻴﺔ )‪ (VAS‬ﻫﻲ ﻣﺴﺎﺣﺔ ﻣﻦ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻟﻜﻞ ﺑﺮﻧﺎﻣﺞ ﲝﻴﺚ ﺗﻴﺪﺃ ﻣﻦ ﺍﻝ 0‪ 0x‬ﻭﻣﻔﻬﻮﻡ ﻫﺬﻩ‬‫ﺍﳌﺴﺎﺣﺔ ﻫﻮ ﺃﻥ ﻛﻞ ﺑﺮﻧﺎﻣﺞ ﺳﻴﺘﻌﺎﻣﻞ ﻣﻊ ﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﳋﺎﺻﺔ ﺑﻪ ﻭﻫﺬﺍ ﻣﺎ ﻳﺆﺩﻱ ﺍﱃ ﲪﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ، ﺣﻴﺚ‬‫ﻟﻦ ﻳﺴﺘﻄﻴﻊ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﻋﻨﻮﺍﻥ ﺁﺧﺮ ﲞﻼﻑ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ‪ .VAS‬ﻭﻧﻈﺮﴽ ﻟﻌﺪﻡ ﺍﺭﺗﺒﺎﻁ‬‫ﺍﻝ ‪ VAS‬ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻓﺎﻧﻪ ﳝﻜﻦ ﺍﻥ ﻳﺸﲑ ﻋﻨﻮﺍﻥ ﲣﻴﻠﻲ ﺍﱃ ﺫﺍﻛﺮﺓ ﺍﺧﺮﻯ ﲞﻼﻑ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ )ﻣﺜﻼ‬‫ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ(. ﻭﻫﺬﺍ ﳛﻞ ﻣﺸﻜﻠﺔ ﺍﻧﺘﻬﺎء ﺍﳌﺴﺎﺣﺎﺕ ﺍﳋﺎﻟﻴﺔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ. ﻭﳚﺪﺭ ﺑﻨﺎ ﺫﻛﺮ ﺃﻥ ﺍﻟﺘﺤﻮﻳﻞ ﺑﲔ‬‫ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﻟﺘﺨﻴﻠﻴﻪ ﺍﱃ ﺍﳊﻘﻴﻘﻴﺔ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺍﻟﻌﺘﺎﺩ ﺑﻮﺍﺳﻄﺔ ﻭﺣﺪﺓ ﺍﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺑﺪﺍﺧﻞ ﺍﳌﻌﺎﰿ )‪Memory‬‬ ‫١ﺍﳌﻘﺼﻮﺩ ﺃ‪‬ﺎ ﺑﺮﺍﻣﺞ ﺗﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ٣.‬‫٥٠١‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬‫‪.(Management Unit‬ﻭﻛﺬﻟﻚ ﻣﻬﻤﺔ ﲪﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﻟﺘﺤﻜﻢ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ‪ Cache‬ﻭﻏﲑﻫﺎ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﻭﺍﻟﱵ‬ ‫ﺳﻴﺘﻢ ﺍﻹﻃﻼﻉ ﻋﻠﻴﻬﺎ ﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺑﻊ - ﲟﺸﻴﺌﺔ ﺍﷲ-.‬ ‫٥.٣. ﻫﻴﻜﻠﺔ ﻭﺗﺼﻤﻴﻢ ﺍﻟﻨﻮﺍﺓ‬‫ﺗﻮﺟﺪ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﻄﺮﻕ ﻟﺘﺼﻤﻴﻢ ﺍﻷﻧﻮﻳﺔ ﻭﺳﻨﺴﺘﻌﺮﺽ ﺑﻌﺾ ﻣﻨﻬﺎ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ، ﻟﻜﻦ ﻗﺒﻞ ﺫﻟﻚ ﳚﺐ ﺍﳊﺪﻳﺚ‬‫ﻋﻦ ﻃﺮﻳﻘﺔ ﻣﻔﻴﺪﺓ ﰲ ﻫﻴﻜﻠﺔ ﻭﺗﺼﻤﻴﻢ ﺍﻷﻧﻮﻳﺔ ﺍﻻ ﻭﻫﻲ ﲡﺮﻳﺪ ﺍﻟﻌﺘﺎﺩ )‪ (Hardware Abstrac on‬ﺃﻱ ﲟﻌﲎ ﻓﺼﻞ‬‫ﺍﻟﻨﻮﺍﺓ ﻣﻦ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ، ﻭﺍﻧﺸﺎء ﻃﺒﻘﺔ ﺑﺮﳎﻴﺔ )‪ (So ware Layer‬ﺗﺴﻤﻰ ﻃﺒﻘﺔ ‪) HAL‬ﺍﺧﺘﺼﺎﺭﺍ‬‫ﻟﻜﻠﻤﺔ ‪ (Hardware Abstrac on Layer‬ﺑﲔ ﺍﻟﻨﻮﺍﺓ ﻭﺑﲔ ﺍﻟﻌﺘﺎﺩ ، ﻭﻇﻴﻔﺔ ﻃﺒﻘﺔ ‪ HAL‬ﻫﻲ ﺗﻮﻓﲑ ﻭﺍﺟﻬﺔ ﻟﻌﺘﺎﺩ‬ ‫ﺍﳊﺎﺳﺐ ﲝﻴﺚ ﲤ ﱢﻦ ﺍﻟﻨﻮﺍﺓ ﻣﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻟﻌﺘﺎﺩ.‬ ‫ﻜ‬‫ﻓﺼﻞ ﺍﻟﻨﻮﺍﺓ ﻣﻦ ﺍﻟﻌﺘﺎﺩ ‪‬ﺘﻴﺢ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﻔﻮﺍﺋﺪ ،ﺃﻭﻻﹰ ﺷﻔﺮﺓ ﺍﻟﻨﻮﺍﺓ ﺳﺘﻜﻮﻥ ﺃﻛﺜﺮ ﻣﻘﺮﻭﺋﻴﺔ ﻭﺃﺳﻬﻞ ﰲ ﺍﻟﺼﻴﺎﻧﺔ‬ ‫ﺗ‬‫ﻭﺍﻟﺘﻌﺪﻳﻞ ﻷﻥ ﺍﻟﻨﻮﺍﺓ ﺳﺘﺘﻌﺎﻣﻞ ﻣﻊ ﻭﺍﺟﻬﺔ ﺃﺧﺮﻯ ﺃﻛﺜﺮ ﺳﻬﻮﻟﺔ ﻣﻦ ﺗﻌﻘﻴﺪﺍﺕ ﺍﻟﻌﺘﺎﺩ ، ﺍﳌﻴﺰﺓ ﺍﻟﺜﺎﻧﻴﺔ ﻭﺍﻷﻛﺜﺮ ﺃﳘﻴﺔ‬‫ﻫﻲ ﺍﻣﻜﺎﻧﻴﺔ ﻧﻘﻞ ﺍﻟﻨﻮﺍﺓ )‪ (Por ng‬ﻷﺟﻬﺰﺓ ﺫﺍﺕ ﻋﺘﺎﺩ ﳐﺘﻠﻒ )ﻣﺜﻞ ‪ (SPARC,MIPS,...etc‬ﺑﺪﻭﻥ ﺍﻟﺘﻐﻴﲑ ﰲ‬‫ﺷﻔﺮﺓ ﺍﻟﻨﻮﺍﺓ ، ﻓﻘﻂ ﺳﻴﺘﻢ ﺗﻌﺪﻳﻞ ﻃﺒﻘﺔ ‪ HAL‬ﻣﻦ ﻧﺎﺣﻴﺔ ﺍﻟﺘﻄﺒﻴﻖ )‪ (Implementa on‬ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺇﻋﺎﺩﺓ ﻛﺘﺎﺑﺔ‬ ‫ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ )‪ (Devcie Drivers‬ﳎﺪﺩﴽ ٢.‬ ‫‪Monolithic Kernel‬‬ ‫٥.٣.١. ﺍﻟﻨﻮﺍﺓ ﺍﻟﻀﺨﻤﺔ‬‫ﺗﻌﺘﱪ ﺍﻷﻧﻮﻳﺔ ﺍﳌﺼﻤﻤﺔ ﺑﻄﺮﻳﻘﺔ ‪ ٣ Monoli c‬ﺃﺳﺮﻉ ﻭﺃﻛﻔﺄ ﺃﻧﻮﻳﺔ ﰲ ﺍﻟﻌﻤﻞ ﻭﺫﻟﻚ ﻧﻈﺮﺍ ﻻﻥ ﻛﻞ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ‬ ‫)‪ (System Process‬ﺗﻜﻮﻥ ﺿﻤﻦ ﺍﻟﻨﻮﺍﺓ ﻭﺗﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ .‬‫ﺍﳌﺸﻜﻠﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﳍﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﻫﻮ ﺍﻧﻪ ﻋﻨﺪ ﺣﺪﻭﺙ ﺃﻱ ﻣﺸﻜﻠﺔ ﰲ ﺃﻱ ﻣﻦ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﻓﺎﻥ ﺍﻟﻨﻈﺎﻡ ﺳﻮﻑ‬‫ﻳﺘﻮﻗﻒ ﻋﻦ ﺍﻟﻌﻤﻞ ﻭﺫﻟﻚ ﻧﻈﺮﺍ ﻻ‪‬ﺎ ﺗﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺳﺎﺑﻘﺎ ﺃﻥ ﺃﻱ ﺧﻠﻞ ﰲ ﻫﺬﺍ ﺍﳌﺴﺘﻮﻯ‬‫ﻳﺆﺩﻱ ﺍﱃ ﺗﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ. ﻣﺸﻜﻠﺔ ﺍﺧﺮﻯ ﳝﻜﻦ ﺫﻛﺮﻫﺎ ﻭﻫﻲ ﺍﻥ ﺍﻟﻨﻮﺍﺓ ﻏﲑ ﻣﺮﻧﺔ ﲟﻌﲎ ﺃﻧﻪ ﻟﺘﻐﻴﲑ ﻧﻈﺎﻡ‬ ‫ﺍﳌﻠﻔﺎﺕ ﻣﺜﻼ ﳚﺐ ﺍﻋﺎﺩﺓ ﺗﺸﻐﻴﻞ ﺍﻟﻨﻈﺎﻡ ﳎﺪﺩﺍ.‬‫ﻭﻛﺄﻣﺜﻠﺔ ﻋﻠﻰ ﺃﻧﻈﻤﺔ ﺗﺸﻐﻴﻞ ﺗﻌﻤﻞ ‪‬ﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﻫﻲ ﺃﻧﻈﻤﺔ ﻳﻮﻧﻜﺲ ﻭﻟﻴﻨﻮﻛﺲ ، ﻭﺃﻧﻈﻤﺔ ﺍﻝ ‪ DOS‬ﺍﻟﻘﺪﳝﺔ‬ ‫ﻭﻭﻳﻨﺪﻭﺯ ﻣﺎ ﻗﺒﻞ ‪.NT‬‬ ‫٢ﺃﻏﻠﺐ ﺃﻧﻮﻳﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺍﳊﺎﻟﻴﺔ ﺗﺴﺘﺨﺪﻡ ﻃﺒﻘﺔ ‪ ،HAL‬ﻫﻞ ﺗﺴﺎﺋﻠﺖ ﻳﻮﻣﺎ ﻛﻴﻒ ﻳﻌﻤﻞ ﻧﻈﺎﻡ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ ﻋﻠﻰ ﺃﺟﻬﺰﺓ ﺳﻄﺢ‬ ‫ﺍﳌﻜﺘﺐ ﻭﺍﻷﺟﻬﺰﺓ ﺍﳌﻀﻤﻨﺔ!‬ ‫٣ﻛﻠﻤﺔ ‪ Mono‬ﺗﻌﲏ ﻭﺍﺣﺪ ، ﺃﻣﺎ ﻛﻠﻤﺔ ‪ Lithic‬ﻓﺘﻌﲏ ﺣﺠﺮﻱ ، ﻭﺍﳌﻘﺼﻮﺩ ﺑﺄﻥ ﺍﻟﻨﻮﺍﺓ ﺗﻜﻮﻥ ﻋﻠﻰ ﺷﻜﻞ ﻛﺘﻠﺔ ﺣﺠﺮﻳﺔ ﻟﻴﺴﺖ ﻣﺮﻧﺔ‬ ‫ﻭﺗﻄﻮﻳﺮﻫﺎ ﻭﺻﻴﺎﻧﺘﻬﺎ ﻣﻌﻘﺪ.‬ ‫٦٠١‬
    • ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬ ‫‪MicroKernel‬‬ ‫٥.٣.٢. ﺍﻟﻨﻮﺍﺓ ﺍﳌﺼﻐﺮﺓ‬‫ﺍﻷﻧﻮﻳﺔ ‪ MicroKernel‬ﻫﻲ ﺍﻷﻛﺜﺮ ﺛﺒﺎﺗﺎ ﻭﺍﺳﺘﻘﺮﺍﺭ ﻭﻣﺮﻭﻧﺔ ﻭﺍﻷﺳﻬﻞ ﰲ ﺍﻟﺼﻴﺎﻧﺔ ﻭﺍﻟﺘﻌﺪﻳﻞ ﻭﺍﻟﺘﻄﻮﻳﺮ ﻭﺫﻟﻚ ﻧﻈﺮﺍ‬‫ﻻﻥ ﺍﻟﻨﻮﺍﺓ ﺗﻜﻮﻥ ﺃﺻﻐﺮ ﻣﺎ ﳝﻜﻦ ، ﺣﻴﺚ ﺃﻥ ﺍﻟﻮﻇﺎﺋﻒ ﺍﻷﺳﺎﺳﻴﺔ ﻓﻘﻂ ﺗﻜﻮﻥ ﺿﻤﻦ ﺍﻟﻨﻮﺍﺓ ﻭﻫﻲ ﺍﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﻭﺍﺩﺍﺭﺓ ﺍﻟﻌﻤﻠﻴﺎﺕ )ﳎﺪﻭﻝ ﺍﻟﻌﻤﻠﻴﺎﺕ،ﺃﺳﺎﺳﻴﺎﺕ ‪ ،(IPC‬ﺃﻣﺎ ﺑﻘﻴﺔ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﻣﺜﻞ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻭﻣﺸﻐﻼﺕ‬‫ﺍﻷﺟﻬﺰﺓ ﻭﻏﲑﻫﺎ ﺗﺘﺒﻊ ﻟﱪﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﻭﺗﻌﻤﻞ ﰲ ﳕﻂ ﺍﳌﺴﺘﺨﺪﻡ )ﺍﳊﻠﻘﺔ ٣( ، ﻭﻫﺬﺍ ﻳﻌﲏ ﰲ ﺣﺎﻟﺔ ﺣﺪﻭﺙ‬‫ﺧﻄﺄ ﰲ ﻫﺬﻩ ﺍﻟﱪﺍﻣﺞ ﻓﺎﻥ ﺍﻟﻨﻈﺎﻡ ﻟﻦ ﻳﺘﺄﺛﺮ ﻛﺬﻟﻚ ﳝﻜﻦ ﺗﻐﻴﲑ ﻫﺬﻩ ﺍﻟﱪﺍﻣﺞ )ﻣﺜﻼ ﺗﻐﻴﲑ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ( ﺩﻭﻥ ﺍﳊﺎﺟﺔ‬‫ﺍﱃ ﺍﻋﺎﺩﺓ ﺗﺸﻐﻴﻞ ﺍﳉﻬﺎﺯ ﺣﻴﺚ ﺃﻥ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﺗﻌﻤﻞ ﻛﱪﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ . ﺍﳌﺸﻜﻠﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﳍﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﻫﻮ‬‫ﺑﻄﺊ ﻋﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﻋﻠﻴﻬﺎ ﺃﻥ ﺗﺘﺨﺎﻃﺐ ﻣﻊ ﺑﻌﻀﻬﺎ ﺍﻟﺒﻌﺾ ﻋﻦ ﻃﺮﻳﻖ ﲤﺮﻳﺮ ﺍﻟﺮﺳﺎﺋﻞ‬‫)‪ (Message Passing‬ﺃﻭ ﻣﺸﺎﺭﻛﺔ ﺟﺰء ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ )‪ (Shared Memory‬ﻭﻫﺬﺍ ﻣﺎ ﻳﻌﺮﻑ ﺏ ‪Interprocess‬‬ ‫‪ .Communica on‬ﻭﺃﺷﻬﺮ ﻣﺜﺎﻝ ﻟﻨﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻳﺘﺒﻊ ﻫﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﻫﻮ ﻧﻈﺎﻡ ﻣﻴﻨﻜﺲ ﺍﻻﺻﺪﺍﺭ ﺍﻟﺜﺎﻟﺚ.‬ ‫‪Hybrid Kernel‬‬ ‫٥.٣.٣. ﺍﻟﻨﻮﺍﺓ ﺍﳍﺠﻴﻨﺔ‬‫ﻫﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﻟﻠﻨﻮﺍﺓ ﻣﺎ ﻫﻮ ﺇﻻ ﻣﺰﻳﺞ ﻣﻦ ﺍﻟﺘﺼﻤﻴﻤﲔ ﺍﻟﺴﺎﺑﻘﲔ ، ﺣﻴﺚ ﺗﻜﻮﻥ ﺍﻟﻨﻮﺍﺓ ‪ MicroKernel‬ﻟﻜﻨﻬﺎ ﺗﻄﺒﻖ‬‫ﻙ ‪ ، Monolithic Kernel‬ﻭﻳﺴﻤﻰ ﻫﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ‪ Hybrid Kernel‬ﺃﻭ ‪ .Modified MicroKernel‬ﻭﻛﺄﻣﺜﻠﺔ ﻋﻠﻰ‬ ‫ﺃﻧﻈﻤﺔ ﺗﻌﻤﻞ ‪‬ﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﻫﻮ ﺃﻧﻈﻤﺔ ﻭﻳﻨﺪﻭﺯ ﺍﻟﱵ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﻣﻌﻤﺎﺭﻳﺔ ‪ ، NT‬ﻭﻧﻈﺎﻡ ‪ BeOS‬ﻭ 9 ‪.Plane‬‬ ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬‫ﳝﻜﻦ ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺑﺄﻱ ﻟﻐﺔ ﺑﺮﳎﺔ ، ﻟﻜﻦ ﳚﺐ ﺍﻟﺘﺄﻛﺪ ﻣﻦ ﺃﻥ ﺍﻟﻠﻐﺔ ﺗﺪﻋﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ‬‫)‪ (Inline Assemlby‬ﺣﻴﺚ ﺃﻥ ﺍﻟﻨﻮﺍﺓ ﻛﺜﲑﺍ ﻣﺎ ﳚﺐ ﻋﻠﻴﻬﺎ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺃﻭﺍﻣﺮ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ )ﻣﺜﻼ ﻋﻨﺪ‬ ‫ﲢﻤﻴﻞ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ﻭﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﻛﺬﻟﻚ ﻋﻨﺪ ﻏﻠﻖ ﺍﳌﻘﻄﺎﻋﺎﺕ ﻭﺗﻔﻌﻴﻠﻬﺎ ﻭﻏﲑﻫﺎ(.‬‫ﺍﻟﺸﻲء ﺍﻻﺧﺮ ﺍﻟﺬﻱ ﳚﺐ ﻭﺿﻌﻪ ﰲ ﺍﳊﺴﺒﺎﻥ ﻫﻮ ﺃﻧﻪ ﻻ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺑﺮﳎﺔ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﻣﻜﺘﺒﺎﺕ ﰲ ﻭﻗﺖ‬‫ﺍﻟﺘﺸﻐﻴﻞ )ﻣﻠﻔﺎﺕ ‪ dll‬ﻣﺜﻼ( ﺩﻭﻥ ﺇﻋﺎﺩﺓ ﺑﺮﳎﺔ ﻫﺬﻩ ﺍﳌﻜﺘﺒﺎﺕ)ﻣﺜﺎﻝ ﺫﻟﻚ ﻻ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺎﺕ ﺩﻭﺕ ﻧﺖ ﺩﻭﻥ‬‫ﺇﻋﺎﺩﺓ ﺑﺮﳎﺔ ﺇﻃﺎﺭ ﺍﻟﻌﻤﻞ(. ﻭﻛﺬﻟﻚ ﻻ ﳝﻜﻦ ﺍﻹﻋﺘﻤﺎﺩ ﻋﻠﻰ ﺩﻭﺍﻝ ﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﺗﻘﻮﻡ ﺑﺘﻄﻮﻳﺮ ﻧﻈﺎﻣﻚ ﺍﳋﺎﺹ ﻓﻴﻪ‬‫)ﻣﺜﻼ ﻟﻦ ﺗﺘﻤﻜﻦ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ‪ new‬ﳊﺠﺰ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺫﻟﻚ ﻻ‪‬ﺎ ﺗﻌﺘﻤﺪ ﻛﻠﻴﺎ ﻋﻠﻰ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ، ﺃﻳﻀﺎ ﺩﻭﺍﻝ‬ ‫ﺍﻻﺩﺧﺎﻝ ﻭﺍﻻﺧﺮﺍﺝ ﺗﻌﺘﻤﺪ ﻛﻠﻴﺎ ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ(.‬‫ﻟﺬﻟﻚ ﻏﺎﻟﺒﺎ ﺗﺴﺘﺨﺪﻡ ﻟﻐﺔ ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++ ﻟﱪﳎﺔ ﺃﻧﻮﻳﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻧﻈﺮﺍ ﳌﺎ ﺗﺘﻤﺘﻊ ﺑﻪ ﺍﻟﻠﻐﺘﲔ ﻣﻦ ﻣﻴﺰﺍﺕ‬‫ﻓﺮﻳﺪﺓ ﲤﻴﺰﻫﺎ ﻋﻦ ﺑﺎﻗﻲ ﺍﻟﻠﻐﺎﺕ ، ﻭﺗﻨﺘﺸﺮ ﻟﻐﺔ ﺍﻟﺴﻲ ﺑﺸﻜﻞ ﺃﻛﱪ ﻻﺳﺒﺎﺏ ﻛﺜﲑﺓ ﻣﻨﻬﺎ ﻫﻮ ﺃ‪‬ﺎ ﻻ ﲢﺘﺎﺝ ﺍﱃ ﻣﻜﺘﺒﺔ‬‫ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ )‪ (RunTime Library‬ﺣﱴ ﺗﻌﻤﻞ ﺍﻟﱪﺍﻣﺞ ﺍﳌﻜﺘﻮﺑﺔ ‪‬ﺎ ﻋﻠﻰ ﻋﻜﺲ ﻟﻐﺔ ﺳﻲ++ ﻭﺍﻟﱵ ﲢﺘﺎﺝ ﺍﱃ‬ ‫)‪ (RunTime Library‬ﻟﺪﻋﻢ ﺍﻟﻜﺜﲑ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﻣﺜﻞ ﺍﻻﺳﺘﺜﻨﺎﺋﺎﺕ ﻭ ﺩﻭﺍﻝ ﺍﻟﺒﻨﺎء ﻭﺍﳍﺪﻡ.‬‫ﻭﰲ ﺣﺎﻟﺔ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺳﻲ ﺃﻭ ﺳﻲ++ ﻓﺎﻧﻪ ﳚﺐ ﺇﻋﺎﺩﺓ ﺗﻄﻮﻳﺮ ﺍﺟﺰﺍء ﻣﻦ ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++ ﺍﻟﻘﻴﺎﺳﻴﺔ‬‫)‪ (Standard C/C++ Library‬ﻭﻫﻲ ﺍﻷﺟﺰﺍء ﺍﻟﱵ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻣﺜﻞ ﺩﻭﺍﻝ ‪ printf‬ﻭ ‪ scanf‬ﻭ‬‫٧٠١‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫ﺩﻭﺍﻝ ﺣﺠﺰ ﺍﻟﺬﻭﺍﻛﺮ ‪ malloc/new‬ﻭﲢﺮﻳﺮﻫﺎ ‪.free/delete‬‬‫ﻭﻧﻈﺮﺍ ﻻﻧﻨﺎ ﺑﺼﺪﺩ ﺑﺮﳎﺔ ﻧﻈﺎﻡ 23 ﺑﺖ ، ﻓﺎﻥ ﺍﻟﻨﻮﺍﺓ ﺃﻳﻀﺎ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ 23 ﺑﺖ ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻧﻪ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ‬‫ﻣﺘﺮﺟﻢ ﺳﻲ ﺃﻭ ﺳﻲ++ 23 ﺑﺖ . ﻣﺸﻜﻠﺔ ﻫﺬﻩ ﺍﳌﺘﺮﲨﺎﺕ ﺃﻥ ﺍﳌﺨﺮﺝ ﻣﻨﻬﺎ )ﺍﻟﱪﻧﺎﻣﺞ( ﻻ ﻳﺄﰐ ﺑﺎﻟﺸﻜﻞ ﺍﻟﺜﻨﺎﺋﻲ‬‫ﻓﻘﻂ )‪ ،٤ (Flat Binary‬ﻭﺍﳕﺎ ﻳﻀﺎﻑ ﻋﻠﻰ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺜﻨﺎﺋﻴﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻷﺷﻴﺎء ‪ .Headers,...etc‬ﻭﻟﺘﺤﻤﻴﻞ ﻣﺜﻞ‬‫ﻫﺬﻩ ﺍﻟﱪﺍﻣﺞ ﻓﺎﻧﻪ ﳚﺐ ﺍﻟﺒﺤﺚ ﻋﻦ ﻧﻘﻄﺔ ﺍﻹﻧﻄﻼﻕ ﻟﻠﱪﻧﺎﻣﺞ )‪ (main rou ne‬ﻭﻣﻦ ﰒ ﺍﻟﺒﺪء ﺑﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﻣﻨﻬﺎ.‬‫ﻭﺳﻴﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻣﺘﺮﺟﻢ ﻓﻴﺠﻮﺍﻝ ﺳﻲ++ ﻟﺘﺮﲨﺔ ﺍﻟﻨﻮﺍﺓ ، ﻭﰲ ﺍﳌﻠﺤﻖ ﺳﻴﺘﻢ ﺗﻮﺿﻴﺢ ﺧﻄﻮﺍﺕ ‪‬ﻴﺌﺔ ﺍﳌﺸﺮﻭﻉ‬ ‫ﻭﺍﺯﺍﻟﺔ ﺃﻱ ﺍﻋﺘﻤﺎﺩﻳﺔ ﻋﻠﻰ ﻣﻜﺘﺒﺎﺕ ﺃﻭ ﻣﻠﻔﺎﺕ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ.‬‫ﻭﺳﻨﻌﻴﺪ ﻛﺘﺎﺑﺔ ﺍﻟﻨﻮﺍﺓ ﺍﻟﱵ ﻗﻤﻨﺎ ﺑﱪﳎﺘﻬﺎ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺑﻖ ﻭﻟﻜﻦ ﺑﻠﻐﺔ ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++ ، ﻭﺳﻨﻨﺎﻗﺶ‬‫ﻛﻴﻔﻴﺔ ﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﻫﺬﻩ ﺍﻟﻨﻮﺍﺓ ﺣﻴﺚ ﺃﻥ ﺍﳌﺨﺮﺝ ﻣﻦ ﻣﺘﺮﺟﻢ ﺍﻟﻔﻴﺠﻮﺍﻝ ﺳﻲ++ ﻫﻮ ﻣﻠﻒ ﺗﻨﻔﻴﺬﻱ )‪Portable‬‬‫‪ (Executable‬ﻭﻟﺪﻳﻪ ﺻﻴﻐﺔ ﳏﺪﺩﺓ ﳚﺐ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻟﺪﺍﻟﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻟﻠﻨﻮﺍﺓ ))(‪(main‬‬‫، ﻛﺬﻟﻚ ﺳﻨﺒﺪﺃ ﰲ ﺗﻄﻮﻳﺮ ﻣﻠﻔﺎﺕ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻠﻐﺔ ﺳﻲ++ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺩﻋﻢ ﺑﻌﺾ ﺧﺼﺎﺋﺺ ﺍﻟﻠﻐﺔ ﻭﺍﻟﱵ‬‫ﲢﺘﺎﺝ ﺍﱃ ﺩﻋﻢ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ ﻣﺜﻞ ﺩﻭﺍﻝ ﺍﻟﺒﻨﺎء ﻭﺍﳍﺪﻡ ﻭﺍﻟﺪﻭﺍﻝ ﺍﻟﻈﺎﻫﺮﻳﺔ )‪ ، (Pure Virtual Func on‬ﻭﰲ‬ ‫ﺍﻟﻮﻗﺖ ﺍﳊﺎﱄ ﻻ ﻳﻮﺟﺪ ﺩﻋﻢ ﻟﻺﺳﺘﺜﻨﺎﺋﺎﺕ )‪ (Excep ons‬ﰲ ﻟﻐﺔ ﺍﻟﺴﻲ++ .‬ ‫‪PE‬‬ ‫٥.٤.١. ﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﻧﻮﺍﺓ‬‫ﲟﺎ ﺃﻧﻨﺎ ﺳﻨﺴﺘﺨﺪﻡ ﻣﺘﺮﺟﻢ ﻓﻴﺠﻮﺍﻝ ﺳﻲ++ ﻭﺍﻟﺬﻱ ﳜﺮﺝ ﻟﻨﺎ ﻣﻠﻒ ﺗﻨﻔﻴﺬﻱ )‪ (Portable Executable‬ﻓﺎﻧﻪ ﳚﺐ‬‫ﺃﻥ ﻧﻌﺮﻑ ﻣﺎ ﻫﻲ ﺷﻜﻞ ﻫﺬﻩ ﺍﻟﺼﻴﻐﺔ ﺣﱴ ﻧﺘﻤﻜﻦ ﻋﻨﺪ ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺃﻥ ﻧﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﺪﺍﻟﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﻟﻴﺴﺖ‬‫ﺍﱃ ﺃﻣﺎﻛﻦ ﺃﺧﺮﻯ.ﻭﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﺘﺮﲨﺎﺕ ﺳﻲ++ ﺃﺧﺮﻯ )ﻣﺜﻞ ﻣﺘﺮﺟﻢ ++‪ (g‬ﻟﻜﻦ ﳚﺐ ﻣﻼﺣﻈﺔ ﺃﻥ ﻫﺬﺍ‬‫ﺍﳌﺘﺮﺟﻢ ﳜﺮﺝ ﻟﻨﺎ ﻣﻠﻒ ﺑﺼﻴﻐﺔ ‪ ELF‬ﻭﻫﻲ ﺻﻴﻐﺔ ﺍﳌﻠﻔﺎﺕ ﺍﻟﺘﻨﻔﻴﺬﻳﺔ ﻋﻠﻰ ﻧﻈﺎﻡ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ. ﻭﺍﻟﺸﻜﻞ ﺍﻟﺘﺎﱄ‬ ‫ﻳﻮﺿﺢ ﺻﻴﻐﺔ ﻣﻠﻒ ‪ PE‬ﺍﻟﺬﻱ ﳓﻦ ﺑﺼﺪﺩ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ.‬‫ﻳﻮﺟﺪ ﺃﺭﺑﻊ ﺍﺿﺎﻓﺎﺕ)‪ (headers‬ﻟﺼﻴﻐﺔ ‪ PE‬ﺳﻨﻄﻠﻊ ﻋﻠﻴﻬﺎ ﺑﺸﻜﻞ ﺳﺮﻳﻊ ﻭﰲ ﺣﺎﻟﺔ ﻗﻤﻨﺎ ﺑﺘﻄﻮﻳﺮ ﳏﻤﻞ ﺧﺎﺹ ﳍﺬﻩ‬ ‫ﺍﻟﺼﻴﻐﺔ ﻓﺴﻴﺘﻢ ﺩﺭﺍﺳﺘﻬﺎ ﺑﺎﻟﺘﻔﺼﻴﻞ. ﻭ ﳝﻜﻦ ﺃﻥ ﻧﺼﻒ ﻫﺬﻩ ﺍﻻﺿﺎﻓﺎﺕ ﺑﻠﻐﺔ ﺍﻟﺴﻲ++ ﻛﺎﻟﺘﺎﱄ.‬ ‫‪Example‬‬ ‫‪٥.١: Portable Executable Header‬‬‫١‬‫‪٢ // header information format for PE files‬‬‫٣‬‫‪٤ typedef struct‬‬ ‫‪IMAGE DOS HEADER { // DOS .EXE header‬‬‫٥‬ ‫‪unsigned‬‬ ‫‪short e magic; // Magic number (Should be MZ‬‬‫٦‬ ‫‪unsigned‬‬ ‫;‪short e cblp‬‬ ‫‪// Bytes on last page of file‬‬‫٧‬ ‫‪unsigned‬‬ ‫;‪short e cp‬‬ ‫‪// Pages in file‬‬‫٨‬ ‫‪unsigned‬‬ ‫;‪short e crlc‬‬ ‫‪// Relocations‬‬‫٩‬ ‫‪unsigned‬‬ ‫‪short e cparhdr; // Size of header in paragraphs‬‬‫٠١‬ ‫‪unsigned‬‬ ‫;‪short e minalloc‬‬ ‫‪// Minimum extra paragraphs needed‬‬ ‫٤ﻛﱪﻧﺎﻣﺞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﻗﻤﻨﺎ ﺑﺘﻄﻮﻳﺮﻩ ﰲ ﺑﺪﺍﻳﺔ ﻫﺬﺍ ﺍﻟﺒﺤﺚ.‬ ‫٨٠١‬
    • ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬١١ unsigned short e maxalloc; // Maximum extra paragraphs needed١٢ unsigned short e ss; // Initial (relative) SS value١٣ unsigned short e sp; // Initial SP value١٤ unsigned short e csum; // Checksum١٥ unsigned short e ip; // Initial IP value١٦ unsigned short e cs; // Initial (relative) CS value١٧ unsigned short e lfarlc; // File address of relocation table١٨ unsigned short e ovno; // Overlay number١٩ unsigned short e res[4]; // Reserved words٢٠ unsigned short e oemid; // OEM identifier (for e oeminfo)٢١ unsigned short e oeminfo; // OEM information; e oemid specific٢٢ unsigned short e res2[10]; // Reserved words٢٣ long e lfanew; // File address of new exe header٢٤ } IMAGE DOS HEADER, ∗ PIMAGE DOS HEADER;٢٥٢٦٢٧ // Real mode stub program٢٨٢٩ typedef struct IMAGE FILE HEADER {٣٠ unsigned short Machine;٣١ unsigned short NumberOfSections;٣٢ unsigned long TimeDateStamp;٣٣ unsigned long PointerToSymbolTable;٣٤ unsigned long NumberOfSymbols;٣٥ unsigned short SizeOfOptionalHeader;٣٦ unsigned short Characteristics;٣٧ } IMAGE FILE HEADER, ∗ PIMAGE FILE HEADER;٣٨٣٩ typedef struct IMAGE OPTIONAL HEADER {٤٠ unsigned short Magic;٤١ unsigned char MajorLinkerVersion;٤٢ unsigned char MinorLinkerVersion;٤٣ unsigned long SizeOfCode;٤٤ unsigned long SizeOfInitializedData;٤٥ unsigned long SizeOfUninitializedData;٤٦ unsigned long AddressOfEntryPoint; // offset of kernel entry٤٧ unsigned long BaseOfCode;٤٨ unsigned long BaseOfData;٤٩ unsigned long ImageBase; // Base address of kernel entry٥٠ unsigned long SectionAlignment;٥١ unsigned long FileAlignment;١٠٩
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬٥٢ unsigned short MajorOperatingSystemVersion;٥٣ unsigned short MinorOperatingSystemVersion;٥٤ unsigned short MajorImageVersion;٥٥ unsigned short MinorImageVersion;٥٦ unsigned short MajorSubsystemVersion;٥٧ unsigned short MinorSubsystemVersion;٥٨ unsigned long Reserved1;٥٩ unsigned long SizeOfImage;٦٠ unsigned long SizeOfHeaders;٦١ unsigned long CheckSum;٦٢ unsigned short Subsystem;٦٣ unsigned short DllCharacteristics;٦٤ unsigned long SizeOfStackReserve;٦٥ unsigned long SizeOfStackCommit;٦٦ unsigned long SizeOfHeapReserve;٦٧ unsigned long SizeOfHeapCommit;٦٨ unsigned long LoaderFlags;٦٩ unsigned long NumberOfRvaAndSizes;٧٠ IMAGE DATA DIRECTORY DataDirectory[DIRECTORY ENTRIES];٧١ } IMAGE OPTIONAL HEADER, ∗ PIMAGE OPTIONAL HEADER;‫( ﻭﺍﻟﱵ ﺳﻴﺒﺪﺃ ﺗﻨﻔﻴﺬ ﺍﻟﻨﻮﺍﺓ ﻣﻨﻬﺎ‬kernel entry()) ‫ﻣﺎ ﻧﺮﻳﺪ ﺍﳊﺼﻮﻝ ﻋﻠﻴﻪ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻟﺪﺍﻟﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻟﻠﻨﻮﺍﺓ‬، IMAGE OPTIONAL HEADER ‫( ﻭﻫﻲ‬header) ‫، ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻮﺟﻮﺩ ﰲ ﺃﺣﺪ ﺍﳌﺘﻐﲑﺍﺕ ﰲ ﺁﺧﺮ ﺇﺿﺎﻓﺔ‬‫ﻭﺣﱴ ﳓﺼﻞ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﻫﺬﻩ ﺍﻷﺿﺎﻓﺔ ﳚﺐ ﺃﻥ ﻧﺒﺪﺃ ﻣﻦ ﺃﻭﻝ ﺇﺿﺎﻓﺔ ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺍﻻﺿﺎﻓﺔ ﺍﻟﺜﺎﻧﻴﺔ ﺫﺍﺕ‬ .‫ﺣﺠﻢ ﻣﺘﻐﲑ ﻭﻟﻴﺴﺖ ﺛﺎﺑﺘﻪ ﻣﺜﻞ ﺑﻘﻴﺔ ﺍﻻﺿﺎﻓﺎﺕ‬‫ ﺣﻴﺚ ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻹﺿﺎﻓﺔ‬e lfanew ‫ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﺍﳌﺘﻐﲑ‬IMAGE DOS HEADER ‫ﻭﺑﺎﻟﻨﻈﺮ ﺍﱃ ﺃﻭﻝ ﺇﺿﺎﻓﺔ‬‫ ﻭﺍﻟﱵ ﻫﻲ ﺍﺿﺎﻓﺔ ﺛﺎﺑﺘﻪ ﺍﳊﺠﻢ ، ﻭﻣﻨﻬﺎ ﻧﺼﻞ ﺍﱃ ﺁﺧﺮ ﺇﺿﺎﻓﺔ ﻭﻧﻘﺮﺃ ﺍﳌﺘﻐﲑ‬IMAGE FILE HEADER ‫ﺍﻟﺜﺎﻟﺜﺔ‬‫ ﻭﺍﻟﺬﻱ‬ImageBase ‫ ﻟﻠﺪﺍﻟﺔ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﻛﺬﻟﻚ ﻧﻘﺮﺃ ﺍﳌﺘﻐﲑ‬offset ‫ ﺍﻟﺬﻱ ﳛﻮﻱ ﻋﻨﻮﺍﻥ‬AddressOfEntryPoint‫ ، ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺘﻢ ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﺪﺍﻟﺔ ﺑﻮﺍﺳﻄﺔ ﺍﻻﻣﺮ‬offset ‫ﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻟﺒﺪﺍﻳﺔ ﻟﻠﺪﺍﻟﺔ ﻭﳚﺐ ﺍﺿﺎﻓﺘﻪ ﻟﻘﻴﻤﺔ ﺍﻝ‬‫. ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻃﺮﻳﻘﺔ ﺫﻟﻚ )ﻭﻳﺘﻢ ﺗﻨﻔﻴﺬﻫﺎ ﰲ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻣﺒﺎﺷﺮﺓ ﺑﻌﺪﻣﺎ‬call .(KERNEL PMODE BASE ‫ﻳﺘﻢ ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻋﻠﻰ ﺍﻟﻌﻨﻮﺍﻥ‬ Example ٥.٢: Ge ng Kernel entry١٢٣ mov ebx,[KERNEL PMODE BASE+60]٤ add ebx,KERNEL PMODE BASE ; ebx = IMAGE FILE HEADER٥٦ add ebx,24 ; ebx = IMAGE OPTIONAL HEADER ١١٠
    • ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬‫٧‬‫٨‬ ‫61,‪add ebx‬‬ ‫‪; ebx point to AddressOfEntryPoint‬‬‫٩‬‫٠١‬ ‫]‪mov ebp,dword[ebx‬‬ ‫‪; epb = AddressOfEntryPoint‬‬‫١١‬‫٢١‬ ‫21,‪add ebx‬‬ ‫‪; ebx point to ImageBase‬‬‫٣١‬‫٤١‬ ‫]‪add ebp,dword[ebx‬‬ ‫‪; epb = kernel entry‬‬‫٥١‬‫٦١‬ ‫‪cli‬‬‫٧١‬‫٨١‬ ‫‪call ebp‬‬ ‫٥.٤.٢. ﺗﻄﻮﻳﺮ ﺑﻴﺌﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻠﻐﺔ ﺳﻲ++‬‫ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ﲨﻴﻊ ﺧﺼﺎﺋﺺ ﻟﻐﺔ ﺳﻲ++ ﻓﺎﻧﻪ ﳚﺐ ﻛﺘﺎﺑﺔ ﺑﻌﺾ ﺍﻟﺸﻔﺮﺍﺕ ﺍﻟﺘﺸﻐﻴﻠﻴﺔ )‪(startup‬‬‫ﻭﺍﻟﱵ ﲤﻬﺪ ﻭﺗﻌﺮﻑ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﰲ ﺍﻟﻠﻐﺔ ، ﻭﰲ ﻫﺬﺍ ﺍﳉﺰء ﺳﻴﺘﻢ ﺗﻄﻮﻳﺮ ﻣﻜﺘﺒﺔ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻠﻐﺔ‬‫ﺳﻲ++ )‪ (C++ Run me Library‬ﻭﺫﻟﻚ ﻧﻈﺮﴽ ﻷﻧﻨﺎ ﻗﺪ ﺍﻟﻐﻴﻨﺎ ﺍﻹﻋﺘﻤﺎﺩ ﻋﻠﻰ ﻣﻜﺘﺒﺔ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ ﺍﻟﱵ ﺗﺄﰐ ﻣﻊ‬‫ﺍﳌﺘﺮﺟﻢ ﺍﳌﺴﺘﺨﺪﻡ ﰲ ﺑﻨﺎء ﺍﻟﻨﻈﺎﻡ )ﺍﻟﻨﻈﺎﻡ ﺍﳋﺎﺹ ﺑﻨﺎ( ﺣﻴﺚ ﺃﻥ ﻫﺬﻩ ﺍﳌﻜﺘﺒﺔ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺍﳌﺴﺘﺨﺪﻡ‬ ‫ﰲ ﻋﻤﻠﻴﺔ ﺍﻟﺘﻄﻮﻳﺮ ﳑﺎ ﻳﺴﺒﺐ ﻣﺸﺎﻛﻞ ﺍﺳﺘﺪﻋﺎء ﺩﻭﺍﻝ ﻟﻴﺴﺖ ﻣﻮﺟﻮﺩﺓ.‬‫ﻭﺑﺪﻭﻥ ﺗﻄﻮﻳﺮ ﻫﺬﻩ ﺍﳌﻜﺘﺒﺔ ﻓﻠﻦ ﳝﻜﻦ ‪‬ﻴﺌﺔ ﺍﻟﻜﺎﺋﻨﺎﺕ ﺍﻟﻌﺎﻣﺔ )‪ (Global Object‬ﻭ ﺣﺬﻑ ﺍﻟﻜﺎﺋﻨﺎﺕ ، ﻭﻛﺬﻟﻚ‬ ‫ﻟﻦ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﺑﻌﺾ ﺍﳌﻌﺎﻣﻼﺕ )‪ (new,delete‬ﻭ ‪ RTTI‬ﻭﺍﻻﺳﺘﺜﻨﺎﺋﺎﺕ )‪.(Excep ons‬‬ ‫‪Global Operator‬‬ ‫ﺍﳌﻌﺎﻣﻼﺕ ﺍﻟﻌﺎﻣﺔ‬‫ﺳﻴﺘﻢ ﺗﻌﺮﻳﻒ ﻣﻌﺎﻣﻞ ﺣﺠﺰ ﺍﻟﺬﺍﻛﺮﺓ )‪ (new‬ﻭﲢﺮﻳﺮﻫﺎ )‪ (delete‬ﰲ ﻟﻐﺔ ﺍﻟﺴﻲ++ ، ﻭﻟﻜﻦ ﻻﻧﻨﺎ ﺣﺎﻟﻴﺎ ﱂ‬ ‫ﻧﱪﻣﺞ ﻣﺪﻳﺮﴽ ﻟﻠﺬﺍﻛﺮﺓ ﻓﺎﻥ ﺍﻟﺘﻌﺮﻳﻒ ﺳﻴﻜﻮﻥ ﺧﺎﻟﻴﺎ.ﻭﺍﳌﻘﻄﻊ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺫﻟﻚ.‬ ‫‪Example‬‬ ‫‪٥.٣: Global new/delete operator‬‬‫١‬‫∗‪٢ void‬‬ ‫‪cdecl ::operator new (unsigned‬‬ ‫};0 ‪int size){return‬‬‫∗‪٣ void‬‬ ‫‪cdecl operator new[] (unsigned‬‬ ‫};0 ‪int size){return‬‬‫‪٤ void‬‬ ‫∗ ‪cdecl ::operator delete (void‬‬ ‫}{)‪p‬‬‫‪٥ void‬‬ ‫∗ ‪cdecl operator delete[] (void‬‬ ‫}{)‪p‬‬‫١١١‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫‪Pure virtual func on call handler‬‬‫ﺍﻳﻀﺎ ﳚﺐ ﺗﻌﺮﻳﻒ ﺩﺍﻟﺔ ﻟﻠﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻟﺪﻭﺍﻝ ﺍﻟﻈﺎﻫﺮﻳﺔ ﺍﻟﻨﻘﻴﺔ ) ‪ ،٥ (Pure virtual func on‬ﺣﻴﺚ ﺳﻴﻘﻮﻡ ﺍﳌﺘﺮﺟﻢ‬‫ﺑﺎﺳﺘﺪﻋﺎء ﺍﻟﺪﺍﻟﺔ )(‪ ٦ purecall‬ﺃﻳﻨﻤﺎ ﻭﺟﺪ ﻋﻤﻠﻴﺔ ﺍﺳﺘﺪﻋﺎء ﻟﺪﺍﻟﺔ ‪ ، Pure virtual‬ﻟﺬﻟﻚ ﺃﻥ ﺃﺭﺩﻧﺎ ﺩﻋﻢ‬ ‫ﺍﻟﺪﻭﺍﻝ ‪ Pure virtual‬ﳚﺐ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ ‪ ، purecall‬ﻭﺣﺎﻟﻴﺎ ﺳﻴﻜﻮﻥ ﺍﻟﺘﻌﺮﻳﻒ ﻛﺎﻻﰐ.‬ ‫‪Example‬‬ ‫‪٥.٤: Pure virtual func‬‬ ‫‪on call handler‬‬‫١‬‫‪٢ int‬‬ ‫} ;0 ‪cdecl :: purecall() { for (;;); return‬‬ ‫‪Floa ng Point Support‬‬ ‫ﺩﻋﻢ ﺍﻟﻔﺎﺻﻠﺔ ﺍﻟﻌﺎﺋﻤﺔ‬‫ﻟﺪﻋﻢ ﺍﻟﻔﺎﺻﻠﺔ ﺍﻟﻌﺎﺋﻤﺔ )‪ (Floa ng Point‬ﰲ ﺳﻲ++ ﻓﺎﻧﻪ ﳚﺐ ﺗﻌﻴﲔ ﺍﻟﻘﻴﻤﺔ 1 ﻟﻠﻤﺘﻐﲑ ‪ ، fltused‬ﻭﻛﺬﻟﻚ‬ ‫ﳚﺐ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ )(‪ ftol2 sse‬ﻭﺍﻟﱵ ﲢﻮﻝ ﻣﻦ ﺍﻟﻨﻮﻉ ‪ float‬ﺍﱃ ﺍﻟﻨﻮﻉ ‪ long‬ﻛﺎﻟﺘﺎﱄ.‬ ‫‪Example‬‬ ‫‪٥.٥: Floa‬‬ ‫‪ng Point Support‬‬‫١‬‫٢‬‫‪٣ extern "C" long‬‬ ‫)‪declspec (naked‬‬ ‫{ )(‪ftol2 sse‬‬‫٤‬ ‫;‪int a‬‬‫٥‬ ‫683‪#ifdef i‬‬‫٦‬ ‫{ ‪asm‬‬‫٧‬ ‫]‪fistp [a‬‬‫٨‬ ‫‪mov ebx, a‬‬‫٩‬ ‫}‬‫‪١٠ #endif‬‬‫١١‬ ‫}‬‫٢١‬‫‪١٣ extern "C" int‬‬ ‫;1 = ‪fltused‬‬ ‫٥ﻋﻨﺪ ﺗﻌﺮﻳﻒ ﺩﺍﻟﺔ ﺑﺄ‪‬ﺎ ‪ Pure virtual‬ﺩﺍﺧﻞ ﺃﻱ ﻓﺌﺔ ﻓﺈﻥ ﻫﺬﺍ ﻳﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﻟﻔﺌﺔ ﳎﺮﺩﺓ )‪ (Abstract‬ﻭﳚﺐ ﺇﻋﺎﺩﺓ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ‬ ‫)‪ (Override‬ﰲ ﺍﻟﻔﺌﺎﺕ ﺍﳌﺸﺘﻘﺔ ﻣﻦ ﺍﻟﻔﺌﺔ ﺍﻟﱵ ﲢﻮﻱ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ، ﻭﺍﻻ ﺳﺘﻜﻮﻥ ﺍﻟﻔﺌﺔ ﺍﳌﺸﺘﻘﺔ .‬ ‫٦ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﻳﻘﻮﻡ ﻣﺘﺮﺟﻢ ﺍﻟﻔﻴﺠﻮﺍﻝ ﺳﻲ++ ﺑﺎﺳﺘﺪﻋﺎﺋﻬﺎ.ﻭﻗﺪ ﲣﺘﻠﻒ ﻣﻦ ﻣﺘﺮﺟﻢ ﻵﺧﺮ.‬ ‫٢١١‬
    • ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬ ‫‪‬ﻴﺌﺔ ﺍﻟﻜﺎﺋﻨﺎﺕ ﺍﻟﻌﺎﻣﺔ ﻭﺍﻟﺴﺎﻛﻨﺔ‬‫ﺍﻟﱪﻧﺎﻣﺞ ٧‬ ‫ﻋﻨﺪﻣﺎ ﳚﺪ ﺍﳌﺘﺮﺟﻢ ﻛﺎﺋﻨﺎ ﻓﺎﻧﻪ ﻳﻀﻴﻒ ﻣﻬﻴﺌﴼ ﺩﻳﻨﺎﻣﻴﻜﻴﺎ ﻟﻪ )‪ (Dynamic ini alizer‬ﰲ ﻗﺴﻢ ﺧﺎﺹ ﻣﻦ‬‫ﻭﻫﻮ ﺍﻟﻘﺴﻢ ‪ ..crt‬ﻭﻗﺒﻞ ﺃﻥ ﻳﻌﻤﻞ ﺍﻟﱪﻧﺎﻣﺞ ﻓﺎﻥ ﻭﻇﻴﻔﺔ ﻣﻜﺘﺒﺔ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ ﻫﻲ ﺍﺳﺘﺪﻋﺎء ﻭﺗﻨﻔﻴﺬ ﻛﻞ‬‫ﺍﳌﻬﻴﺌﺎﺕ ﻭﺫﻟﻚ ﺣﱴ ﺗﺄﺧﺬ ﺍﻟﻜﺎﺋﻨﺎﺕ ﻗﻴﻤﻬﺎ ﺍﻻﺑﺘﺪﺍﺋﻴﺔ )ﻋﱪ ﺩﺍﻟﺔ ﺍﻟﺒﻨﺎء ‪ .(Constructor‬ﻭﺑﺴﺒﺐ ﺃﻧﻨﺎ ﺃﺯﻟﻨﺎ ﻣﻜﺘﺒﺔ‬‫ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ ﻓﺎﻧﻪ ﳚﺐ ﺍﻧﺸﺎء ﺍﻟﻘﺴﻢ ‪ .crt‬ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﻣﻮﺟﻬﺎﺕ ﺍﳌﻌﺎﰿ ﺍﻟﺘﻤﻬﻴﺪﻱ)‪(Preprocessor‬‬ ‫ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﺍﳌﺘﺮﺟﻢ.‬‫ﻫﺬﺍ ﺍﻟﻘﺴﻢ ‪ .crt‬ﳛﻮﻱ ﻣﺼﻔﻮﻓﺔ ﻣﻦ ﻣﺆﺷﺮﺍﺕ ﺍﻟﺪﻭﺍﻝ )‪ ، (Func on Pointer‬ﻭﻭﻇﻴﻔﺔ ﻣﻜﺘﺒﺔ ﻭﻗﺖ ﺍﻟﺘﺸﻐﻴﻞ‬‫ﻫﻲ ﺍﺳﺘﺪﻋﺎء ﻛﻞ ﺍﻟﺪﻭﺍﻝ ﺍﳌﻮﺟﻮﺩﺓ ﻭﺫﻟﻚ ﺑﺎﳌﺮﻭﺭ ﻋﻠﻰ ﻣﺼﻔﻮﻓﺔ ﺍﳌﺆﺷﺮﺍﺕ ﺍﳌﻮﺟﻮﺩﺓ . ﻭ ﳚﺐ ﺃﻥ ﻧﻌﻠﻢ ﺃﻥ‬‫ﻣﺼﻔﻮﻓﺔ ﺍﳌﺆﺷﺮﺍﺕ ﻣﻮﺟﻮﺩﺓ ﺣﻘﻴﻘﺔ ﺩﺍﺧﻞ ﺍﻟﻘﺴﻢ ‪ .crt:xcu‬ﺣﻴﺚ ﺃﻥ ﺍﳉﺰء ﺍﻟﺬﻱ ﻳﻠﻲ ﺍﻟﻌﻼﻣﺔ ‪dollar sign‬‬‫ﳛﺪﺩ ﺍﳌﻜﺎﻥ ﺑﺪﺍﺧﻞ ﺍﻟﻘﺴﻢ ، ﻭﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﺳﺘﺪﻋﺎء ﻭﺗﻨﻔﻴﺬ ﺍﻟﺪﻭﺍﻝ ﻋﻦ ﻃﺮﻳﻖ ﻣﺼﻔﻮﻓﺔ ﺍﳌﺆﺷﺮﺍﺕ ﻓﺎﻧﻪ‬‫ﳚﺐ ﺍﻧﺸﺎء ﻣﺆﺷﺮ ﺍﱃ ﺑﺪﺍﻳﺔ ﺍﻟﻘﺴﻢ ‪ .crt:xcu‬ﻭﰲ ‪‬ﺎﻳﺘﻪ ، ﻣﺆﺷﺮ ﺍﻟﺒﺪﺍﻳﺔ ﺳﻴﻜﻮﻥ ﰲ ﺍﻟﻘﺴﻢ ‪.crt:xca‬‬‫ﻭﻫﻮ ﻳﺴﺒﻖ ﺍﻟﻘﺴﻢ ‪ .crt:xcu‬ﻣﺒﺎﺷﺮﺓ ، ﻭﻣﺆﺷﺮ ﺍﻟﻨﻬﺎﻳﺔ ﺳﻴﻜﻮﻥ ﰲ ﺍﻟﻘﺴﻢ ‪ .crt:xcz‬ﻭﻳﻠﻲ ﺍﻟﻘﺴﻢ‬ ‫‪ .crt:xcu‬ﻣﺒﺎﺷﺮﺓ .‬‫ﻭﲞﺼﻮﺹ ﺍﻟﻘﺴﻢ ‪ .crt‬ﺍﻟﺬﻱ ﺳﻨﻨﺸﺌﻪ ﻓﺎﻧﻨﺎ ﻻ ﳕﻠﻚ ﺻﻼﺣﻴﺎﺕ ﻗﺮﺍءﺓ ﻭﻛﺘﺎﺑﺔ ﻓﻴﻪ ، ﻟﺬﻟﻚ ﺍﳊﻞ ﰲ ﺃﻥ ﻧﻘﻮﻡ‬ ‫ﺑﺪﻣﺞ ﻫﺬﺍ ﺍﻟﻘﺴﻢ ﻣﻊ ﻗﺴﻢ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪. .data‬‬ ‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻣﺎ ﺳﺒﻖ.‬ ‫‪Example‬‬ ‫‪٥.٦: Object Ini‬‬ ‫‪alizer‬‬‫١‬‫‪٢ // Function pointer typedef for less typing‬‬‫( ‪٣ typedef void‬‬ ‫;)‪cdecl ∗ PVFV)(void‬‬‫٤‬‫// ٥‬ ‫‪x c a points to beginning of initializer table‬‬‫)"‪٦ #pragma data seg(".CRT$XCA‬‬‫٧‬ ‫‪PVFV‬‬ ‫;} 0 { = ][ ‪x c a‬‬‫٨‬‫// ٩‬ ‫‪x c z points to end of initializer table‬‬‫)"‪١٠ #pragma data seg(".CRT$XCZ‬‬‫‪١١ PVFV‬‬ ‫;} 0 { = ][ ‪x c z‬‬‫٢١‬‫‪١٣ // Select the default data segment again (.data) for the rest of the‬‬ ‫‪unit‬‬‫)(‪١٤ #pragma data seg‬‬‫٥١‬ ‫‪.stack‬‬ ‫ﻭﺍﳌﻜﺪﺱ‬ ‫‪.code‬‬ ‫ﻭﻗﺴﻢ ﺍﻟﺸﻔﺮﺓ‬ ‫‪.data‬‬ ‫٧ﰲ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﺗﻨﻔﻴﺬﻱ ﻳﻮﺟﺪ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻷﻗﺴﺎﻡ، ﻣﺜﻼ ﻗﺴﻢ ﺍﻟﺒﻴﺎﻧﺎﺕ‬ ‫ﻭﻏﲑﻫﺎ.‬‫٣١١‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬١٦ // Now, move the CRT data into .data section so we can read/write to it١٧ #pragma comment(linker, "/merge:.CRT=.data")١٨١٩٢٠ // initialize all global initializers (ctors, statics, globals, etc ..)٢١ void cdecl initterm ( PVFV ∗ pfbegin, PVFV ∗ pfend ) {٢٢٢٣ //! Go through each initializer٢٤ while ( pfbegin < pfend )٢٥ {٢٦ //! Execute the global initializer٢٧ if ( ∗pfbegin != 0 )٢٨ (∗∗pfbegin) ();٢٩٣٠ //! Go to next initializer inside the initializer table٣١ ++pfbegin;٣٢ }٣٣ }٣٤٣٥ // execute all constructors and other dynamic initializers٣٦ void cdecl init ctor() {٣٧٣٨ atexit init();٣٩ initterm( xc a , x c z );٤٠ } ‫ﺣﺬﻑ ﺍﻟﻜﺎﺋﻨﺎﺕ‬، (deini alizer array) ‫( ﳚﺐ ﺍﻧﺸﺎء ﻣﺼﻔﻮﻓﺔ ﻣﻦ ﻣﺆﺷﺮﺍﺕ ﺩﻭﺍﻝ ﺍﳍﺪﻡ‬Objects) ‫ﻟﻜﻲ ﻳﺘﻢ ﺣﺬﻑ ﺍﻟﻜﺎﺋﻨﺎﺕ‬‫ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺍﳌﺘﺮﺟﻢ ﻋﻨﺪﻣﺎ ﳚﺪ ﺩﺍﻟﺔ ﻫﺪﻡ ﻓﺎﻧﻪ ﻳﻀﻴﻒ ﻣﺆﺷﺮﴽ ﺍﱃ ﺩﺍﻟﺔ ﺍﳍﺪﻡ ﺑﺪﺍﺧﻞ ﻫﺬﻩ ﺍﳌﺼﻔﻮﻓﺔ ﻭﺫﻟﻚ‬‫ ﺣﻴﺚ ﺃﻥ ﻣﺘﺮﺟﻢ‬atexit ‫(، ﻭﳚﺐ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ‬exit() ‫ﺣﱴ ﻳﺘﻢ ﺍﺳﺘﺪﻋﺎﺋﻬﺎ ﻻﺣﻘﺎ )ﻋﻨﺪ ﺍﺳﺘﺪﻋﺎء ﺍﻟﺪﺍﻟﺔ‬‫ﺍﻟﻔﻴﺠﻮﺍﻝ ﺳﻲ++ ﻳﻘﻮﻡ ﺑﺎﺳﺘﺪﻋﺎﺋﻬﺎ ﻋﻨﺪﻣﺎ ﳚﺪ ﺃﻱ ﻛﺎﺋﻦ ، ﻭﻇﻴﻔﺔ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﻫﻲ ﺍﺿﺎﻓﺔ ﻣﺆﺷﺮ ﻟﺪﺍﻟﺔ ﻫﺪﻡ‬. ‫ﺍﻟﻜﺎﺋﻦ ﺍﱃ ﻣﺼﻔﻮﻓﺔ ﺍﳌﺆﺷﺮﺍﺕ ،ﻭﲞﺼﻮﺹ ﻣﺼﻔﻮﻓﺔ ﺍﳌﺆﺷﺮﺍﺕ ﻓﺎﻧﻪ ﳝﻜﻦ ﺣﻔﻈﻬﺎ ﰲ ﺃﻱ ﻣﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ‬ .‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻣﺎ ﺳﺒﻖ‬ Example ٥.٧: Delete Object ١١٤
    • ‫٥.٤. ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ‬١٢ /! function pointer table to global deinitializer table٣ static PVFV ∗ pf atexitlist = 0;٤٥ // Maximum entries allowed in table. Change as needed٦ static unsigned max atexitlist entries = 32;٧٨ // Current amount of entries in table٩ static unsigned cur atexitlist entries = 0;١٠١١ //! initialize the de−initializer function table١٢ void cdecl atexit init(void) {١٣١٤ max atexitlist entries = 32;١٥١٦ // Warning: Normally, the STDC will dynamically allocate this. Because we have no memory manager, just choose١٧ // a base address that you will never use for now١٨ pf atexitlist = ( PVFV ∗)0x5000;١٩ }٢٠٢١ //! adds a new function entry that is to be called at shutdown٢٢ int cdecl atexit( PVFV fn) {٢٣٢٤ //! Insure we have enough free space٢٥ if (cur atexitlist entries>=max atexitlist entries)٢٦ return 1;٢٧ else {٢٨٢٩ //! Add the exit routine٣٠ ∗(pf atexitlist++) = fn;٣١ cur atexitlist entries++;٣٢ }٣٣ return 0;٣٤ }٣٥٣٦ //! shutdown the C++ runtime; calls all global de−initializers٣٧ void cdecl exit () {٣٨٣٩ //! Go through the list, and execute all global exit routines٤٠ while (cur atexitlist entries−−) {١١٥
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬٤١٤٢ //! execute function٤٣ (∗(−−pf atexitlist)) ();٤٤ }٤٥ } ‫٥.٤.٣. ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﻨﻮﺍﺓ‬‫ ﻭﺍﻟﱵ ﺗﻌﺘﱪ‬kernel entry() ‫ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﺪﺍﻟﺔ‬PE ‫( ﻟﺼﻴﻐﺔ ﻣﻠﻒ‬Parsing) ‫ﺑﻌﺪ ﺃﻥ ﻗﻤﻨﺎ ﺑﻌﻤﻞ ﲢﻠﻴﻞ‬‫ﺃﻭﻝ ﺩﺍﻟﺔ ﻳﺘﻢ ﺗﻨﻔﻴﺬﻫﺎ ﰲ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ، ﻭﺃﻭﻝ ﻣﺎ ﳚﺐ ﺗﻨﻔﻴﺬﻩ ﻓﻴﻬﺎ ﻫﻮ ﲢﺪﻳﺪ ﻗﻴﻢ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﻭﺍﻧﺸﺎء‬‫ ﺍﻟﱵ ﲢﻮﻱ ﺷﻔﺮﺓ‬main() ‫ﺌﻴﺔ ﺍﻟﻜﺎﺋﻨﺎﺕ ﺍﻟﻌﺎﻣﺔ ﻭﻣﻦ ﰒ ﺍﺳﺘﺪﻋﺎء ﺍﻟﺪﺍﻟﺔ‬ ‫( ﻭﺑﻌﺪ ﺫﻟﻚ ﳚﺐ‬Stack) ‫ﻣﻜﺪﺱ‬‫(. ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ‬Hang) ‫ ﻳﺘﻢ ﺣﺬﻑ ﺍﻟﻜﺎﺋﻨﺎﺕ ﻭﺍﻳﻘﺎﻑ ﺍﻟﻨﻈﺎﻡ‬main() ‫ﺍﻟﻨﻮﺍﺓ ، ﻭﺍﺧﲑﺍ ﻋﻨﺪﻣﺎ ﺗﻌﻮﺩ ﺍﻟﺪﺍﻟﺔ‬ ‫ﺗﻮﺿﺢ ﺫﻟﻚ‬ Example ٥.٨: Kernel Entry rou ne١٢ extern void cdecl main (); // main function.٣ extern void cdecl init ctor(); // init constructor.٤ extern void cdecl exit (); // exit.٥٦ void cdecl kernel entry ()٧ {٨٩ #ifdef i386١٠ asm {١١ cli١٢١٣ mov ax, 10h // select data descriptor in GDT.١٤ mov ds, ax١٥ mov es, ax١٦ mov fs, ax١٧ mov gs, ax١٨ mov ss, ax // Set up base stack١٩ mov esp, 0x90000٢٠ mov ebp, esp // store current stack pointer٢١ push ebp٢٢ }٢٣ #endif ١١٦
    • ‫٥.٥. ﻧﻈﺮﺓ ﻋﻠﻰ ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ‬‫٤٢‬‫٥٢‬ ‫‪// Execute global constructors‬‬‫٦٢‬ ‫;)(‪init ctor‬‬‫٧٢‬‫٨٢‬ ‫‪// Call kernel entry point‬‬‫٩٢‬ ‫;)(‪main‬‬‫٠٣‬‫١٣‬ ‫‪// Cleanup all dynamic dtors‬‬‫٢٣‬ ‫;)(‪exit‬‬‫٣٣‬‫683‪٣٤ #ifdef i‬‬‫٥٣‬ ‫‪asm cli‬‬‫‪٣٦ #endif‬‬‫٧٣‬‫٨٣‬ ‫;);;(‪for‬‬‫٩٣‬ ‫}‬ ‫ﻭﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ )(‪ main‬ﺣﺎﻟﻴﴼ ﺳﻴﻜﻮﻥ ﺧﺎﻟﻴﺎ.‬ ‫٥.٥. ﻧﻈﺮﺓ ﻋﻠﻰ ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ‬‫ﺃﻫﻢ ﺍﳋﺼﺎﺋﺺ ﺍﻟﱵ ﳚﺐ ﻣﺮﺍﻋﺘﻬﺎ ﺃﺛﻨﺎء ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻫﻲ ﺧﺎﺻﻴﺔ ﺍﳌﺤﻤﻮﻟﻴﺔ ﻋﻠﻰ ﺻﻌﻴﺪ ﺍﻷﺟﻬﺰﺓ‬‫ﻭﺍﳌﻨﺼﺎﺕ ٨ ﻭﺧﺎﺻﻴﺔ ﻗﺎﺑﻠﻴﺔ ﺗﻮﺳﻌﺔ ﺍﻟﻨﻮﺍﺓ )‪ (Expandibility‬ﻭ ﻟﺬﻟﻚ ﰎ ﺍﻹﺗﻔﺎﻕ ﻋﻠﻰ ﺃﻥ ﺗﺼﻤﻴﻢ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ‬‫ﺇﻗﺮﺃ ﺳﻴﺘﻢ ﺑﻨﺎﺋﻬﺎ ﻋﻠﻰ ﻃﺒﻘﺔ ‪ HAL‬ﺣﱴ ﺗﺴﻤﺢ ﻷﻱ ﻣﻄﻮﺭ ﻓﻴﻤﺎ ﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺗﻄﺒﻴﻖ ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﻟﺪﻋﻢ ﺃﺟﻬﺰﺓ ﻭﻋﺘﺎﺩ‬‫ﺁﺧﺮ. ﻭﺣﱴ ﳓﺼﻞ ﻋﻠﻰ ﺃﻋﻠﻰ ﻗﺪﺭ ﻣﻦ ﺍﳌﺤﻤﻮﻟﻴﺔ ﻭﻗﺎﺑﻠﻴﺔ ﺍﻟﺘﻮﺳﻌﺔ ﰲ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻓﺎﻧﻪ ﺳﻴﺘﻢ ﺗﻘﺴﻴﻢ ﺍﻟﺸﻔﺮﺍﺕ‬‫ﺍﻟﱪﳎﻴﺔ ﻟﻠﻨﻮﺍﺓ ﺍﱃ ﻭﺣﺪﺍﺕ ﻣﺴﺘﻘﻠﺔ ﲝﻴﺚ ﺗﺆﺩﻱ ﻛﻞ ﻭﺣﺪﺓ ﻭﻇﻴﻔﺔ ﻣﺎ ، ﻭﰲ ﻧﻔﺲ ﺍﻟﻮﻗﺖ ﳚﺐ ﺃﻥ ﺗﺘﻮﺍﻓﺮ‬‫ﻭﺍﺟﻬﺔ ﻋﺎﻣﺔ )‪ (Interface‬ﻟﻜﻞ ﻭﺣﺪﺓ ﲝﻴﺚ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﺧﺪﻣﺎﺕ ﻫﺬﻩ ﺍﻟﻮﺣﺪﺓ ﺩﻭﻥ ﺍﳊﺎﺟﺔ‬‫ﳌﻌﺮﻓﺔ ﺗﻔﺎﺻﻴﻠﻬﺎ ﺍﻟﺪﺍﺧﻠﻴﺔ. ﻭﰲ ﺑﺪﺍﻳﺔ ﺗﺼﻤﻴﻢ ﺍﳌﺸﺮﻭﻉ ﻓﺎﻥ ﻋﻤﻠﻴﺔ ﺗﺼﻤﻴﻢ ﺍﻟﻮﺍﺟﻬﺔ ﺗﻌﺘﱪ ﺃﻫﻢ ﺑﻜﺜﲑ ﻣﻦ ﻋﻤﻠﻴﺔ‬‫ﺑﺮﳎﺔ ﳏﺘﻮﻳﺎﺕ ﺍﻟﻮﺣﺪﺓ ﺃﻭ ﻣﺎ ﻳﺴﻤﻰ ﺑﺎﻟﺘﻨﻔﻴﺬ )‪ (Impelmenta on‬ﻧﻈﺮﴽ ﻻﻥ ﺍﻟﺘﻨﻔﻴﺬ ﻗﺪ ﻻ ﻳﺆﺛﺮ ﻋﻠﻰ ﻫﻴﻜﻠﺔ‬ ‫ﺍﳌﺸﺮﻭﻉ ﻭﻣﻌﻤﺎﺭﻳﺘﻪ ﻣﺜﻠﻤﺎ ﺗﺆﺛﺮ ﺍﻟﻮﺍﺟﻬﺔ .‬ ‫:‪• eqraOS‬‬ ‫.‪– boot: first-stage and second-stage bootloader‬‬ ‫:‪– core‬‬ ‫.‪∗ kernel:Kernel program PE executable file type‬‬ ‫٨ﻋﻠﻰ ﻋﻜﺲ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ‪ Bootloader‬ﻭﺍﻟﺬﻱ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﻣﻌﻤﺎﺭﻳﺔ ﺍﻟﻌﺘﺎﺩ ﻭﺍﳌﻌﺎﰿ.‬‫٧١١‬
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬ ∗ hal:Hardware abstrac on layer. ∗ lib:Standard library run me and standard C/C++ library. ∗ include:Standard include headers. ∗ debug:Debug version of eqraOS. ∗ release:Final release of eqraOS. ‫٥.٦. ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﺍﻟﻘﻴﺎﺳﻴﺔ‬‫ﻧﻈﺮّ ﻷﻧﻪ ﻗﺪ ﰎ ﺇﻟﻐﺎء ﺍﻻﻋﺘﻤﺎﺩ ﻋﻠﻰ ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++ ﺍﻟﻘﻴﺎﺳﻴﺔ ﺃﺛﻨﺎء ﺗﻄﻮﻳﺮ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻓﺎﻧﻪ ﳚﺐ‬ ‫ﺍ‬‫ﺍﻧﺸﺎء ﻫﺬﻩ ﺍﳌﻜﺘﺒﺔ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺳﻲ ﻭﺳﻲ++ ، ﻭﺑﺴﺒﺐ ﺃﻥ ﻋﻤﻠﻴﺔ ﺇﻋﺎﺩﺓ ﺑﺮﳎﺔ ﻫﺬﻩ ﺍﳌﻜﺘﺒﺎﺕ‬ .‫ﻳﺘﻄﻠﺐ ﻭﻗﺘّ ﻭﺟﻬﺪﺍ ﻓﺎﻧﻨﺎ ﺳﻨﺮﻛﺰ ﻋﻠﻰ ﺑﻌﺾ ﺍﳌﻠﻔﺎﺕ ﺍﳌﺴﺘﺨﺪﻣﺔ ﺑﻜﺜﺮﺓ ﻭﻧﺘﺮﻙ ﺍﻟﺒﻘﻴﺔ ﻟﻠﺘﻄﻮﻳﺮ ﻻﺣﻘﺎ‬ ‫ﺎ‬ NULL ‫ﺗﻌﺮﻳﻒ‬ .(void*)0 ‫ﺎ ﺍﻟﻘﻴﻤﺔ 0 ﺑﻴﻨﻤﺎ ﰲ ﻟﻐﺔ ﺍﻟﺴﻲ ﺗﻌﺮﻑ ﺏ‬‫ ﻋﻠﻰ ﺃ‬NULL ‫ﰲ ﻟﻐﺔ ﺳﻲ++ ﻳﺘﻢ ﺗﻌﺮﻳﻒ‬ Example ٥.٩: null.h:Defini on of NULL in C and C++١٢ #ifndef NULL H٣ #define NULL H٤٥ #if define ( MSC VER) && ( MSC VER > = 1020)٦ #pargma once٧ #endif٨٩ #ifdef NULL١٠ #undev NULL١١ #endif١٢١٣ #ifdef cplusplus١٤ extern "C"١٥ {١٦ #endif١٧١٨ /∗ C++ NULL definition ∗/ ١١٨
    • ‫٥.٦. ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﺍﻟﻘﻴﺎﺳﻴﺔ‬١٩ #define NULL 0٢٠٢١ #ifdef cplusplus٢٢ }٢٣ #else٢٤٢٥ /∗ C NULL definition ∗/٢٦ #define NULL (void∗)0٢٧٢٨ #endif٢٩٣٠ #endif //NULL H‫ﻓﺔ ﻟﺪﻳﻪ ، ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﺗﺮﲨﺔ ﺍﻟﻨﻮﺍﺓ‬ ‫ﺗﻜﻮﻥ ﻣﻌ‬ ‫ﺮ‬ cplusplus ‫ﻭﻋﻨﺪ ﺗﺮﲨﺔ ﺍﻟﻨﻮﺍﺓ ﲟﺘﺮﺟﻢ ﺳﻲ++ ﻓﺎﻥ ﺍﻟﻘﻴﻤﺔ‬ .‫ﻌ ﱢﻑ ﺗﻠﻚ ﺍﻟﻘﻴﻤﺔ‬ ‫ﲟﺘﺮﺟﻢ ﺳﻲ ﻓﺎﻥ ﺍﳌﺘﺮﺟﻢ ﻻ‬ ‫ﻳﺮ‬ size t ‫ﺗﻌﺮﻳﻒ‬ .(unsigned) ‫-23 ﺑﺪﻭﻥ ﺇﺷﺎﺭﺓ‬bit ‫ﺎ ﻋﺪﺩ ﺻﺤﻴﺢ‬‫ ﻋﻠﻰ ﺃ‬size t ‫ﻳﺘﻢ ﺗﻌﺮﻳﻒ‬ Example ٥.١٠: size t.h:Defini on of size t in C/C++١٢ #ifndef SIZE T H٣ #define SIZE T H٤٥ #ifdef cplusplus٦ extern "C"٧ {٨ #endif٩١٠ /∗ Stdandard definition of size t ∗/١١ typedef unsigned size t;١٢١٣ #ifdef cplusplus١٤ }١٥ #endif١٦١٧١٨ #endif //SIZE T H١١٩
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬ ‫ﺇﻋﺎﺩﺓ ﺗﻌﺮﻳﻒ ﺃﻧﻮﺍﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ‬‫( ﲣﺘﻠﻒ ﺣﺠﻤﻬﺎ ﲝﺴﺐ ﺍﳌﺘﺮﺟﻢ ﻭﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﰎ ﺗﺮﲨﺔ ﺍﻟﱪﻧﺎﻣﺞ ﻋﻠﻴﻪ ، ﻭﻳﻔﻀﻞ‬Data Types) ‫ﺃﻧﻮﺍﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ‬ . ‫( ﻟﺘﻮﺿﻴﺢ ﺍﳊﺠﻢ ﻭﺍﻟﻨﻮﻉ ﰲ ﺁﻥ ﻭﺍﺣﺪ‬typedef) ‫ﺃﻥ ﻳﺘﻢ ﺍﻋﺎﺩﺓ ﺗﻌﺮﻳﻔﻬﺎ‬ Example ٥.١١: stdint.h:typedef data type١٢ #ifndef STDINT H٣ #define STDINT H`٤٥ #define need wint t٦ #define need wchar t٧٨ /∗ Exact−width integer type ∗/٩ typedef char int8 t;١٠ typedef unsigned char uint8 t;١١ typedef short int16 t;١٢ typedef unsigned short uint16 t;١٣ typedef int int32 t;١٤ typedef unsigned int uint32 t;١٥ typedef long long int64 t;١٦ typedef unsigned long long uint64 t;١٧١٨١٩ // to be continue..٢٠٢١ #endif //STDINT H‫ ﻭﻫﻲ ﺍﻟﺘﺴﻤﻴﺔ ﺍﻟﱵ‬cstdint ‫ﻭﻟﺪﻋﻢ ﻣﻠﻔﺎﺕ ﺍﻟﺮﺃﺱ ﻟﻠﻐﺔ ﺳﻲ++ ﻓﺎﻥ ﺍﳌﻠﻒ ﺍﻟﺴﺎﺑﻖ ﺳﻴﺘﻢ ﺗﻀﻤﻴﻨﻪ ﰲ ﻣﻠﻒ‬ .٩ ‫ﺗﺘﺒﻌﻬﺎ ﺍﻟﺴﻲ++ ﰲ ﻣﻠﻔﺎﺕ ﺍﻟﺮﺃﺱ‬ Example ٥.١٢: cstdint:C++ typedef data type١٢ #ifndef CSTDINT H .‫٩ﻣﻠﻔﺎﺕ ﺍﻟﺮﺃﺱ ﻟﻠﻐﺔ ﺳﻲ++ ﺗﺘﺒﻊ ﻧﻔﺲ ﻫﺬﺍ ﺍﻷﺳﻠﻮﺏ ﻟﺬﻟﻚ ﻟﻦ ﻳﺘﻢ ﺫﻛﺮﻫﺎ ﳎﺪﺩﺍ ﻭﺳﻨﻜﺘﻔﻲ ﺑﺬﻛﺮ ﻣﻠﻔﺎﺕ ﺍﻟﺮﺃﺱ ﻟﻠﻐﺔ ﺳﻲ‬ ١٢٠
    • ‫٥.٦. ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﺍﻟﻘﻴﺎﺳﻴﺔ‬٣ #define CSTDINT H٤٥ #include <stdint.h>٦٧ #endif //CSTDINT H ‫ﻧﻮﻉ ﺍﳊﺮﻑ‬‫( ﻭﺍﻟﱵ ﲢﺪﺩ ﻧﻮﻉ ﺍﳊﺮﻑ )ﻋﺪﺩ،ﺣﺮﻑ،ﺣﺮﻑ ﺻﻐﲑ،ﻣﺴﺎﻓﺔ،ﺣﺮﻑ‬Macros) ‫ ﳛﻮﻱ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺎﻛﺮﻭ‬ctype.h ‫ﻣﻠﻒ‬ .(‫ﲢﻜﻢ،...ﺍﱁ‬ Example ٥.١٣: ctype.h:determine character type١٢ #ifndef CTYPE H٣ #define CTYPE H٤٥ #ifdef MSC VER٦ #pragma warning (disable:4244)٧ #endif٨٩ #ifdef cplusplus١٠ extern "C"١١ {١٢ #endif١٣١٤ extern char ctype[];١٥١٦ /∗ constants ∗/١٧١٨ #define CT UP 0x01 // upper case١٩ #define CT LOW 0x02 // lower case٢٠ #define CT DIG 0x04 // digit٢١ #define CT CTL 0x08 // control٢٢ #define CT PUN 0x10 // punctuation٢٣ #define CT WHT 0x20 // white space (space,cr,lf,tab).٢٤ #define CT HEX 0x40 // hex digit٢٥ #define CT SP 0x80 // sapce.٢٦١٢١
    • ‫٥. ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬٢٧ /∗ macros ∗/٢٨٢٩ #define isalnum(c) ( ( ctype+1)[(unsigned)(c)] & (CT UP | CT LOW | CT DIG) )٣٠ #define isalpha(c) (( ctype + 1)[(unsigned)(c)] & (CT UP | CT LOW) )٣١ #define iscntrl(c) (( ctype + 1)[(unsigned)(c)] & (CT CTL))٣٢٣٣٣٤ // to be continue..٣٥٣٦ #ifdef cplusplus٣٧ }٣٨ #endif٣٩٤٠ #endif // CTYPE H ١٢٢
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬‫ﺍﳌﻘﺎﻃﻌﺎﺕ ﻫﻲ ﻃﺮﻳﻘﺔ ﻹﻳﻘﺎﻑ ﺍﳌﻌﺎﰿ ﺑﺸﻜﻞ ﻣﺆﻗﺖ ﻣﻦ ﺗﻨﻔﻴﺬ ﻋﻤﻠﻴﺔ ﻣﺎ )‪ (Current Process‬ﻭﺍﻟﺒﺪء ﺑﺘﻨﻔﻴﺬ‬‫ﺃﻭﺍﻣﺮ ﺃﺧﺮﻯ . ﻭﻛﻤﺜﺎﻝ ﻋﻠﻰ ﺫﻟﻚ ﻫﻮ ﻋﻨﺪ ﺍﻟﻀﻐﻂ ﻋﻠﻰ ﺃﻱ ﺣﺮﻑ ﰲ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻓﺎﻥ ﻫﺬﺍ ﻳﻮﻟﺪ ﻣﻘﺎﻃﻌﺔ‬‫)‪ (Interrupt‬ﺗﺄﰐ ﻛﺈﺷﺎﺭﺓ ﺍﱃ ﺍﳌﻌﺎﰿ ﺑﺄﻥ ﻳﻮﻗﻒ ﻣﺎ ﻳﻌﻤﻞ ﻋﻠﻴﻪ ﺣﺎﻟﻴﺎ ﻭﳛﻔﻆ ﻛﻞ ﺍﻟﻘﻴﻢ ﺍﻟﱵ ﳛﺘﺎﺟﻬﺎ ﻟﻜﻲ‬‫ﻳﺴﺘﻄﻴﻊ ﻣﻮﺍﺻﻠﺔ ﻣﺎ ﰎ ﻗﻄﻌﻪ ، ﻭﰲ ﺣﺎﻟﺔ ﻭﺟﻮﺩ ﺩﺍﻟﺔ ﻟﻠﺘﻌﺎﻣﻞ ﻣﻊ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ )ﻣﻘﺎﻃﻌﺔ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ( ﻭﺗﺴﻤﻰ‬‫ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ )‪ (Interrupt Handler‬ﺃﻭ ﺩﺍﻟﺔ ﺧﺪﻣﺔ ﺍﳌﻘﺎﻃﻌﺔ )‪ (Interrupt Service Roun ne‬ﻓﺎﻥ ﺍﻟﺘﻨﻔﻴﺬ‬‫ﻳﺘﻨﻘﻞ ﺍﻟﻴﻬﺎ ﺗﻠﻘﺎﺋﻴﺎ ، ﻭ ﻳﺘﻢ ﻓﻴﻬﺎ ﻣﻌﺎﳉﺔ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ )ﻣﺜﻼ ﻳﺘﻢ ﻗﺮﺍءﺓ ﺍﳊﺮﻑ ﺍﻟﺬﻱ ﰎ ﺍﺩﺧﺎﻟﻪ ﻣﻦ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ‬‫ﺍﳌﻔﺎﺗﻴﺢ ﻭﻣﻦ ﰒ ﺍﺭﺳﺎﻟﻪ ﺍﱃ ﻣﺘﻐﲑ ﰲ ﺍﻟﺬﺍﻛﺮﺓ( ﻭﻋﻨﺪﻣﺎ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻌﻮﺩ‬‫ﻟُﻜﹾﻤ‪‬ﻞ ﺗﻨﻔﻴﺬ ﺍﻟﻌﻤﻠﻴﺔ ﺍﻟﱵ ﻛﺎﻥ ﻳﻌﻤﻞ ﻋﻠﻴﻬﺎ. ﻭﺍﳌﻘﺎﻃﻌﺎﺕ ﺇﻣﺎ ﺗﻜﻮﻥ ﻣﻘﺎﻃﻌﺎﺕ ﻋﺘﺎﺩﻳﺔ )‪(Hardware Interrupt‬‬ ‫ﻴ‬‫ﻭﺗﺼﺪﺭ ﻣﻦ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ﺃﻭ ﺗﻜﻮﻥ ﺑﺮﳎﻴﺔ )‪ (So ware Interrupt‬ﻭﺗﺼﺪﺭ ﻣﻦ ﺧﻼﻝ ﺍﻟﱪﺍﻣﺞ ﻋﻦ ﻃﺮﻳﻖ ﺗﻌﻠﻴﻤﺔ‬‫‪ .int n‬ﻛﺬﻟﻚ ﻫﻨﺎﻙ ﻣﻘﺎﻃﻌﺎﺕ ﻳﺼﺪﺭﻫﺎ ﺍﳌﻌﺎﰿ ﻧﻔﺴﻪ ﻋﻨﺪ ﺣﺪﻭﺙ ﺧﻄﺄ ﻣﺎ )ﻣﺜﻼ ﻋﻦ ﺍﻟﻘﺴﻤﺔ ﻋﻠﻰ ﺍﻟﻌﺪﺩ‬‫ﺻﻔﺮ ﺃﻭ ﻋﻨﺪ ﺣﺪﻭﺙ ‪ (Page Fault‬ﻭﺗﺴﻤﻰ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺑﺄﺧﻄﺎء ﺍﳌﻌﺎﰿ ﺃﻭ ﺍﺳﺘﺜﻨﺎﺋﺎﺕ ﺍﳌﻌﺎﰿ )‪(Excep ons‬‬ ‫ﻭﳚﺐ ﻣﻌﺎﳉﺔ ﻫﺬﻩ ﺍﻷﺧﻄﺎء )‪ (Error Handler‬ﻷ‪‬ﺎ ﺗﻮﻗﻒ ﻋﻤﻞ ﺍﻟﻨﻈﺎﻡ ﰲ ﺣﺎﻟﺔ ﱂ ﺗﺘﻮﻓﺮ ﺩﺍﻟﺔ ﳌﻌﺎﳉﺘﻬﺎ.‬ ‫‪So ware Interrupts‬‬ ‫٦.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ‬‫ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ ﻫﻲ ﻣﻘﺎﻃﻌﺎﺕ ﻳﺘﻢ ﺍﻃﻼﻗﻬﺎ ﻣﻦ ﺩﺍﺧﻞ ﺍﻟﱪﻧﺎﻣﺞ )ﻋﻦ ﻃﺮﻳﻖ ﺍﻷﻣﺮ ‪ (int n‬ﻟ‪‬ﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ‬‫ﺩﺍﻟﺔ ﺃﺧﺮﻯ ﺗﻌﺎﰿ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ )‪ ،(Interrupt handler‬ﻭﻏﺎﻟﺒﺎ ﻣﺎ ﺗﺴﺘﺨﺪﻡ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ‬‫)‪ (Ring3 user mode‬ﻟﻼﺳﺘﻔﺎﺩﺓ ﻣﻦ ﺧﺪﻣﺎﺕ ﺍﻟﻨﻈﺎﻡ )ﻣﺜﻼ ﻟﻠﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﰲ ﺃﺟﻬﺰﺓ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ‬ ‫ﺣﻴﺚ ﻻ ﺗﻮﺟﺪ ﻃﺮﻳﻘﺔ ﺍﺧﺮﻯ ﻟﺬﻟﻚ ﰲ ﳕﻂ ﺍﳌﺴﺘﺨﺪﻡ(.‬ ‫٦.١.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ‬‫ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻋﻨﺪﻣﺎ ﻳﺘﻢ ﺗﻨﻔﻴﺬ ﺃﻣﺮ ﺍﳌﻘﺎﻃﻌﺔ )ﻭﻫﻮ ﻣﺎ ﻳﺴﻤﻰ ﺑﻄﻠﺐ ﺗﻨﻔﻴﺬ ﺍﳌﻘﺎﻃﻌﺔ )‪(Interrupt Request‬‬‫ﻭﲣﺘﺼﺮ ﺑـ‪ (IRQ‬ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﻳﺄﺧﺬ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﺍﳌﻄﻠﻮﺏ ﺗﻨﻔﻴﺬﻫﺎ ﻭﻳﺬﻫﺐ ‪‬ﺎ ﺍﱃ ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ )‪Interrupt‬‬‫‪ ، (Vector Table‬ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳊﻘﻴﻘﻲ 0‪ 0x‬ﻭﻳﻨﺘﻬﻲ ﻋﻨﺪ ﺍﻟﻌﻨﻮﺍﻥ ‪ 0x3ff‬ﻭﳛﻮﻱ ﻛﻞ ﺳﺠﻞ‬‫ﻓﻴﻪ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ )‪ (IR‬ﻭﺍﻟﱵ ﳚﺐ ﺗﻨﻔﻴﺬﻫﺎ ﻟﺘﺨﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﺍﳌﻄﻠﻮﺑﺔ. ﺣﺠﻢ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ ﺃﺭﺑﻊ‬ ‫ﺑﺎﻳﺖ ﻭﺗﻜﻮﻥ ﻛﺎﻟﺘﺎﱄ:‬‫٣٢١‬
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ Interrupt Vector Table :.١.٦ ‫ﺟﺪﻭﻝ‬ Descrip on Interrupt Number Base Address Divide by 0 0 0x000 Single step (Debugger) 1 0x004 Non Maskable Interrupt (NMI) Pin 2 0x008 Breakpoint (Debugger) 3 0x00C Overflow 4 0x010 Bounds check 5 0x014 Undefined Opera on Code 6 0x018 No coprocessor 7 0x01C Double Fault 8 0x020 Coprocessor Segment Overrun 9 0x024 nvalid Task State Segment (TSS)I 10 0x028 Segment Not Present 11 0x02C Stack Segment Overrun 12 0x030 General Protec on Fault (GPF) 13 0x034 tPage Faul 14 0x038 Unassigned 15 0x03C Coprocessor error 16 0x040 Alignment Check (486+ Only) 17 0x044 Machine Check (Pen um/586+ Only) 18 0x048 Reserved excep ons 19-31 0x05C Interrupts free for so ware use 32-255 0x068 - 0x3FF • Byte 0: Low offset address of IR. • Byte 1: High offset address of IR. • Byte 2: Low Segment address of IR. • Byte 3: High Segment Address of IR.‫ﻭﻳﺘﻜﻮﻥ ﺍﳉﺪﻭﻝ ﻣﻦ 652 ﻣﻘﺎﻃﻌﺔ )ﻭﲝﺴﺒﺔ ﺑﺴﻴﻄﺔ ﻳﻜﻮﻥ ﺣﺠﻢ ﺍﳉﺪﻭﻝ ﻫﻮ 4201 ﺑﺎﻳﺖ ﻭﻫﻲ ﻧﺎﲡﺔ ﻣﻦ‬‫ﺿﺮﺏ ﻋﺪﺩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺣﺠﻢ ﻛﻞ ﺳﺠﻞ (، ﺑﻌﺾ ﻣﻨﻬﺎ ﳏﺠﻮﺯ ﻭﺍﻟﺒﻌﺾ ﺍﻻﺧﺮ ﻳﺴﺘﺨﺪﻣﻪ ﺍﳌﻌﺎﰿ ﻭﺍﻟﺒﻘﻴﺔ‬‫ﻣﺘﺮﻭﻛﺔ ﳌﱪﻣﺞ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻟﺪﻋﻢ ﺍﳌﺰﻳﺪ ﻣﻦ ﺍﳌﻘﻄﺎﻋﺎﺕ. ﻭﺑﺴﺒﺐ ﺃﻥ ﺍﳉﺪﻭﻝ ﻳﺘﻜﻮﻥ ﻓﻘﻂ ﻣﻦ ﻋﻨﺎﻭﻳﻦ ﻟﺪﻭﺍﻝ‬‫ﺎ ﺩﺍﺧﻞ ﻫﺬﺍ‬‫ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻓﺎﻥ ﻫﺬﺍ ﳝﻜﻨﻨﺎ ﻣﻦ ﻭﺿﻊ ﺍﻟﺪﺍﻟﺔ ﰲ ﺃﻱ ﻣﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻣﻦ ﰒ ﻭﺿﻊ ﻋﻨﻮﺍ‬ .‫ ﻭﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﳌﻮﺟﻮﺩﺓ ﻓﻴﻪ‬IVT ‫ﺍﻟﺴﺠﻞ )ﻳﺘﻢ ﻫﺬﺍ ﻋﻦ ﻃﺮﻳﻖ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ(، ﻭﺍﳉﺪﻭﻝ ٦.١ ﻳﻮﺿﺢ‬ ١٢٤
    • So ware Interrupts ‫٦.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ‬ ‫٦.١.٢. ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ‬Interrupt Descriptor) ‫ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻳﺴﺘﺨﺪﻡ ﺍﳌﻌﺎﰿ ﺟﺪﻭﻻً ﺧﺎﺻﴼ ﻳﺴﻤﻰ ﲜﺪﻭﻝ ﻭﺍﺻﻔﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ‬‫ ﺣﻴﺚ ﻳﺘﻜﻮﻥ ﻣﻦ 652 ﻭﺍﺻﻔﺔ ﻛﻞ ﻭﺍﺻﻔﺔ ﳐﺼﺼﺔ‬IVT ‫ ، ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﺸﺎﺑﻪ ﺟﺪﻭﻝ‬IDT ‫( ﻭﳜﺘﺼﺮ ﺏ‬Table‫ﳌﻘﺎﻃﻌﺔ ﻣﺎ )ﺍﺫﴽ ﺍﳉﺪﻭﻝ ﳛﻮﻱ 652 ﻣﻘﺎﻃﻌﺔ( ، ﺣﺠﻢ ﻛﻞ ﻭﺍﺻﻔﺔ ﻫﻮ 8 ﺑﺎﻳﺖ ﲢﻮﻱ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ‬‫ ﺍﻟﺬﻱ ﺗﻌﻤﻞ ﻋﻠﻴﻪ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ‬GDT ‫( ﰲ ﺟﺪﻭﻝ‬selector type: code or data) ‫( ﻭ ﻧﻮﻉ ﺍﻟﻨﺎﺧﺐ‬IR) .‫، ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ﺍﳌﻄﻠﻮﺏ ﻭﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﺗﻮﺿﺤﻬﺎ ﺍﻟﺘﺮﻛﻴﺒﺔ ﺍﻟﺘﺎﻟﻴﺔ‬ • Bits 0-15: – Interrupt / Trap Gate: Offset address Bits 0-15 of IR – Task Gate: Not used. • Bits 16-31: – Interrupt / Trap Gate: Segment Selector (Useually 0x10) – Task Gate: TSS Selector • Bits 31-35: Not used • Bits 36-38: – Interrupt / Trap Gate: Reserved. Must be 0. – Task Gate: Not used. • Bits 39-41: – Interrupt Gate: Of the format 0D110, where D determins size ∗ 01110 - 32 bit descriptor ∗ 00110 - 16 bit descriptor – Task Gate: Must be 00101 – Trap Gate: Of the format 0D111, where D determins size ∗ 01111 - 32 bit descriptor ∗ 00111 - 16 bit descriptor • Bits 42-44: Descriptor Privedlge Level (DPL) – 00: Ring 0 – 01: Ring 1 – 10: Ring 2 – 11: Ring 3١٢٥
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫)‪• Bit 45: Segment is present (1: Present, 0:Not present‬‬ ‫:26-64 ‪• Bits‬‬ ‫‪– Interrupt / Trap Gate: Bits 16-31 of IR address‬‬ ‫‪– Task Gate: Not used‬‬‫ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻧﺸﺎء ﻭﺍﺻﻔﺔ ﻭﺍﺣﺪﺓ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺣﱴ ﻳﺴﻬﻞ ﺗﺘﺒﻊ ﺍﻟﻘﻴﻢ ، ﻭﺳﻴﺘﻢ ﻛﺘﺎﺑﺔ ﻣﺜﺎﻝ ﻛﺎﻣﻞ‬ ‫ﻻﺣﻘﺎ ﺑﻠﻐﺔ ﺍﻟﺴﻲ.‬‫‪Example‬‬ ‫‪٦.١: Example of interrupt descriptor‬‬‫١‬‫:‪٢ idt descriptor‬‬‫٣‬ ‫‪baseLow‬‬ ‫‪dw‬‬ ‫0‪0x‬‬‫٤‬ ‫‪selector‬‬ ‫‪dw‬‬ ‫8‪0x‬‬‫٥‬ ‫‪reserved‬‬ ‫‪db‬‬ ‫0‪0x‬‬‫٦‬ ‫‪flags‬‬ ‫‪db‬‬ ‫‪0x8e‬‬ ‫011100010 ;‬‫٧‬ ‫‪baseHi‬‬ ‫‪dw‬‬ ‫0‪0x‬‬‫ﺍﳌﺘﻐﲑ ﺍﻷﻭﻝ ‪ baseLow‬ﻫﻮ ﺃﻭﻝ 61 ﺑﺖ ﻣﻦ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ ‪ IR‬ﻭﻳﻜﻤﻞ ﺍﳉﺰء ﺍﻻﺧﺮ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ‬‫ﺍﳌﺘﻐﲑ ‪ baseHi‬ﻭﰲ ﻫﺬﺍ ﺍﳌﺜﺎﻝ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ 0‪ 0x‬ﲟﻌﲎ ﺃﻥ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﺳﺘﻜﻮﻥ ﰲ ﺍﻟﻌﻨﻮﺍﻥ 0‪ .0x‬ﻭﲟﺎ ﺃﻥ‬‫ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ )ﲣﺪﱘ( ﺍﳌﻘﺎﻃﻌﺔ ﲢﻮﻱ ﺷﻔﺮﺓ ﺑﺮﳎﻴﺔ ﻟﻠﺘﻨﻔﻴﺬ ﻭﻟﻴﺴﺖ ﺑﻴﺎﻧﺎﺕ )‪ (Data‬ﻓﺎﻥ ﻗﻴﻤﺔ ﺍﳌﺘﻐﲑ ‪selector‬‬‫ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ 8‪ 0x‬ﻟﻺﺷﺎﺭﺓ ﺍﱃ ﻧﺎﺧﺐ ﺍﻟﺸﻔﺮﺓ )‪ (Code Selector‬ﰲ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ )‪ .(GDT‬ﺃﻣﺎ‬‫ﺍﳌﺘﻐﲑ ‪ flags‬ﻓﺎﻥ ﻗﻴﻤﺘﻪ ﻫﻲ ‪ 010001110b‬ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﺍﻟﻮﺍﺻﻔﺔ ﻫﻲ ‪ 32-bit‬ﻭﺃﻥ ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ‬ ‫ﻫﻮ ﺍﳊﻠﻘﺔ ﺻﻔﺮ )0‪.(Ring‬‬‫ﻭﺑﻌﺪ ﺃﻥ ﻳﺘﻢ ﺍﻧﺸﺎء ﺃﻏﻠﺐ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺑﺸﻜﻞ ﻣﺘﺴﻠﺴﻞ )ﰲ ﺃﻱ ﻣﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ( ، ﳚﺐ ﺃﻥ ﻧﻨﺸﺊ ﺟﺪﻭﻝ‬‫‪ IDT‬ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺣﻔﻆ ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻭﺍﺻﻔﺔ ﰲ ﻣﺘﻐﲑ ﻭﻟﻴﻜﻦ ‪ idt start‬ﻭﻋﻨﻮﺍﻥ ‪‬ﺎﻳﺔ ﺍﻟﻮﺍﺻﻔﺎﺕ‬‫ﰲ ﺍﳌﺘﻐﲑ ‪ idt end‬ﻭﻣﻦ ﰒ ﺍﻧﺸﺎء ﻣﺆﺷﺮﴽ ﻳﺴﻤﻰ ‪ idt ptr‬ﻭﺍﻟﺬﻱ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﰲ ﺻﻮﺭﺓ ﻣﻌﻴﻨﺔ ﲝﻴﺚ‬ ‫ﳛﻔﻆ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳉﺪﻭﻝ ﻭ‪‬ﺎﻳﺘﻪ :‬‫‪Example‬‬ ‫‪٦.٢: Value to put in IDTR‬‬‫:‪١ idt ptr‬‬‫٢‬ ‫‪limit dw idt end − idt start ; bits 0−15 is size of idt‬‬‫٣‬ ‫‪base dd idt start‬‬ ‫‪; base of idt‬‬‫ﻫﺬﺍ ﺍﳌﺆﺷﺮ ﳚﺐ ﺃﻥ ﻳﺘﻢ ﲢﻤﻴﻠﻪ ﺍﱃ ﺍﳌﺴﺠﻞ ‪) IDTR‬ﻭﻫﻮ ﻣﺴﺠﻞ ﺩﺍﺧﻞ ﺍﳌﻌﺎﰿ( ﻋﻦ ﻃﺮﻳﻖ ﺗﻨﻔﻴﺬ ﺍﻻﻣﺮ ‪١ lidt‬‬ ‫‪.lidt‬‬ ‫]‪[idt ptr‬‬ ‫ﺑﺎﻟﺸﻜﻞ ﺍﻟﺘﺎﱄ‬ ‫١ﺑﻌﺪ ﺗﻨﻔﻴﺬ ﻫﺬﺍ ﺍﻷﻣﺮ ﻓﺎﻥ ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺳﻴﺘﻢ ﺍﺳﺘﺒﺪﺍﻟﻪ ﺑﺎﳉﺪﻭﻝ ﺍﳉﺪﻳﺪ ﻭﺍﻟﺬﻱ ﳒﺪ ﻋﻨﻮﺍﻧﻪ ﺑﺪﺍﺧﻞ ﺍﳌﺴﺠﻞ ‪ ، idtr‬ﻭﻫﺬﺍ‬ ‫ﺍﻷﻣﺮ ﻻ ‪‬ﻨ ﱠﺬ ﺇ ﱠ ﺍﺫﺍ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﺍﻟﻌﻠﻢ )‪ (CPL flag‬ﻫﻲ ﺻﻔﺮ.‬ ‫ﻳﻔ ﻻ‬ ‫٦٢١‬
    • ‫‪So ware Interrupts‬‬ ‫٦.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ‬‫ﻭﻋﻨﺪ ﺣﺪﻭﺙ ﺃﻱ ﻣﻘﺎﻃﻌﺔ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻨﻬﻲ ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﻳﻌﻤﻞ ﻋﻠﻴﻪ ﻭ ﻳﺄﺧﺬ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻳﺬﻫﺐ ﺑﻪ ﺍﱃ ﺟﺪﻭﻝ‬‫‪) IDT‬ﻋﻨﻮﺍﻥ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﺘﻮﺍﺟﺪ ﺑﺪﺍﺧﻞ ﺍﳌﺴﺠﻞ ‪ ، (IDTR‬ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﻘﻮﻡ ﲝﺴﺎﺏ ﻣﻜﺎﻥ ﺍﻟﻮﺍﺻﻔﺔ ﺑﺎﳌﻌﺎﺩﻟﺔ‬‫8 * ‪ int num‬ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺣﺠﻢ ﻛﻞ ﻭﺍﺻﻔﺔ ﰲ ﺟﺪﻭﻝ ‪ IDT‬ﻫﻮ 8 ﺑﺎﻳﺖ. ﻭﻗﺒﻞ ﺃﻥ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ‬‫ﺍﱃ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﻳﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ ﺣﻔﻆ ﻟﻠﻤﻜﺎﻥ ﺍﻟﺬﻱ ﺗﻮﻗﻒ ﻓﻴﻪ ﺣﱴ ﻳﺴﺘﻄﻴﻊ ﺃﻥ ﻳﺘﺎﺑﻊ ﻋﻤﻠﻪ‬‫ﻋﻨﺪﻣﺎ ﺗﻌﻮﺩ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ . ﻭﻳﺘﻢ ﺣﻔﻆ ﺍﻷﻋﻼﻡ ‪ EFLAGS‬ﻭﻣﺴﺠﻞ ﻣﻘﻄﻊ ﺍﻟﺸﻔﺮﺓ ‪ CS‬ﻭﻣﺴﺠﻞ ﻋﻨﻮﺍﻥ‬‫ﺍﻟﺘﻌﻠﻴﻤﺔ ﺍﻟﺘﺎﻟﻴﺔ ‪ IP‬ﰲ ﺍﳌﻜﺪﺱ )‪ (Stack‬ﺍﳊﺎﱄ ، ﻭﰲ ﺣﺎﻟﺔ ﺣﺪﻭﺙ ﺧﻄﺄ ﻣﺎ ﻓﺎﻧﻪ ﻳﺘﻢ ﺩﻓﻊ ﺷﻔﺮﺓ ﺍﳋﻄﺄ )‪Error‬‬ ‫‪ (Code‬ﺍﱃ ﺍﳌﻜﺪﺱ ﺃﻳﻀﺎ. ﻭﺷﻔﺮﺓ ﺍﳋﻄﺄ ﻫﻲ ﺑﻄﻮﻝ ‪ 32-bit‬ﻭﺗﺘﺒﻊ ﺍﻟﺘﺮﻛﻴﺒﺔ ﺍﻟﺘﺎﻟﻴﺔ.‬ ‫‪• Bit 0: External event‬‬ ‫.‪– 0: Internal or so ware event triggered the error‬‬ ‫.‪– 1: External or hardware event triggered the error‬‬ ‫‪• Bit 1: Descrip on loca on‬‬ ‫.‪– 0: Index por on of error code refers to descriptor in GDT or current LDT‬‬ ‫.‪– 1: Index por on of error code refers to gate descriptor in IDT‬‬ ‫.0 ‪• Bit 2: GDT/LDT. Only use if the descriptor loca on is‬‬ ‫.‪– 0: This indicates the index por on of the error code refers to a descriptor in the current GDT‬‬ ‫‪– 1: This indicates the index por on of the error code refers to a segment or gate descriptor in‬‬ ‫.‪the LDT‬‬ ‫‪• Bits 3-15: Segment selector index. This is an index into the IDT, GDT, or current LDT to the segment‬‬ ‫.‪or gate selector bring refrenced by the error code‬‬ ‫.‪• Bits 16-31: Reserved‬‬‫ﻭﻋﻨﺪﻣﺎ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﺗﻨﻔﺬ ﺍﻷﻣﺮ ‪ iret‬ﺃﻭ ‪ iretd‬ﺣﱴ ﻳﺘﻢ ﺍﺭﺟﺎﻉ‬ ‫ﺍﻟﻘﻴﻢ ﺍﻟﱵ ﰎ ﺩﻓﻌﻬﺎ ﺍﱃ ﺍﳌﻜﺪﺱ )ﻗﻴﻢ ﺍﻷﻋﻼﻡ ‪ .(FLAGS‬ﻭﺑﺎﻟﺘﺎﱄ ‪‬ﻳﻜﹾﻤ‪‬ﻞ ﺍﳌﻌﺎﰿ ﻋﻤﻠﻪ.‬ ‫٦.١.٣. ﺃﺧﻄﺎء ﺍﳌﻌﺎﰿ‬‫ﺧﻼﻝ ﺗﻨﻔﻴﺬ ﺍﳌﻌﺎﰿ ﻟﻸﻭﺍﻣﺮ ﻓﺎﻧﻪ ﺭﲟﺎ ﳛﺪﺙ ﺧﻄﺄ ﻣﺎ ﳑﺎ ﳚﻌﻞ ﺍﳌﻌﺎﰿ ﻳﻘﻮﻡ ﺑﺘﻮﻟﻴﺪ ﺍﺳﺘﺜﻨﺎء ﻳﻌﺮﻑ ﺑﺎﺳﺘﺜﻨﺎء ﺍﳌﻌﺎﰿ‬ ‫، ﻭﻳﻮﺟﺪ ﻟﻪ ﻋﺪﺓ ﺃﻧﻮﺍﻉ:‬‫ﺍﳋﻄﺄ ‪ :Fault‬ﻋﻨﺪﻣﺎ ﺗﻌﻤﻞ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﻫﺬﺍ ﺍﻟﻨﻮﻉ ﻣﻦ ﺍﻻﺳﺘﺜﻨﺎء ﻓﺮﲟﺎ ﻳﺘﻢ ﺍﺻﻼﺡ ﻫﺬﺍ ﺍﳋﻄﺄ ، ﻭﻋﻨﻮﺍﻥ‬ ‫•‬ ‫ﺍﻟﻌﻮﺩﺓ ﺍﻟﺬﻱ ﻳﺘﻢ ﺩﻓﻌﻪ ﺍﱃ ﺍﳌﻜﺪﺱ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﺗﺴﺒﺐ ﰲ ﻫﺬﺍ ﺍﳋﻄﺄ.‬ ‫ﺍﳋﻄﺄ ‪ :Trap‬ﻋﻨﻮﺍﻥ ﺍﻟﻌﻮﺩﺓ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻟﺘﻌﻠﻴﻤﺔ ﺍﻟﱵ ﺗﻠﻲ ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﺗﺴﺒﺐ ﰲ ﺍﳋﻄﺄ.‬ ‫•‬‫٧٢١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫ﺟﺪﻭﻝ ٦.٢.: ‪x86 Processor Excep ons Table‬‬ ‫‪Descrip on‬‬ ‫‪Class‬‬ ‫‪Interrupt Number‬‬ ‫0 ‪Divide by‬‬ ‫‪Fault‬‬ ‫0‬ ‫‪Single step‬‬ ‫1 ‪Trap/Fault‬‬ ‫2 ‪Non Maskable Interrupt (NMI) Pin Unclassed‬‬ ‫‪Breakpoint‬‬ ‫‪Trap‬‬ ‫3‬ ‫‪Overflow‬‬ ‫‪Trap‬‬ ‫4‬ ‫‪Bounds check‬‬ ‫‪Fault‬‬ ‫5‬ ‫‪Unvalid OPCode‬‬ ‫‪Fault‬‬ ‫6‬ ‫‪Device not available‬‬ ‫‪Fault‬‬ ‫7‬ ‫‪Double Fault‬‬ ‫‪Abort‬‬ ‫8‬ ‫‪Coprocessor Segment Overrun‬‬ ‫‪Abort‬‬ ‫9‬ ‫‪Invalid Task State Segment‬‬ ‫‪Fault‬‬ ‫01‬ ‫‪Segment Not Present‬‬ ‫‪Fault‬‬ ‫11‬ ‫‪Stack Fault Excep on‬‬ ‫‪Fault‬‬ ‫21‬ ‫‪General Protec on Fault‬‬ ‫‪Fault‬‬ ‫31‬ ‫‪Page Fault‬‬ ‫‪Fault‬‬ ‫41‬ ‫‪Unassigned‬‬ ‫-‬ ‫51‬ ‫‪x87 FPU Error‬‬ ‫‪Fault‬‬ ‫61‬ ‫‪Alignment Check‬‬ ‫‪Fault‬‬ ‫71‬ ‫‪Machine Check‬‬ ‫‪Abort‬‬ ‫81‬ ‫‪SIMD FPU Excep on‬‬ ‫‪Fault‬‬ ‫91‬ ‫‪Reserved‬‬ ‫-‬ ‫13-02‬ ‫‪Avilable for so ware use‬‬ ‫-‬ ‫552-23‬ ‫ﺍﳋﻄﺄ ‪ :Abort‬ﻻ ﻳﻮﺟﺪ ﻋﻨﻮﺍﻥ ﻟﻠﻌﻮﺩﺓ ، ﻭﻟﻦ ﻳﻜﻤﻞ ﺍﻟﱪﻧﺎﻣﺞ ﻋﻤﻠﻪ ﺑﻌﺪ ﺍﻧﺘﻬﺎء ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳋﻄﺄ.‬ ‫•‬ ‫ﻭﺍﳉﺪﻭﻝ ٦.٢ ﻳﻮﺿﺢ ﺃﺧﻄﺎء ﺍﳌﻌﺎﰿ ﻭﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﻘﻮﻡ ﺑﺘﻮﻟﻴﺪﻫﺎ.‬‫ﻭﳚﺪﺭ ﺑﻨﺎ ﺍﻟﻮﻗﻮﻑ ﻋﻠﻰ ﻣﻼﺣﻈﺔ ﻛّﺎ ﻗﺪ ﺫﻛﺮﻧﺎﻫﺎ ﰲ ﺍﻟﻔﺼﻮﻝ ﺍﻟﺴﺎﺑﻘﺔ ﻭﻫﻲ ﺇﻟﻐﺎء ﺍﳌﻘﺎﻃﻌﺎﺕ )ﺑﻮﺍﺳﻄﺔ ﺍﻷﻣﺮ‬ ‫ﻨ‬‫‪ (cli‬ﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺣﱴ ﻻ ﻳﺘﺴﺒﺐ ﰲ ﺣﺪﻭﺙ ﺧﻄﺄ ‪ General Protec on Fault‬ﻭﺑﺎﻟﺘﺎﱄ‬‫ﺗﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ ﻭﺳﺒﺐ ﺫﻟﻚ ﻫﻮ ﺃﻥ ﻋﺪﻡ ﺗﻨﻔﻴﺬ ﺍﻷﻣﺮ ‪ cli‬ﻳﻌﲏ ﺃﻥ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﻣﻔﻌﻠﺔ ﻭﺑﺎﻟﺘﺎﱄ‬‫ﺃﻱ ﻋﺘﺎﺩ ﳝﻜﻨﻪ ﺃﻥ ﻳﺮﺳﻞ ﻣﻘﺎﻃﻌﺔ ﺍﱃ ﺍﳌﻌﺎﰿ ﻟﻜﻲ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺩﺍﻟﺔ ﲣﺪﳝﻬﺎ . ﻭﻋﻨﺪ ﺑﺪﺍﻳﺔ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ‬‫ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﺎﻥ ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ‪ IDT‬ﱂ ﻳﺘﻢ ﺍﻧﺸﺎﺋﻪ ﻭﺃﻱ ﳏﺎﻭﻟﺔ ﻻﺳﺘﺨﺪﺍﻣﻪ ﺳﻴﺆﺩﻱ ﺍﱃ ﻫﺬﺍ ﺍﳋﻄﺄ.‬‫ﺃﺣﺪ ﺍﳌﺘﺤﻜﻤﺎﺕ ﺍﻟﱵ ﺗﺮﺳﻞ ﻣﻘﺎﻃﻌﺎﺕ ﺍﱃ ﺍﳌﻌﺎﰿ ﺑﺸﻜﻞ ﺛﺎﺑﺖ ﻫﻮ ﻣﺘﺤﻜﻢ ‪Prpgrammable Interval Timer‬‬‫ﻭﲣﺘﺼﺮ ﲟﺘﺤﻜﻢ ‪ PIT‬ﻭﻫﻲ ﲤﺜﻞ ﺳﺎﻋﺔ ﺍﻟﻨﻈﺎﻡ ‪ System Timer‬ﲝﻴﺚ ﺗﺮﺳﻞ ﻣﻘﺎﻃﻌﺔ ﺑﺸﻜﻞ ﺩﺍﺋﻢ ﺍﱃ ﺍﳌﻌﺎﰿ‬‫ﻭﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺩﺍﻟﺔ ﲣﺪﱘ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ . ﻭﺑﺴﺒﺐ ﺃﻥ ﺟﺪﻭﻝ ﺍﳌﻘﻄﺎﻋﺎﺕ ﻏﲑ ﻣﺘﻮﺍﺟﺪ ﰲ ﺑﺪﺍﻳﺔ‬‫ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻭﻛﺬﻟﻚ ﻻ ﺗﻮﺟﺪ ﺩﺍﻟﺔ ﻟﺘﺨﺪﱘ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ ﻓﺎﻥ ﻫﺬﺍ ﻳﺆﺩﻱ ﺍﱃ ﺗﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ،‬ ‫٨٢١‬
    • ‫‪So ware Interrupts‬‬ ‫٦.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ‬‫ﻟﺬﻟﻚ ﳚﺐ ﺍﻳﻘﺎﻑ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﳊﲔ ﺍﻧﺸﺎء ﺟﺪﻭﻝ ﺍﳌﻘﻄﺎﻋﺎﺕ ﻭﻛﺘﺎﺑﺔ ﺩﻭﺍﻝ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ. ﻛﺬﻟﻚ‬‫ﺗﻮﺟﺪ ﻣﺸﻜﻠﺔ ﺃﺧﺮﻯ ﻟﺒﻌﺾ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﺣﻴﺚ ﺍ‪‬ﺎ ﺗﺴﺘﺨﺪﻡ ﻧﻔﺲ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ‬‫ﺍﳌﻌﺎﰿ ﻟﻺﺳﺘﺜﻨﺎءﺍﺕ ﻭﺣﻠﻬﺎ ﻫﻮ ﺑﺈﻋﺎﺩﺓ ﺑﺮﳎﺔ ﺍﻟﺸﺮﳛﺔ ﺍﳌﺴﺆﻭﻟﺔ ﻋﻦ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻻﺷﺎﺭﺍﺕ ﻣﻦ ﺍﻟﻌﺘﺎﺩ ﻭﲢﻮﻳﻠﻬﺎ ﺍﱃ‬‫ﻣﻘﺎﻃﻌﺎﺕ ﻭﺍﺭﺳﺎﳍﺎ ﺍﱃ ﺍﳌﻌﺎﰿ ، ﻫﺬﻩ ﺍﻟﺸﺮﳛﺔ ﺗﺴﻤﻰ ‪ Programmable Interrupt Controller‬ﻭﲣﺘﺼﺮ ﺏ ‪PIC‬‬ ‫ﻭﳚﺐ ﺇﻋﺎﺩﺓ ﺑﺮﳎﺘﻬﺎ ﻭﺗﻐﻴﲑ ﺍﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻟﻸﺟﻬﺰﺓ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﺃﺭﻗﺎﻣﴼ ﻣﺘﺸﺎ‪‬ﺔ.‬‫ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺳﻴﺘﻢ ﺇﻧﺸﺎء ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ )‪ (IDT‬ﺑﺎﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺴﻲ ﻭﺗﻮﻓﲑ ﺍﻝ 652 ﺩﺍﻟﺔ ﳌﻌﺎﳉﺔ ﺍﳌﻘﻄﺎﻋﺎﺕ‬‫ﻭﺣﺎﻟﻴﺎ ﺳﻴﻘﺘﺼﺮ ﻋﻤﻞ ﺍﻟﺪﻭﺍﻝ ﻋﻠﻰ ﻃﺒﺎﻋﺔ ﺭﺳﺎﻟﺔ ، ﻭﻗﺒﻞ ﺫﻟﻚ ﺳﻨﻘﻮﻡ ﺑﺎﻧﺸﺎء ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ )‪(GDT‬‬‫ﳎﺪﺩﺍ )ﺃﻱ ﺳﻴﺘﻢ ﺍﻟﻐﺎء ﺍﳉﺪﻭﻝ ﺍﻟﺬﻱ ﻗﻤﻨﺎ ﺑﺎﻧﺸﺎﺋﻪ ﰲ ﻣﺮﺣﻠﺔ ﺍﻻﻗﻼﻉ( ﻭﺑﻌﺪ ﺫﻟﻚ ﺳﻨﺒﺪﺃ ﰲ ﺑﺮﳎﺔ ﻣﺘﺤﻜﻢ ‪PIC‬‬ ‫ﻭﺍﻋﺎﺩﺓ ﺗﺮﻗﻴﻢ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻷﺟﻬﺰﺓ ﻭﻛﺬﻟﻚ ﺑﺮﳎﺔ ﺳﺎﻋﺔ ﺍﻟﻨﻈﺎﻡ ﻻﺭﺳﺎﻝ ﻣﻘﺎﻃﻌﺔ ﺑﻮﻗﺖ ﳏﺪﺩ.‬ ‫‪GDT‬‬ ‫٦.١.٤. ﺇﻧﺸﺎء ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ‬‫ﺍﳍﺪﻑ ﺍﻟﺮﺋﻴﺴﻲ ﰲ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻫﻲ ﺍﳌﺤﻤﻮﻟﻴﺔ ﻋﻠﻰ ﺻﻌﻴﺪ ﺍﳌﻨﺼﺎﺕ ، ﻭﻫﺬﺍ ﻣﺎ ﺃﺩﻯ ﺍﱃ ﺍﻋﺘﻤﺎﺩ ﻓﻜﺮﺓ‬‫ﻃﺒﻘﺔ ‪ HAL‬ﻭﺍﻟﱵ ﻳﻘﺒﻊ ﲢﺘﻬﺎ ﻛﻞ ﻣﺎ ﻳﺘﻌﻠﻖ ﺑﻌﺘﺎﺩ ﺍﳊﺎﺳﺐ ﻭﺍﺩﺍﺭﺗﻪ ﻭﻛﻞ ﻣﺎ ﳚﻌﻞ ﺍﻟﻨﻈﺎﻡ ﻣﻌﺘﻤﺪﴽ ﻋﻠﻰ ﻣﻌﻤﺎﺭﻳﺔ‬‫ﻣﻌﻴﻨﺔ ﺃﻳﻀﺎ ﳒﺪﻩ ﲢﺖ ﻃﺒﻘﺔ ‪ ، HAL‬ﻭﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ - ﻛﻤﺎ ﺫﻛﺮﻧﺎ ﰲ ﺍﻟﻔﺼﻮﻝ ﺍﻟﺴﺎﺑﻘﺔ- ﳛﺪﺩ ﻭﻳﻘﺴﻢ‬‫ﻟﻨﺎ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻛﺄﺟﺰﺍء ﻗﺎﺑﻠﺔ ﻟﻠﺘﻨﻔﻴﺬ ﻭﺃﺟﺰﺍء ﲢﻮﻱ ﺑﻴﺎﻧﺎﺕ ﻭﻏﲑﻫﺎ ، ﻭﻧﻈﺮﴽ ﻷﻥ ﺇﻧﺸﺎء ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﻌﺘﻤﺪ‬‫ﻋﻠﻰ ﻣﻌﻤﺎﺭﻳﺔ ﺍﳌﻌﺎﰿ ﻭﺍﻷﻭﺍﻣﺮ ﺍﳌﺪﻋﻮﻣﺔ ﻓﻴﻪ ﻓﺎﻧﻪ ﳚﺐ ﺍﻥ ﻳﻘﻊ ﲢﺖ ﻃﺒﻘﺔ ‪ ٢ HAL‬ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻥ ﻧﻘﻞ ﺍﻟﻨﻈﺎﻡ ﺍﱃ‬ ‫ﻣﻌﻤﺎﺭﻳﺔ ﺣﺎﺳﻮﺏ ﺁﺧﺮ ﻳﺘﻄﻠﺐ ﻓﻘﻂ ﺇﻋﺎﺩﺓ ﺑﺮﳎﺔ ﻃﺒﻘﺔ ‪. HAL‬‬‫ﺑﺪﺍﻳﺔ ﺳﻨﺒﺪﺃ ﺑﺘﺼﻤﻴﻢ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﻌﺎﻣﺔ ﻟﻄﺒﻘﺔ ‪ HAL‬ﻭﳚﺐ ﺃﻥ ﻧﺮﺍﻋﻲ ﺃﻥ ﺗﻜﻮﻥ ﺍﻟﻮﺍﺟﻬﺔ ﻣﻔﺼﻮﻟﺔ ﲤﺎﻣﺎ ﻋﻦ ﺍﻟﺘﻄﺒﻴﻖ‬ ‫ﺣﱴ ﻳﺘﻤﻜﻦ ﺃﻱ ﻣﻄﻮﺭ ﻣﻦ ﺇﻋﺎﺩﺓ ﺗﻄﺒﻴﻘﻬﺎ ﻻﺣﻘّ ﻋﻠﻰ ﻣﻌﻤﺎﺭﻳﺔ ﺣﺎﺳﻮﺏ ﺁﺧﺮ.‬ ‫ﺎ‬ ‫‪Example‬‬ ‫‪٦.٣: include/hal.h:Hardware Abstrac‬‬ ‫‪on Layer Interface‬‬‫١‬‫‪٢ #ifndef HAL H‬‬‫‪٣ #define HAL H‬‬‫٤‬‫683‪٥ #ifndef i‬‬‫"‪٦ #error "HAL is not implemented in this platform‬‬‫‪٧ #endif‬‬‫٨‬‫‪٩ #include‬‬ ‫>‪<stdint.h‬‬‫٠١‬‫‪١١ #ifdef‬‬ ‫‪MSC VER‬‬‫‪١٢ #define interrupt‬‬ ‫)‪declspec(naked‬‬‫‪١٣ #else‬‬ ‫٢ﻣﻦ ﻣﻨﻈﻮﺭ ﺁﺧﺮ ﻫﺬﻩ ﺍﳉﺪﺍﻭﻝ )‪ (GDT,LDT and IDT‬ﻫﻲ ﺟﺪﺍﻭﻝ ﻟﻠﻤﻌﺎﰿ ﻟﺬﻟﻚ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﰲ ﻃﺒﻘﺔ ‪.HAL‬‬‫٩٢١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬‫‪١٤ #define interrupt‬‬‫‪١٥ #endif‬‬‫٦١‬‫‪١٧ #define far‬‬‫‪١٨ #define near‬‬‫٩١‬‫٠٢‬‫∗/ ١٢‬ ‫/∗ ‪Interface‬‬‫٢٢‬‫‪٢٣ extern int‬‬ ‫;)(‪cdecl hal init‬‬‫‪٢٤ extern int‬‬ ‫;)(‪cdecl hal close‬‬‫;)‪٢٥ extern void cdecl gen interrupt(int‬‬‫٦٢‬‫٧٢‬‫‪٢٨ #endif // HAL H‬‬‫ﻭﺣﺎﻟﻴﴼ ﻭﺍﺟﻬﺔ ﻃﺒﻘﺔ ‪ HAL‬ﻣﻜﻮﻧﺔ ﻣﻦ ﺛﻼﺙ ﺩﻭﺍﻝ ﰎ ﺍﻹﻋﻼﻥ ﻋﻨﻬﺎ ﺑﺄ‪‬ﺎ ‪ extern‬ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻥ ﺃﻱ ﺗﻄﺒﻴﻖ‬‫)‪ (Implementa on‬ﳍﺬﻩ ﺍﻟﻮﺍﺟﻬﺔ ﳚﺐ ﺃﻥ ‪‬ﻌ ﱢﻑ ﻫﺬﻩ ﺍﻟﺪﻭﺍﻝ. ﺍﻟﺪﺍﻟﺔ ﺍﻻﻭﱃ ﻫﻲ )(‪ hal init‬ﻭﺍﻟﱵ ﺗﻘﻮﻡ‬ ‫ﻳﺮ‬‫ﺑﺘﻬﻴﺌﺔ ﺍﻟﻌﺘﺎﺩ ﻭﺟﺪﺍﻭﻝ ﺍﳌﻌﺎﰿ ﺑﻴﻨﻤﺎ ﺍﻟﺪﺍﻟﺔ ﺍﻟﺜﺎﻧﻴﺔ )(‪ hal close‬ﺗﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ ﺍﳊﺬﻑ ﻭﺍﻟﺘﺤﺮﻳﺮ ﻭﺃﺧﲑﺍ ﺍﻟﺪﺍﻟﺔ‬‫‪ gen interrupt‬ﻭﺍﻟﱵ ﰎ ﻭﺿﻌﻬﺎ ﻟﻐﺮﺽ ﲡﺮﺑﺔ ﺇﺭﺳﺎﻝ ﻣﻘﺎﻃﻌﺔ ﺑﺮﳎﻴﺔ ﻭﺍﻟﺘﺄﻛﺪ ﻣﻦ ﺃﻥ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ‬ ‫ﺗﻌﻤﻞ ﻛﻤﺎ ﻳﺮﺍﻡ.‬‫ﻧﻌﻮﺩ ﺑﺎﳊﺪﻳﺚ ﺍﱃ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ )‪ ٣ (GDT‬ﺣﻴﺚ ﺳﻴﺘﻢ ﺍﻧﺸﺎﺋﻪ ﺑﻠﻐﺔ ﺍﻟﺴﻲ ﻭﻫﺬﺍ ﻣﺎ ﺳﻴﺴﻤﺢ ﻟﻨﺎ‬‫ﺑﺎﺳﺘﺨﺪﺍﻡ ﺗﺮﺍﻛﻴﺐ ﻋﺎﻟﻴﺔ ﻟﻠﺘﻌﺒﲑ ﻋﻦ ﺍﳉﺪﻭﻝ ﻭ ﺍﳌﺆﺷﺮ ﳑﺎ ﻳﻌﻄﻲ ﻭﺿﻮﺡ ﻭﻣﻘﺮﻭﺋﻴﺔ ﺃﻛﺜﺮ ﰲ ﺍﻟﺸﻔﺮﺓ.ﻭﺳﻮﻑ‬ ‫ﳓﺘﺎﺝ ﺍﱃ ﺗﻌﺮﻳﻒ ﺛﻼﺙ ﺩﻭﺍﻝ ٤:‬‫ﺍﻟﺪﺍﻟﺔ ‪ :i386 gdt init‬ﺗﻘﻮﻡ ﺑﺘﻬﻴﺌﺔ ﻭﺍﺻﻔﺔ ﺧﺎﻟﻴﺔ ﻭﻭﺍﺻﻔﺔ ﻟﻠﺸﻔﺮﺓ ﻭﻟﻠﺒﻴﺎﻧﺎﺕ ﻭﻛﺬﻟﻚ ﺍﻧﺸﺎء ﻣﺆﺷﺮ‬ ‫•‬ ‫ﺍﳉﺪﻭﻝ.‬‫ﺍﻟﺪﺍﻟﺔ ‪ :i386 gdt set desc‬ﺩﺍﻟﺔ ‪‬ﻴﺌﺔ ﺍﻟﻮﺍﺻﻔﺔ ﺣﻴﺚ ﺗﺴﺘﻘﺒﻞ ﺍﻟﻘﻴﻢ ﻭﺗﻌﻴﻨﻬﺎ ﺍﱃ ﺍﻟﻮﺍﺻﻔﺔ ﺍﳌﻄﻠﻮﺑﺔ.‬ ‫•‬‫ﺍﻟﺪﺍﻟﺔ ‪ :gdt install‬ﺗﻘﻮﻡ ﺑﺘﺤﻤﻴﻞ ﺍﳌﺆﺷﺮ ﺍﻟﺬﻱ ﳛﻮﻱ ﺣﺠﻢ ﺍﳉﺪﻭﻝ ﻭﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺘﻪ ﺍﱃ ﺍﳌﺴﺠﻞ‬ ‫•‬ ‫‪.GDTR‬‬ ‫ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺍﻧﺸﺎء ﺍﳉﺪﻭﻝ ٥.‬ ‫‪Example‬‬ ‫‪٦.٤: hal/gdt.cpp:Install GDT‬‬ ‫٣ﺭﺍﺟﻊ ٤.١.١.‬ ‫٤ﻟﻐﺮﺽ ﺍﻟﺘﻨﻈﻴﻢ ﻭﺍﻟﺘﻘﺴﻴﻢ ﻻ ﺃﻛﺜﺮ ﻭﻻ ﺃﻗﻞ.‬ ‫٥ﺭﺍﺟﻊ ﺷﻔﺮﺓ ﺍﻟﻨﻈﺎﻡ ﻟﻘﺮﺍءﺓ ﻣﻠﻒ ﺍﻟﺮﺃﺱ ‪.hal/gdt.h‬‬ ‫٠٣١‬
    • So ware Interrupts ‫٦.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ‬١٢ #include <string.h>٣ #include "gdt.h"٤٥ static struct gdt desc gdt[MAX GDT DESC];٦ static struct gdtr gdtr;٧٨٩ static void gdt install();١٠١١١٢ static void gdt install() {١٣ #ifdef MSC VER١٤ asm lgdt [ gdtr];١٥ #endif١٦ }١٧١٨ extern void i386 gdt set desc(uint32 t index,uint64 t base,uint64 t limit,uint8 t access,uint8 t grand) {١٩٢٠ if ( index > MAX GDT DESC )٢١ return;٢٢٢٣ // clear the desc.٢٤ memset((void∗)& gdt[index],0,sizeof(struct gdt desc));٢٥٢٦ // set limit and base.٢٧ gdt[index].low base = uint16 t(base & 0xffff);٢٨ gdt[index].mid base = uint8 t((base >> 16) & 0xff);٢٩ gdt[index].high base = uint8 t((base >> 24) & 0xff);٣٠ gdt[index].limit = uint16 t(limit & 0xffff);٣١٣٢ // set flags and grandularity bytes٣٣ gdt[index].flags = access;٣٤ gdt[index].grand = uint8 t((limit >> 16) & 0x0f);٣٥ gdt[index].grand = gdt[index].grand | grand & 0xf0;٣٦ }٣٧٣٨ extern gdt desc ∗ i386 get gdt desc(uint32 t index) {٣٩ if ( index >= MAX GDT DESC )٤٠ return 0;١٣١
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٤١ else٤٢ return & gdt[index];٤٣ }٤٤٤٥ extern int i386 gdt init() {٤٦٤٧ // init gdtr٤٨ gdtr.limit = sizeof(struct gdt desc) ∗ MAX GDT DESC − 1;٤٩ gdtr.base = (uint32 t)& gdt[0];٥٠٥١ // set null desc.٥٢ i386 gdt set desc(0,0,0,0,0);٥٣٥٤ // set code desc.٥٥ i386 gdt set desc(1,0,0xffffffff,٥٦ I386 GDT CODE DESC | I386 GDT DATA DESC | I386 GDT READWRITE | I386 GDT MEMORY, // 10011010٥٧ I386 GDT LIMIT HI | I386 GDT 32BIT | I386 GDT 4K // 11001111٥٨٥٩ );٦٠٦١ // set data desc.٦٢ i386 gdt set desc(2,0,0xffffffff,٦٣ I386 GDT DATA DESC | I386 GDT READWRITE | I386 GDT MEMORY, // 10010010٦٤ I386 GDT LIMIT HI | I386 GDT 32BIT | I386 GDT 4K // 11001111٦٥ );٦٦٦٧ // install gdtr٦٨ gdt install();٦٩٧٠ return 0;٧١ } ١٣٢
    • ‫‪Programmable Interrupt Controller‬‬ ‫٦.٢. ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫‪Programmable Interrupt‬‬ ‫٦.٢. ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫‪Controller‬‬‫ﺍﻟﺴﺒﺐ ﺍﻟﺮﺋﻴﺴﻲ ﰲ ﺗﻌﻄﻴﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﻋﻨﺪ ﺍﻹﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ )‪ (PMode‬ﻫﻮ ﺑﺴﺒﺐ ﻋﺪﻡ‬‫ﺗﻮﻓﺮ ﺩﻭﺍﻝ ﳌﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺗﻠﻚ ﺍﻟﻠﺤﻈﺔ ، ﻭﺣﱴ ﻟﻮ ﻗﻤﻨﺎ ﺑﺘﻮﻓﲑ ﺍﻝ ٦٥٢ ﺩﺍﻟﺔ ﳌﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻓﺎﻥ‬‫ﻫﻨﺎﻟﻚ ﻣﺸﻜﻠﺔ ﺍﺳﺘﺨﺪﺍﻡ ﻧﻔﺲ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻷﻛﺜﺮ ﻣﻦ ﻏﺮﺽ ، ﻓﻤﺜﻼ ﻣﺆﻗﺘﺔ ﺍﻟﻨﻈﺎﻡ ‪ PIT‬ﺍﻟﱵ ﺗﺮﺳﻞ ﻣﻘﺎﻃﻌﺎﺕ‬‫ﺑﺸﻜﻞ ﺩﺍﺋﻢ ﺗﺴﺘﺨﺪﻡ ﺍﳌﻘﺎﻃﻌﺔ ﺭﻗﻢ ٨ ﻭﺍﻟﱵ ﻫﻲ ﺃﻳﻀﺎ ﺃﺣﺪ ﺍﺳﺘﺜﻨﺎءﺍﺕ ﺍﳌﻌﺎﰿ ، ﻟﺬﻟﻚ ﰲ ﻛﻠﺘﺎ ﺍﳊﺎﻻﺕ ﺳﻴﺘﻢ‬‫ﺍﺳﺘﺪﻋﺎء ﺩﺍﻟﺔ ﲣﺪﱘ ﻭﺍﺣﺪﺓ ﻭﻫﻮ ﺷﻲء ﻣﺮﻓﻮﺽ ﲤﺎﻣﴼ. ﻟﺬﻟﻚ ﺍﳊﻞ ﺍﻟﻮﺣﻴﺪ ﻫﻮ ﺑﺈﻋﺎﺩﺓ ﺑﺮﳎﺔ ﺍﳌﺘﺤﻜﻢ ﺍﳌﺴﺆﻭﻝ‬‫ﻋﻦ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻹﺷﺎﺭﺍﺕ ﻣﻦ ﻣﺘﺤﻜﻤﺎﺕ ﺍﻟﻌﺘﺎﺩ ﻭﺗﻌﻴﲔ ﺃﺭﻗﺎﻡ ﳐﺘﻠﻔﺔ ﲞﻼﻑ ﺗﻠﻚ ﺍﻷﺭﻗﺎﻡ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ‬‫ﻟﻸﺧﻄﺎء ﻭﺍﻻﺳﺘﺜﻨﺎءﺍﺕ ، ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ )ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ٦.١( ﻭﻇﻴﻔﺘﻪ ﻫﻲ ﺍﺳﺘﻘﺒﺎﻝ ﺇﺷﺎﺭﺍﺕ ﻣﻦ ﻣﺘﺤﻜﻤﺎﺕ‬‫ﺍﻟﻌﺘﺎﺩ ﻭﻣﻦ ﰒ ﻳﻘﻮﻡ ﺑﺘﺤﻮﻳﻠﻬﺎ ﺍﱃ ﺃﺭﻗﺎﻡ ﻣﻘﺎﻃﻌﺎﺕ ‪‬ﺮﺳﻞ ﺑﻌﺪ ﺫﻟﻚ ﺍﱃ ﺍﳌﻌﺎﰿ ﺍﻟﺬﻱ ﻳﻘﻮﻡ ﺑﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ،‬ ‫ﺗ‬‫ﻭﻳﻌﺮﻑ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﲟﺘﺤﻜﻢ ‪ PIC‬ﺍﺧﺘﺼﺎﺭﴽ ﻝ ‪ Programmable Interrupt Controller‬ﻭﻳﻌﺮﻑ ﺃﻳﻀﺎ ﺑﺎﻹﺳﻢ‬ ‫‪ ، 8259A‬ﻭﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺳﻨﺴﺘﺨﺪﻡ ﺍﳌﺴﻤﻰ ﻣﺘﺤﻜﻢ ‪.PIC‬‬ ‫‪8259A‬‬ ‫ﺷﻜﻞ ٦.١.: ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫‪Hardware Interrupts‬‬ ‫٦.٢.١. ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ‬‫ﻗﺒﻞ ﺃﻥ ﻧﺒﺪﺃ ﰲ ﺍﻟﺪﺧﻮﻝ ﰲ ﺗﻔﺎﺻﻴﻞ ﻣﺘﺤﻜﻢ ‪ PIC‬ﳚﺐ ﺇﻋﻄﺎء ﻧﺒﺬﺓ ﻋﻦ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﺣﻴﺚ ﺫﻛﺮﻧﺎ ﺃ‪‬ﺎ‬‫ﻣﻘﺎﻃﻌﺎﺕ ﲣﺘﻠﻒ ﻋﻦ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ ﻣﻦ ﻧﺎﺣﻴﺔ ﺃﻥ ﻣﺼﺪﺭﻫﺎ ﻳﻜﻮﻥ ﻣﻦ ﺍﻟﻌﺘﺎﺩ ﻭﻟﻴﺲ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﻣﺎ ، ﻭﻫﺬﺍ‬‫ﻣﺎ ﺃﺩﻯ ﺍﱃ ﻇﻬﻮﺭ ﻟﻘﺐ ﻣﺴﲑ ﻟﻸﺣﺪﺍﺙ )‪ (Interrupt Driven‬ﻋﻠﻰ ﺃﺟﻬﺰﺓ ﺍﳊﺎﺳﺐ. ﺣﻴﺚ ﻗﺪﳝﺎ ﱂ ﻳﻜﻦ ﻫﻨﺎﻙ‬‫ﻃﺮﻳﻘﺔ ﻟﻠﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﺇﻻ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺣﻠﻘﺔ ﺑﺮﳎﻴﺔ )‪ (loop‬ﻋﻠﻰ ﻣﺴﺠﻞ ﻣﺎ ﰲ ﻣﺘﺤﻜﻢ ﺍﻟﻌﺘﺎﺩ ﺣﱴ ﺗﺘﻐﲑ ﻗﻴﻤﺘﻪ‬‫ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﻨﺎﻙ ﻗﻴﻤﺔ ﺃﻭ ﻧﺘﻴﺠﺔ ﻗﺪ ﺟﺎءﺕ ﻣﻦ ﺍﻟﻌﺘﺎﺩ ، ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﰲ ﺍﻟﺘﺨﺎﻃﺐ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﺗﺴﻤﻰ ‪٦ Polling‬‬‫ﻭﻫﻲ ﺗﻀﻴﻊ ﻭﻗﺖ ﺍﳌﻌﺎﰿ ﰲ ﺍﻧﺘﻈﺎﺭ ﻗﻴﻤﺔ ﻻ ‪‬ﻌﺮﻑ ﻫﻞ ﺳﺘﻈﻬﺮ ﺃﻡ ﻻ ﻭﻗﺪ ﰎ ﺇﻟﻐﺎﺋﻬﺎ ﰲ ﺍﻟﺘﺨﺎﻃﺐ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﺣﻴﺚ‬ ‫ﻳ‬‫ﺍﻻﻥ ﺃﺻﺒﺢ ﺃﻱ ﻣﺘﺤﻜﻢ ﻋﺘﺎﺩ ﻳﺪﻋﻢ ﺇﺭﺳﺎﻝ ﺍﻹﺷﺎﺭﺍﺕ )ﻭﺑﺎﻟﺘﺎﱄ ﺍﳌﻘﺎﻃﻌﺎﺕ( ﺍﱃ ﺍﳌﻌﺎﰿ ﻭﺍﻟﺬﻱ ﻗﺪ ﻳﻌﻤﻞ ﻋﻠﻰ‬‫ﻋﻤﻠﻴﺔ ﺃﺧﺮﻯ ، ﻭﻫﻜﺬﺍ ﰎ ﺍﻹﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻭﻗﺖ ﺍﳌﻌﺎﰿ ﻭﺃﺻﺒﺢ ﺍﻟﺘﺨﺎﻃﺐ ﻫﻮ ﻏﲑ ﻣﺘﺰﺍﻣﻦ )‪(Asynchronous‬‬‫ﺑﺪﻻﹰ ﻣﻦ ﻣﺘﺰﺍﻣﻦ )‪ .(Synchronous‬ﻭﻋﻨﺪﻣﺎ ﻳﺒﺪﺃ ﺍﳊﺎﺳﺐ ﰲ ﺍﻹﻗﻼﻉ ﻓﺎﻥ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﻳﻘﻮﻡ ﺑﺘﺮﻗﻴﻢ ﻋﺘﺎﺩ‬ ‫‪.Busy Wai‬‬ ‫‪ng‬‬ ‫٦ﻭﺗﺴﻤﻰ ﺃﻳﻀﺎ ﺏ‬‫٣٣١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫68‪x‬‬ ‫ﺟﺪﻭﻝ ٦.٣.: ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩ ﳊﻮﺍﺳﻴﺐ‬ ‫ﺭﻗﻢ ﺍﳌﺸﺒﻚ)ﺍﻟﺪﺑﻮﺱ( ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﺍﻟﻮﺻﻒ‬ ‫ﺍﳌﺆﻗﺘﺔ ‪Timer‬‬ ‫80‪0x‬‬ ‫0‪IRQ‬‬ ‫ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬ ‫90‪0x‬‬ ‫1‪IRQ‬‬ ‫‪‬ﺮﺑﻂ ﻣﻊ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺛﺎﻧﻮﻱ‬ ‫ﻳ‬ ‫‪0x0a‬‬ ‫2‪IRQ‬‬ ‫ﺍﳌﻨﻔﺬ ﺍﻟﺘﺴﻠﺴﻠﻲ ٢‬ ‫‪0x0b‬‬ ‫3‪IRQ‬‬ ‫ﺍﳌﻨﻔﺬ ﺍﻟﺘﺴﻠﺴﻠﻲ ١‬ ‫‪0x0c‬‬ ‫4‪IRQ‬‬ ‫ﻣﻨﻔﺬ ﺍﻟﺘﻮﺍﺯﻱ ٢‬ ‫‪0x0d‬‬ ‫5‪IRQ‬‬ ‫ﻣﺘﺤﻜﻢ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ‬ ‫‪0x0e‬‬ ‫6‪IRQ‬‬ ‫ﻣﻨﻔﺬ ﺍﻟﺘﻮﺍﺯﻱ ١‬ ‫‪0x0f‬‬ ‫7‪IRQ‬‬ ‫ﺳﺎﻋﺔ ﺍﻝ ‪CMOS‬‬ ‫07‪0x‬‬ ‫0‪IRQ8/IRQ‬‬ ‫‪CGA ver cal retrace‬‬ ‫17‪0x‬‬ ‫1‪IRQ9/IRQ‬‬ ‫ﳏﺠﻮﺯﺓ‬ ‫27‪0x‬‬ ‫2‪IRQ10/IRQ‬‬ ‫ﳏﺠﻮﺯﺓ‬ ‫37‪0x‬‬ ‫3‪IRQ11/IRQ‬‬ ‫ﳏﺠﻮﺯﺓ‬ ‫47‪0x‬‬ ‫4‪IRQ12/IRQ‬‬ ‫ﻭﺣﺪﺓ ‪FPU‬‬ ‫57‪0x‬‬ ‫5‪IRQ13/IRQ‬‬ ‫ﻣﺘﺤﻜﻢ ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ‬ ‫67‪0x‬‬ ‫6‪IRQ14/IRQ‬‬ ‫ﳏﺠﻮﺯﺓ‬ ‫77‪0x‬‬ ‫7‪IRQ15/IRQ‬‬‫ﺍﳊﺎﺳﺐ ﻭﺇﻋﻄﺎء ﺭﻗﻢ ﻣﻘﺎﻃﻌﺔ ﻟﻜﻞ ﻣﺘﺤﻜﻢ ﻭﺑﺴﺒﺐ ﺗﻜﺮﺍﺭ ﻫﺬﻩ ﺍﻷﺭﻗﺎﻡ ﻓﺎﻧﻪ ﳚﺐ ﺗﻐﻴﲑﻫﺎ ﻷﺭﻗﺎﻡ ﺃﺧﺮﻯ ﻭﻫﺬﺍ‬‫ﻳﺘﻢ ﺑﺴﻬﻮﻟﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻭﺫﻟﻚ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﺃﻣﺎ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﻴﺠﺐ ﺃﻥ ﻧﻘﻮﻡ‬‫ﺑﺎﻟﺘﺨﺎﻃﺐ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺬﻱ ﻟﺪﻳﻪ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﻣﻦ ﰒ ﺗﻐﻴﲑﻫﺎ . ﻭﺍﳉﺪﻭﻝ ٦.٣ ﻳﻮﺿﺢ ﺃﺭﻗﺎﻡ‬ ‫ﺍﳌﻘﺎﻃﻌﺎﺕ ﳌﺘﺤﻜﻤﺎﺕ ﺍﳊﺎﺳﺐ.‬ ‫‪PIC‬‬ ‫٦.٢.٢. ﺑﺮﳎﺔ ﻣﺘﺤﻜﻢ‬‫ﻣﺘﺤﻜﻢ ‪ PIC‬ﻳﺴﺘﻘﺒﻞ ﺇﺷﺎﺭﺍﺕ )‪ (Signals‬ﻣﻦ ﻣﺘﺤﻜﻤﺎﺕ ﺍﻟﻌﺘﺎﺩ ﻭﺍﻟﱵ ﺗﻜﻮﻥ ﻣﻮﺻﻮﻟﺔ ﺑﻪ ﻭﻣﻦ ﰒ ﻳﻘﻮﻡ ﺑﺘﺤﻮﻳﻠﻬﺎ‬‫ﺍﱃ ﺃﺭﻗﺎﻡ ﻣﻘﺎﻃﻌﺎﺕ ﻟﻜﻲ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ ﺑﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺩﺍﻟﺔ ﲣﺪﳝﻬﺎ ، ﻭﻳﺮﺍﻋﻲ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺃﻭﻟﻴﺔ ﻣﺘﺤﻜﻤﺎﺕ‬‫ﺍﻟﻌﺘﺎﺩ ، ﻓﻤﺜﻼ ﻟﻮ ﰎ ﺇﺭﺳﺎﻝ ﺇﺷﺎﺭﺗﲔ ﰲ ﻧﻔﺲ ﺍﻟﻮﻗﺖ ﺍﱃ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻓﺎﻥ ﺍﳌﺘﺤﻜﻢ ﺳﻮﻑ ﻳﺮﺍﻋﻲ ﺍﻷﻭﻟﻴﺔ ﻭﻳﻘﻮﻡ‬‫ﺑﺎﺭﺳﺎﻝ ﺭﻗﻢ ﻣﻘﺎﻃﻌﺔ ﺍﻟﻌﺘﺎﺩ ﺫﻭ ﺍﻷﻭﻟﻴﺔ ﺃﻭﻻ ﻭﺑﻌﺪ ﺃﻥ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻳﻘﻮﻡ ﺍﳌﺘﺤﻜﻢ ﺑﺎﺭﺳﺎﻝ ﺍﻟﺮﻗﻢ‬‫ﺍﻵﺧﺮ . ﻭﻧﻈﺮﴽ ﻟﺘﻌﻘﻴﺪﺍﺕ ﺑﻨﺎء ﺍﳌﺘﺤﻜﻢ ﻓﺎﻧﻪ ﻳﺘﻌﺎﻣﻞ ﻓﻘﻂ ﻣﻊ ٨ ﺃﺟﻬﺰﺓ ﳐﺘﻠﻔﺔ )ﺃﻱ ٨ ﻣﻘﺎﻃﻌﺎﺕ ‪ (IRQ‬ﻭﻫﺬﺍ‬‫ﻣﺎ ﺃﺩﻯ ﻣﺼﻨﻌﻰ ﺍﳊﺎﺳﺐ ﺍﱃ ﺗﻮﻓﲑ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺁﺧﺮ ﻳﻌﺮﻑ ﺑﺎﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ )‪. (Secondary/Slave PIC‬‬‫ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ )‪ (Primary PIC‬ﻳﻮﺟﺪ ﺩﺍﺧﻞ ﺍﳌﻌﺎﰿ ﻭﻳﺮﺗﺒﻂ ﻣﻊ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻭﺍﻟﺬﻱ ﻳﺘﻮﺍﺟﺪ ﰲ ﺍﳉﺴﺮ‬ ‫ﺍﳉﻨﻮﰊ )‪. (SouthBridge‬‬ ‫٤٣١‬
    • ‫‪Programmable Interrupt Controller‬‬ ‫٦.٢. ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫‪PICs Pins‬‬ ‫ﻣﺸﺎﺑﻚ ﺍﳌﺘﺤﻜﻢ‬‫ﺗﻌﺘﱪ ﻣﺸﺎﺑﻚ ﺍﳌﺘﺤﻜﻢ ﻫﻲ ﻃﺮﻳﻘﺔ ﺍﺭﺳﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻣﻦ ﺍﳌﺘﺤﻜﻢ ﺍﱃ ﺍﳌﻌﺎﰿ )ﺃﻭ ﺍﱃ ﻣﺘﺤﻜﻢ ﺭﺋﻴﺴﻲ( ، ﻭﻧﻈﺮﴽ‬‫ﻻﻥ ﻛﻞ ﻣﺸﺒﻚ ﻟﺪﻳﻪ ﻭﻇﻴﻔﺔ ﳏﺪﺩﺓ ﻓﺎﻧﻪ ﳚﺐ ﺩﺭﺍﺳﺔ ﻫﺬﻩ ﺍﳌﺸﺎﺑﻚ ﻭﻟﻜﻦ ﻟﻦ ﻧﻔ ‪‬ﻞ ﻛﺜﲑﴽ ﺣﻴﺚ ﺃﻥ ﺍﳌﻮﺿﻮﻉ‬ ‫ﺼ‬ ‫ﻣﺘﺸﻌﺐ ﻭﳜﺺ ﺩﺭﺍﺳﻲ ﺍﳌﻨﻄﻖ ﺍﻟﺮﻗﻤﻲ )‪ .(Digital Logic‬ﻭﻳﻮﺿﺢ ﺍﻟﺸﻜﻞ ٦.٢ ﻫﺬﻩ ﺍﳌﺸﺎﺑﻚ.‬ ‫ﺣﻴﺚ ﺃﻥ ﺍﳌﺸﺎﺑﻚ 7‪ D0-D‬ﻫﻲ ﻹﺭﺳﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﱃ ﻣﺘﺤﻜﻢ‬ ‫‪ PIC‬ﺃﻣﺎ ﺍﳌﺸﺎﺑﻚ 2‪ CAS0, CAS1, CAS‬ﺗﺴﺘﺨﺪﻡ ﻟﻠﺘﺨﺎﻃﺐ ﺑﲔ‬ ‫ﻣﺘﺤﻜﻤﺎﺕ ‪ PIC‬ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺍﻟﺜﺎﻧﻮﻳﺔ ، ﻭﺍﳌﺸﺒﻚ ‪ INT‬ﻳﺮﺗﺒﻂ ﻣﻊ‬ ‫ﻣﺸﺒﻚ ﻟﻠﻤﻌﺎﰿ ﻭﻫﻮ ‪ INTR‬ﻛﺬﻟﻚ ﺍﳌﺸﺒﻚ ‪ INTA‬ﻳﺮﺗﺒﻂ ﻣﻊ‬ ‫ﻣﺸﺒﻚ ﺍﳌﻌﺎﰿ ‪ INTA‬ﻭﻫﺬﻩ ﺍﳌﺸﺎﺑﻚ ﳍﺎ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﻔﻮﺍﺋﺪ ﺣﻴﺚ‬ ‫ﻋﻨﺪﻣﺎ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ ﺑﺘﻨﻔﻴﺬ ﺃﻱ ﻣﻘﺎﻃﻌﺔ ﻓﺎﻧﻪ ﻳﻘﻮﻡ ﺑﺘﻌﻄﻴﻞ ﻗﻴﻢ‬ ‫ﺍﻟﻌﻠﻤﲔ ‪ IF and TF‬ﻭﻫﺬﺍ ﻣﺎ ﳚﻌﻞ ﻣﺸﺒﻚ ﺍﳌﻌﺎﰿ ‪ INTR‬ﻳﻐﻠﻖ‬ ‫ﻣﺒﺎﺷﺮﺓ ﻭﺑﺎﻟﺘﺎﱄ ﻻ ﳝﻜﻦ ﳌﺘﺤﻜﻢ ‪ PIC‬ﺇﺭﺳﺎﻝ ﺃﻱ ﻣﻘﺎﻃﻌﺔ ﻋﱪ‬ ‫ﺷﻜﻞ ٦.٢.: ﻣﺸﺎﺑﻚ ﻣﺘﺤﻜﻢ ‪PIC‬‬ ‫ﻣﺸﺒﻜﻪ ‪ INT‬ﺣﻴﺚ ﺃﻥ ﺍﳉﻬﺔ ﺍﳌﻘﺎﺑﻠﺔ ﳍﺎ ﰎ ﻏﻠﻘﻬﺎ ﻭﺑﺎﻟﺘﺎﱄ ﻻ ﳝﻜﻦ‬ ‫ﳌﻘﺎﻃﻌﺔ ﺃﻥ ﺗﻘﻄﻊ ﻣﻘﺎﻃﻌﺔ ﺃﺧﺮﻯ ﻭﺇﳕﺎ ﻳﺘﻢ ﺣﺠﺮﻫﺎ ﰲ ﻣﺴﺠﻞ‬‫ﺩﺍﺧﻞ ‪ PIC‬ﺍﱃ ﺃﻥ ﻳﻨﺘﻬﻲ ﺍﳌﻌﺎﰿ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﳌﻘﺎﻃﻌﺔ ﻭﺍﻟﻌﻮﺩﺓ ﺑﺈﺷﺎﺭﺓ )ﺗﺴﻤﻰ ﺇﺷﺎﺭﺓ ‪‬ﺎﻳﺔ ﺍﳌﻘﺎﻃﻌﺔ ‪End Of‬‬‫‪ (Interrupt‬ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﳌﻘﺎﻃﻌﺔ ﻗﺪ ﺍﻧﺘﻬﺖ. ﺃﺧﲑﺍ ﻣﺎ ﻳﻬﻤﻨﺎ ﰲ ﻫﺬﻩ ﺍﳌﺸﺎﺑﻚ ﻫﻲ ﻣﺸﺎﺑﻚ 7‪ IR0...IR‬ﻭﻫﻲ‬‫ﻣﺸﺎﺑﻚ ﺗﺮﺗﺒﻂ ﻣﻊ ﻣﺘﺤﻜﻤﺎﺕ ﺍﻟﻌﺘﺎﺩ ﺍﳌﺮﺍﺩ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻹﺷﺎﺭﺍﺕ ﻣﻨﻪ ﻋﻨﺪ ﺣﺪﻭﺙ ﺷﻲء ﻣﻌﲔ )ﺍﻟﻀﻐﻂ ﻋﻠﻰ‬‫ﺣﺮﻑ ﰲ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻣﺜﻼﹰ( ﻭﳝﻜﻦ ﳍﺬﻩ ﺍﳌﺸﺎﺑﻚ ﺃﻥ ﺗﺮﺗﺒﻂ ﻣﻊ ﻣﺘﺤﻜﻤﺎﺕ ‪ PIC‬ﺃﺧﺮﻯ ﻭﻻ ﻳﻮﺟﺪ ﺷﺮﻁ‬‫ﻳﻨﺺ ﻋﻠﻰ ﻭﺟﻮﺏ ﺗﻮﻓﺮ ﻣﺘﺤﻜﻤﲔ ‪ PIC‬ﻭﺇﳕﺎ ﳝﻜﻦ ﺭﺑﻂ ﻛﻞ ﻣﺸﺒﻚ ﻣﻦ ﻫﺬﻩ ﺍﳌﺸﺎﺑﻚ ﺍﻟﺜﻤﺎﻧﻴﺔ ﻣﻊ ﻣﺘﺤﻜﻢ ‪PIC‬‬‫ﻭﻫﻜﺬﺍ ﺳﻴﺘﻮﺍﺟﺪ ٨ ﻣﺘﺤﻜﻤﺎﺕ ﺗﺪﻋﻢ ﺣﱴ ٦٥٢ ﻣﻘﺎﻃﻌﺔ ﻋﺘﺎﺩﻳﺔ ﳐﺘﻠﻔﺔ. ﻭﳚﺐ ﻣﻼﺣﻈﺔ ﺃﻥ ﻣﺘﺤﻜﻢ ﺍﻟﻌﺘﺎﺩ‬ ‫ﺍﻟﺬﻱ ﻳﺮﺗﺒﻂ ﺑﺄﻭﻝ ﻣﺸﺒﻚ 0‪ IR‬ﻟﺪﻳﻪ ﺍﻷﻭﻟﻴﺔ ﺍﻷﻭﱃ ﰲ ﺍﻟﺘﻨﻔﻴﺬ ﻭﻫﻜﺬﺍ ﻋﻠﻰ ﺍﻟﺘﻮﺍﱄ.‬ ‫‪PIC‬‬ ‫ﻣﺴﺠﻼﺕ ﻣﺘﺤﻜﻢ‬ ‫ﳛﻮﻱ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻋﻠﻰ ﻋﺪﺓ ﻣﺴﺠﻼﺕ ﺩﺍﺧﻠﻴﺔ ﻭﻫﻲ:‬‫ﻣﺴﺠﻞ ﺍﻷﻭﺍﻣﺮ )‪ :(Command Reigster‬ﻭﻳﺴﺘﺨﺪﻡ ﻹﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ، ﻭﻫﻨﺎﻙ ﻋﺪﺩ ﻣﻦ‬ ‫•‬ ‫ﺍﻷﻭﺍﻣﺮ ﻣﺜﻞ ﺃﻣﺮ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ﻣﺴﺠﻞ ﻣﺎ ﺃﻭ ﺃﻣﺮ ﺍﺭﺳﺎﻝ ﺍﺷﺎﺭﺓ ‪.EOI‬‬ ‫ﻣﺴﺠﻞ ﺍﳊﺎﻟﺔ )‪ :(Status Register‬ﻭﻫﻮ ﻣﺴﺠﻞ ﻟﻠﻘﺮﺍءﺓ ﻓﻘﻂ ﺣﻴﺚ ﺗﻈﻬﺮ ﻋﻠﻴﻪ ﺣﺎﻟﺔ ﺍﳌﺘﺤﻜﻢ.‬ ‫•‬‫ﻣﺴﺠﻞ ﻃﻠﺒﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ )‪ :(Interrupt Request Register‬ﳛﻔﻆ ﻫﺬﺍ ﺍﳌﺴﺠﻞ ﺍﻷﺟﻬﺰﺓ ﺍﻟﱵ ﻃﻠﺒﺖ‬ ‫•‬‫ﺗﻨﻔﻴﺬ ﻣﻘﺎﻃﻌﺘﻬﺎ ﻭﻫﻲ ﺑﺎﻧﺘﻈﺎﺭ ﻭﺻﻮﻝ ﺇﺷﻌﺎﺭ )‪ (Acnowledges‬ﻣﻦ ﺍﳌﻌﺎﰿ ، ﻭﺍﳉﺪﻭﻝ ٦.٤ ﻳﻮﺿﺢ ﺑﺘﺎﺕ‬ ‫ﻫﺬﺍ ﺍﳌﺴﺠﻞ.‬‫٥٣١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫ﺟﺪﻭﻝ ٦.٤.: ﻣﺴﺠﻞ ‪IRR/ISR/IMR‬‬ ‫)‪IRQ Number (Slave controller) IRQ Number (Primary controller‬‬ ‫‪Bit Number‬‬ ‫8‪IRQ‬‬ ‫0‪IRQ‬‬ ‫0‬ ‫9‪IRQ‬‬ ‫1‪IRQ‬‬ ‫1‬ ‫01‪IRQ‬‬ ‫2‪IRQ‬‬ ‫2‬ ‫11‪IRQ‬‬ ‫3‪IRQ‬‬ ‫3‬ ‫21‪IRQ‬‬ ‫4‪IRQ‬‬ ‫4‬ ‫31‪IRQ‬‬ ‫5‪IRQ‬‬ ‫5‬ ‫41‪IRQ‬‬ ‫6‪IRQ‬‬ ‫6‬ ‫51‪IRQ‬‬ ‫7‪IRQ‬‬ ‫7‬ ‫‪PIC‬‬ ‫ﺟﺪﻭﻝ ٦.٥.: ﻋﻨﺎﻭﻳﻦ ﺍﳌﻨﺎﻓﺬ ﳌﺘﺤﻜﻢ‬ ‫ﺍﻟﻮﺻﻒ‬ ‫ﺭﻗﻢ ﺍﳌﻨﻔﺬ‬ ‫‪Primary PIC Command and Status Register‬‬ ‫02‪0x‬‬ ‫‪Primary PIC Interrupt Mask Register and Data Register‬‬ ‫12‪0x‬‬ ‫‪Secondary (Slave) PIC Command and Status Register‬‬ ‫0‪0xA‬‬ ‫‪Secondary (Slave) PIC Interrupt Mask Register and Data Register‬‬ ‫1‪0xA‬‬ ‫ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﺃﻱ ﺑﺖ ﻫﻲ ١ ﻓﻬﺬﺍ ﻳﻌﲏ ﺃﻥ ﻣﺘﺤﻜﻢ ﺍﻟﻌﺘﺎﺩ ﺑﺎﻧﺘﻈﺎﺭ ﺍﻹﺷﻌﺎﺭ ﻣﻦ ﺍﳌﻌﺎﰿ.‬‫ﻣﺴﺠﻞ ﺍﳋﺪﻣﺔ ))‪ :(In Service Register (ISR‬ﻳﺪﻝ ﻋﻠﻰ ﺍﳌﺴﺠﻞ ﻋﻠﻰ ﺃﻥ ﻃﻠﺐ ﺍﳌﻘﺎﻃﻌﺔ ﻗﺪ ﳒﺢ ﻭﺃﻥ‬ ‫•‬ ‫ﺍﻹﺷﻌﺎﺭ ﻗﺪ ﻭﺻﻞ ﻟﻜﻦ ﱂ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ.‬‫ﻣﺴﺠﻞ ))‪ :(Interrupt Mask Register (IMR‬ﳛﺪﺩ ﻫﺬﺍ ﺍﳌﺴﺠﻞ ﻣﺎ ﻫﻲ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﳚﺐ ﲡﺎﻫﻠﻬﺎ‬ ‫•‬ ‫ﻭﻋﺪﻡ ﺍﺭﺳﺎﻝ ﺇﺷﻌﺎﺭ ﳍﺎ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻷﻫﻢ.‬ ‫ﻭﺍﳉﺪﻭﻝ ٦.٥ ﻳﻮﺿﺢ ﻋﻨﺎﻭﻳﻦ ﻣﻨﺎﻓﺬ ﺍﳌﺴﺠﻼﺕ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪.x‬‬ ‫‪PIC‬‬ ‫ﺑﺮﳎﺔ ﻣﺘﺤﻜﻢ‬‫ﻟﱪﳎﺔ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻭﺇﻋﺎﺩﺓ ﺗﺮﻗﻴﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻓﺈﻥ ﺫﻟﻚ ﻳﺘﻄﻠﺐ ﺇﺭﺳﺎﻝ ﺑﻌﺾ ﺍﻷﻭﺍﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﲝﻴﺚ ﺗﺄﺧﺬ‬‫ﻫﺬﻩ ﺍﻷﻭﺍﻣﺮ ﳕﻂ ﻣﻌﲔ ‪‬ﺤ‪ ‬ﺩ ‪‬ﺎ ﻋﻤﻞ ﺍﳌﺘﺤﻜﻢ. ﻭﺗﻮﺟﺪ ﺃﺭﻳﻊ ﺃﻭﺍﻣﺮ ‪‬ﻴﺌﺔ ﳚﺐ ﺇﺭﺳﺎﳍﺎ ﻟﺘﻬﻴﺌﺔ ﺍﳌﺘﺤﻜﻢ ﺗﻌﺮﻑ‬ ‫ﺗ ﺪ‬‫ﺏ ‪ Ini aliza on Control Words‬ﻭﲣﺘﺼﺮ ﺑﺄﻭﺍﻣﺮ ‪‬ﻴﺌﺔ ‪ ، ICW‬ﻭﻛﺬﻟﻚ ﺗﻮﺟﺪ ﺛﻼﺙ ﺃﻭﺍﻣﺮ ﲢﻜﻢ ﰲ ﻋﻤﻞ‬‫ﻣﺘﺤﻜﻢ ‪ PIC‬ﺗﻌﺮﻑ ﺏ ‪ Opera on Control Words‬ﻭﲣﺘﺼﺮ ﺏ ‪ . OCW‬ﻭﰲ ﺣﺎﻟﺔ ﺗﻮﻓﺮ ﺃﻛﺜﺮ ﻣﻦ ﻣﺘﺤﻜﻢ‬‫‪ PIC‬ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ ﻓﻴﺠﺐ ﺃﻥ ‪‬ﺮﺳﻞ ﺃﻭﺍﻣﺮ ﺍﻟﺘﻬﻴﺌﺔ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﻵﺧﺮ ﻛﺬﻟﻚ. ﺍﻷﻣﺮ ﺍﻷﻭﻝ 1‪ ICW‬ﻭﻫﻮ ﺃﻣﺮ ﺍﻟﺘﻬﻴﺌﺔ‬ ‫ﺗ‬ ‫٦٣١‬
    • ‫‪Programmable Interrupt Controller‬‬ ‫٦.٢. ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫1‪ICW‬‬ ‫ﺟﺪﻭﻝ ٦.٦.: ﺍﻷﻣﺮ ﺍﻷﻭﻝ‬ ‫ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﻟﻘﻴﻤﺔ ﺍﻟﻮﺻﻒ‬ ‫ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ 4‪ICW‬‬ ‫4‪IC‬‬ ‫0‬ ‫‪ SNGL‬ﻫﻞ ﻳﻮﺟﺪ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻭﺍﺣﺪ‬ ‫1‬ ‫ﺗﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫‪ADI‬‬ ‫2‬ ‫‪ LTIM‬ﳕﻂ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺔ‬ ‫3‬ ‫ﺑﺖ ﺍﻟﺘﻬﻴﺌﺔ‬ ‫1‬ ‫4‬ ‫ﺗﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫0‬ ‫5‬ ‫ﺗﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫0‬ ‫6‬ ‫ﺗﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫0‬ ‫7‬‫ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺬﻱ ﳚﺐ ﺇﺭﺳﺎﻟﻪ ﺃﻭﻻ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ ﻭﻳﺄﺧﺬ ٧ ﺑﺘﺎﺕ ﻭﻳﻮﺿﺢ ﺍﳉﺪﻭﻝ ٦.٦ ﻫﺬﻩ‬ ‫ﺍﻟﺒﺘﺎﺕ ﻭﻭﻇﻴﻔﺔ ﻛﻞ ﺑﺖ.‬‫ﺣﻴﺚ ﺃﻥ ﺍﻟﺒﺖ ﺍﻷﻭﻝ ﳛﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﳚﺐ ﺇﺭﺳﺎﻝ ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ 4‪ ICW‬ﺃﻡ ﻻ ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻗﻴﻤﺔ ﺍﻟﺒﺖ ﻫﻲ ١‬‫ﻓﺈﻧﻪ ﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ 4‪ ICW‬ﺃﻣﺎ ﺍﻟﺒﺖ ﺍﻟﺜﺎﱐ ﻓﻐﺎﻟﺒﴼ ﻳﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﻨﺎﻙ ﺃﻛﺜﺮ ﻣﻦ ﻣﺘﺤﻜﻢ‬‫‪ PIC‬ﰲ ﺍﻟﻨﻈﺎﻡ ، ﻭﺍﻟﺒﺖ ﺍﻟﺜﺎﻟﺚ ﻏﲑ ﻣﺴﺘﺨﺪﻡ ﺃﻣﺎ ﺍﻟﺮﺍﺑﻊ ﻓﻴﺤﺪﺩ ﳕﻂ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺔ ﻫﻞ ﻫﻲ ‪Level Triggered‬‬‫‪ Mode‬ﺃﻡ ‪ ، Edge Triggered Mode‬ﺃﻣﺎ ﺍﻟﺒﺖ ﺍﳋﺎﻣﺲ ﻓﻴﺠﺐ ﺃﻥ ﻳﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ١ ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻧﻨﺎ ﺳﻨﻘﻮﻡ ﺑﺘﻬﻴﺌﺔ‬‫ﻣﺘﺤﻜﻢ ‪ PIC‬ﻭﺑﻘﻴﺔ ﺍﻟﺒﺘﺎﺕ ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪ .x‬ﻭﺍﻟﺸﻔﺮﺓ ٥.٦ ﺗﻮﺿﺢ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﻷﻭﻝ ﺍﱃ‬ ‫ﻣﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ.‬‫‪Example‬‬ ‫‪٦.٥: Ini‬‬ ‫1 ‪aliza on Control Words‬‬‫١‬ ‫1 ‪; Setup to initialize the primary PIC. Send ICW‬‬‫٢‬ ‫11‪mov al, 0x‬‬ ‫10001000 ;‬‫٣‬ ‫‪out 0x20, al‬‬‫٤‬‫٥‬ ‫‪; Send ICW 1 to second PIC command register‬‬‫٦‬ ‫‪out 0xA0, al‬‬‫ﺍﻷﻣﺮ ﺍﻟﺜﺎﱐ 2‪ ICW‬ﻳﺴﺘﺨﺪﻡ ﻹﻋﺎﺩﺓ ﺗﻐﻴﲑ ﻋﻨﻮﺍﻳﻦ ﺟﺪﻭﻝ ‪ IVT‬ﺍﻟﺮﺋﻴﺴﻴﺔ ﻟﻠﻄﻠﺒﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ ‪ IRQ‬ﻭﺑﺎﻟﺘﺎﱄ ﻋﻦ‬‫ﻃﺮﻳﻖ ﻫﺬﺍ ﺍﻷﻣﺮ ﳝﻜﻦ ﺃﻥ ﻧﻐﲑ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻟﻞ ‪ IRQ‬ﺍﱃ ﺃﺭﻗﺎﻡ ﺃﺧﺮﻯ . ﻭﳚﺐ ﺃﻥ ﻳﺮﺳﻞ ﻫﺬﺍ ﺍﻷﻣﺮ ﻣﺒﺎﺷﺮﺓ‬‫ﺑﻌﺪ ﺍﻷﻣﺮ ﺍﻷﻭﻝ ﻛﺬﻟﻚ ﳚﺐ ﺃﻥ ﻳﺘﻢ ﺍﺧﺘﻴﺎﺭ ﺃﺭﻗﺎﻣﺎ ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ ﻣﻦ ﻗﺒﻞ ﺍﳌﻌﺎﰿ ﺣﱴ ﻻ ﻧﻘﻊ ﰲ ﻧﻔﺲ ﺍﳌﺸﻜﻠﺔ‬‫ﺍﻟﺴﺎﺑﻘﺔ ) ﻭﻫﻲ ﺃﻛﺜﺮ ﻣﻦ ‪ IRQ‬ﻳﺴﺘﺨﺪﻡ ﻧﻔﺲ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﺑﺎﻟﺘﺎﱄ ﻟﺪﻳﻬﻢ ﺩﺍﻟﺔ ﲣﺪﱘ ﻭﺍﺣﺪﺓ(. ﻭﺍﳌﺜﺎﻝ ٦.٦‬‫ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺗﻐﻴﲑ ﺃﺭﻗﺎﻡ ‪ IRQ‬ﳌﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ ﲝﻴﺚ ﻳﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ٢٣-٩٣‬‫ﻟﻠﻤﺘﺤﻜﻢ ﺍﻷﻭﻝ ﻭﺍﻷﺭﻗﺎﻡ ﻣﻦ ٠٤-٧٤ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻭﻫﻲ ﺃﺭﻗﺎﻣﴼ ﺧﺎﻟﻴﺔ ﻻ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ ﻭﺗﻘﻊ ﻣﺒﺎﺷﺮﺓ‬ ‫ﺑﻌﺪ ﺁﺧﺮ ﻣﻘﺎﻃﻌﺔ ﻟﻠﻤﻌﺎﰿ ﺍﻟﺬﻱ ﻳﺴﺘﺨﺪﻡ ٢٣ ﻣﻘﺎﻃﻌﺔ ﺑﺪءﴽ ﻣﻦ ﺍﻟﺼﻔﺮ ﻭﺍﻧﺘﻬﺎءﴽ ﺑﺎﳌﻘﺎﻃﻌﺔ ١٣.‬‫٧٣١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫‪ICW3 for Primary PIC‬‬ ‫ﺟﺪﻭﻝ ٦.٧.: ﺍﻷﻣﺮ ﺍﻟﺜﺎﻟﺚ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ‬ ‫ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﻟﻘﻴﻤﺔ ﺍﻟﻮﺻﻒ‬ ‫7‪ S0-S‬ﺭﻗﻢ ‪ IRQ‬ﺍﻟﱵ ﻳﺘﺼﻞ ‪‬ﺎ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ‬ ‫7-0‬ ‫‪ICW3 for Slave PIC‬‬ ‫ﺟﺪﻭﻝ ٦.٨.: ﺍﻷﻣﺮ ﺍﻟﺜﺎﻟﺚ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ‬ ‫ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﻟﻘﻴﻤﺔ ﺍﻟﻮﺻﻒ‬ ‫0‪ ID‬ﺭﻗﻢ ‪ IRQ‬ﺍﻟﱵ ﻳﺘﺼﻞ ‪‬ﺎ ﻣﻊ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ‬ ‫2-0‬ ‫7-3 ﳏﺠﻮﺯﺓ‬ ‫7-3‬ ‫‪Example‬‬ ‫‪٦.٦: Ini‬‬ ‫2 ‪aliza on Control Words‬‬‫١‬ ‫‪; send ICW 2 to primary PIC‬‬‫٢‬ ‫02‪mov al, 0x‬‬‫٣‬ ‫‪out 0x21, al‬‬‫٤‬ ‫‪; Primary PIC handled IRQ 0..7. IRQ 0 is now mapped to interrupt‬‬ ‫02‪number 0x‬‬‫٥‬‫٦‬‫٧‬ ‫‪; send ICW 2 to secondary PIC‬‬‫٨‬ ‫82‪mov al, 0x‬‬‫٩‬ ‫‪out 0xA1, al‬‬‫٠١‬ ‫‪; Secondary PIC handles IRQs 8..15. IRQ 8 is now mapped to use‬‬ ‫82‪interrupt 0x‬‬‫ﺍﻷﻣﺮ ﺍﻟﺜﺎﻟﺚ 3‪ ICW‬ﻳﺴﺘﺨﺪﻡ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻫﻨﺎﻙ ﺃﻛﺜﺮ ﻣﻦ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺣﻴﺚ ﳚﺐ ﺃﻥ ﳓﺪﺩ ﺭﻗﻢ ﻃﻠﺐ‬‫ﺍﳌﻘﺎﻃﻌﺔ ‪ IRQ‬ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻟﻠﺘﺨﺎﻃﺐ ﻣﻊ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ. ﻭﰲ ﺣﻮﺍﺳﻴﺐ 68‪ x‬ﻏﺎﻟﺒﴼ ﻣﺎ‬‫ﻳﺴﺘﺨﺪﻡ 2‪ IRQ‬ﻟﺬﺍ ﳚﺐ ﺇﺭﺳﺎﻝ ﻫﺬﺍ ﺍﻷﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ، ﻟﻜﻦ ﻛﻞ ﻣﺘﺤﻜﻢ ﻳﺘﻮﻗﻊ ﺍﻷﻣﺮ ﺑﺼﻴﻐﺔ ﻣﻌﻴﻨﺔ ﻳﻮﺿﺤﻬﺎ‬ ‫ﺍﳉﺪﻭﻻﻥ ٦.٧ ﻭ ٦.٨ .‬‫ﻭﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﲝﺴﺐ ﺍﻟﺼﻴﻐﺔ ﺍﻟﱵ ﻳﻘﺒﻠﻬﺎ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻟﻠﻤﺘﺤﻜﻢ ، ﻓﻤﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﺮﺋﻴﺴﻲ ﻳﺴﺘﻘﺒﻞ‬‫ﺭﻗﻢ ‪ IRQ‬ﻋﻠﻰ ﺷﻜﻞ ٧ ﺑﺖ ﲝﻴﺚ ﻳﺘﻢ ﺗﻔﻌﻴﻞ ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﳌﻘﺎﺑﻞ ﻟﺮﻗﻢ ‪ IRQ‬ﻭﰲ ﻣﺜﺎﻟﺜﺎ ﻳﺮﺗﺒﻂ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ‬‫ﻣﻊ ﺍﻟﺜﺎﻧﻮﻱ ﻋﱪ 2‪ IRQ‬ﻟﺬﻟﻚ ﳚﺐ ﺗﻔﻌﻴﻞ ﻗﻴﻤﺔ ﺍﻟﺒﺖ ٢ )ﺃﻱ ﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻟﻘﻴﻤﺔ ‪ 0000100b‬ﻭﻫﻲ ﺗﻌﺎﺩﻝ 4‪(0x‬‬‫ﺑﻴﻨﻤﺎ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻳﻘﺒﻞ ﺭﻗﻢ ‪ IRQ‬ﻋﻦ ﻃﺮﻳﻖ ﺇﺭﺳﺎﻝ ﻗﻴﻤﺘﻪ ﻋﻠﻰ ﺍﻟﺸﻜﻞ ﺍﻟﺜﻨﺎﺋﻲ ﻭﻫﻲ ٢ )ﻭﺗﻌﺎﺩﻝ ﺑﺎﻟﺘﺮﻣﻴﺰ‬‫ﺍﻟﺜﻨﺎﺋﻲ 010( ﻭﺑﻘﻴﺔ ﺍﻟﺒﺘﺎﺕ ﳏﺠﻮﺯﺓ )ﺍﻧﻈﺮ ﺟﺪﻭﻝ ٦.٨( ، ﻭﺍﳌﺜﺎﻝ ٧.٦ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﻟﺜﺎﻟﺚ ﺍﱃ‬ ‫ﺍﳌﺘﺤﻜﻤﲔ.‬ ‫‪Example‬‬ ‫‪٦.٧: Ini‬‬ ‫3 ‪aliza on Control Words‬‬ ‫٨٣١‬
    • ‫‪Programmable Interrupt Controller‬‬ ‫٦.٢. ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ‬ ‫4‪ICW‬‬ ‫ﺟﺪﻭﻝ ٦.٩.: ﺍﻷﻣﺮ ﺍﻟﺮﺍﺑﻊ‬ ‫ﺍﻟﻮﺻﻒ‬ ‫ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﻟﻘﻴﻤﺔ‬ ‫ﳚﺐ ﺗﻔﻌﻴﻞ ﻫﺬﺍ ﺍﻟﺒﺖ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫‪uPM‬‬ ‫0‬ ‫ﺟﻌﻞ ﺍﳌﺘﺤﻜﻢ ﻳﻘﻮﻡ ﺑﺈﺭﺳﺎﻝ ﺇﺷﺎﺭﺓ ‪EOI‬‬ ‫‪AEOI‬‬ ‫1‬ ‫.‪If set (1), selects buffer master. Cleared if buffer slave‬‬ ‫‪M/S‬‬ ‫2‬ ‫‪If set, controller operates in buffered mode‬‬ ‫‪BUF‬‬ ‫3‬ ‫ﺗﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫‪SFNM‬‬ ‫4‬ ‫ﺗﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﰲ ﺣﻮﺍﺳﻴﺐ 68‪x‬‬ ‫0‬ ‫7-5‬‫١‬ ‫‪; Send ICW 3 to primary PIC‬‬‫٢‬ ‫4‪mov al, 0x‬‬ ‫)2 ‪; 0x04 => 0100, second bit (IR line‬‬‫٣‬ ‫‪out 0x21, al ; write to data register of primary PIC‬‬‫٤‬‫٥‬ ‫‪; Send ICW 3 to secondary PIC‬‬‫٦‬ ‫2‪mov al, 0x‬‬ ‫2 ‪; 010=> IR line‬‬‫٧‬ ‫‪out 0xA1, al ; write to data register of secondary PIC‬‬‫ﻫﻮ ﺁﺧﺮ ﺃﻣﺮ ﲢﻜﻢ ﳚﺐ ﺇﺭﺳﺎﻟﻪ ﺍﱃ ﺍﳌﺘﺤﻜﻤﲔ ﻭﻳﺄﺧﺬ ﺍﻟﺘﺮﻛﻴﺒﺔ ﺍﻟﱵ ﻳﻮﺿﺤﻬﺎ ﺟﺪﻭﻝ‬ ‫ﺍﻷﻣﺮ ﺍﻟﺮﺍﺑﻊ‬ ‫4‪ICW‬‬ ‫٦.٩.‬‫ﻭﰲ ﺍﻟﻐﺎﻟﺐ ﻻ ﻳﻮﺟﺪ ﺣﻮﺟﺔ ﻟﺘﻔﻌﻴﻞ ﻛﻞ ﻫﺬﻩ ﺍﳋﺼﺎﺋﺺ ، ﻓﻘﻂ ﺃﻭﻝ ﺑﺖ ﳚﺐ ﺗﻔﻌﻴﻠﻪ ﺣﻴﺚ ﻳﺴﺘﺨﺪﻡ ﻣﻊ‬ ‫ﺣﻮﺍﺳﻴﺐ 68‪ . x‬ﻭﺍﳌﺜﺎﻝ ٨.٦ ﻳﻮﺿﺢ ﻛﻴﻔﺔ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﻟﺮﺍﺑﻊ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ.‬‫‪Example‬‬ ‫‪٦.٨: Ini‬‬ ‫4 ‪aliza on Control Words‬‬‫١‬ ‫1 ,‪mov al‬‬ ‫‪; bit 0 enables 80x86 mode‬‬‫٢‬‫٣‬ ‫‪; send ICW 4 to both primary and secondary PICs‬‬‫٤‬ ‫‪out 0x21, al‬‬‫٥‬ ‫‪out 0xA1, al‬‬‫ﻭﺑﻌﺪ ﺇﺭﺳﺎﻝ ﻫﺬﻩ ﺍﻷﻭﺍﻣﺮ ﺍﻷﺭﺑﻊ ﺗﻜﺘﻤﻞ ﻋﻤﻠﻴﺔ ‪‬ﻴﺌﺔ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ ، ﻭﰲ ﺣﺎﻟﺔ ﺣﺪﻭﺙ ﺃﻱ‬‫ﻣﻘﺎﻃﻌﺔ ﻣﻦ ﻣﺘﺤﻜﻢ ﻟﻌﺘﺎﺩ ﻣﺎ ، ﻓﺈﻥ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﺳﺘﺮﺳﻞ ﺍﱃ ﺍﳌﻌﺎﰿ ﻫﻲ ﺍﻷﺭﻗﺎﻡ ﺍﻟﱵ ﻗﻤﻨﺎ ﺑﺘﻌﻴﻴﻨﻬﺎ ﰲ‬‫ﺍﻷﻣﺮ ﺍﻟﺜﺎﱐ )ﻭﺗﺒﺪﺃ ﻣﻦ ٢٣ ﺍﱃ ٧٤( ﻭﻫﻲ ﲣﺘﻠﻒ ﺑﺎﻟﻄﺒﻊ ﻋﻦ ﺍﻷﺭﻗﺎﻡ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ. ﻭﲞﺼﻮﺹ ﺃﻭﺍﻣﺮ‬‫ﺍﻟﺘﺤﻜﻢ ﺍﻟﺜﻼﺙ ‪ OCW‬ﻓﻠﻦ ﳓﺘﺎﺝ ﺍﻟﻴﻬﺎ ﲨﻴﻌﴼ ﻭﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﺍﻷﻣﺮ ﺍﻟﺜﺎﱐ 2‪ OCW‬ﻧﻈﺮﴽ ﻷﻧﻪ ﳚﺐ ﺃﻥ ‪‬ﺮﺳﻞ‬ ‫ﻳ‬‫ﺩﺍﺋﻤﴼ ﺑﻌﺪ ﺃﻥ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺍﻟﺴﻤﺎﺡ ﻟﺒﻘﻴﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺃﻥ ﺗﺄﺧﺬ ﺩﻭﺭﴽ‬‫ﳌﻌﺎﳉﺘﻬﺎ. ﻭﺍﳉﺪﻭﻝ ٦.٠١ ﻳﻮﺿﺢ ﺍﻟﺒﺘﺎﺕ ﺍﻟﱵ ﳚﺐ ﺇﺭﺳﺎﳍﺎ ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ . ﻭﻳﻬﻤﻨﺎ ﺍﻟﺒﺘﺎﺕ ٥-٧ ﺣﻴﺚ‬‫ﺃﻥ ﻗﻴﻤﻬﻢ ﲢﺪﺩ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ ﺍﻟﱵ ﻳﻮﺿﺤﻬﺎ ﺍﳉﺪﻭﻝ ٦.١١. ﻭﺍﳌﺜﺎﻝ ٩.٦ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺇﺭﺳﺎﻝ ﺇﺷﺎﺭﺓ ‪‬ﺎﻳﺔ‬‫٩٣١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫2‪OCW‬‬ ‫ﺟﺪﻭﻝ ٦.٠١.: ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ ﺍﻟﺜﺎﱐ‬ ‫ﺍﻟﻮﺻﻒ‬ ‫ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﻟﻘﻴﻤﺔ‬ ‫‪Interrupt level upon which the controller must react‬‬ ‫2‪L0/L1/L‬‬ ‫2-0‬ ‫ﳏﺠﻮﺯﺓ‬ ‫0‬ ‫4-3‬ ‫)‪End of Interrupt (EOI‬‬ ‫‪EOI‬‬ ‫5‬ ‫‪Selec on‬‬ ‫‪SL‬‬ ‫6‬ ‫‪Rota on op on‬‬ ‫‪R‬‬ ‫7‬ ‫2‪OCW‬‬ ‫ﺟﺪﻭﻝ ٦.١١.: ﺃﻣﺮ‬ ‫‪Descrip on‬‬ ‫‪EOI Bit‬‬ ‫‪SL Bit‬‬ ‫‪R Bit‬‬ ‫)‪Rotate in Automa c EOI mode (CLEAR‬‬ ‫0‬ ‫0‬ ‫0‬ ‫‪Non specific EOI command‬‬ ‫1‬ ‫0‬ ‫0‬ ‫‪No opera on‬‬ ‫0‬ ‫1‬ ‫0‬ ‫‪Specific EOI command‬‬ ‫1‬ ‫1‬ ‫0‬ ‫)‪Rotate in Automa c EOI mode (SET‬‬ ‫0‬ ‫0‬ ‫1‬ ‫‪Rotate on non specific EOI‬‬ ‫1‬ ‫0‬ ‫1‬ ‫‪Set priority command‬‬ ‫0‬ ‫1‬ ‫1‬ ‫‪Rotate on specific EOI‬‬ ‫1‬ ‫1‬ ‫1‬ ‫ﻋﻤﻞ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ )‪ (EOI‬ﺣﻴﺚ ﳚﺐ ﺿﺒﻂ ﺍﻟﺒﺘﺎﺕ ﻹﺧﺘﻴﺎﺭ ‪.Non specific EOI command‬‬‫‪Example‬‬ ‫‪٦.٩: Send EOI‬‬‫١‬ ‫‪; send EOI to primary PIC‬‬‫٢‬‫٣‬ ‫02‪mov al, 0x‬‬ ‫2 ‪; set bit 4 of OCW‬‬‫٤‬ ‫‪out 0x20, al‬‬ ‫‪; write to primary PIC command register‬‬ ‫ﻛﻴﻒ ﺗﻌﻤﻞ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩ‬‫ﻋﻨﺪﻣﺎ ﳛﺘﺎﺝ ﻣﺘﺤﻜﻢ ﺃﻱ ﻋﺘﺎﺩ ﻟﻔﺖ ﺍﻧﺘﺒﺎﻩ ﺍﳌﻌﺎﰿ ﺍﱃ ﺷﻲء ﻣﺎ ﻓﺄﻭﻝ ﺧﻄﻮﺓ ﻳﻘﻮﻡ ‪‬ﺎ ﻫﻲ ﺇﺭﺳﺎﻝ ﺇﺷﺎﺭﺓ ﺍﱃ‬‫ﻣﺘﺤﻜﻢ ‪) PIC‬ﻭﻋﻠﻰ ﺳﺒﻴﻞ ﺍﳌﺜﺎﻝ ﺳﻨﻔﺮﺽ ﺃﻥ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﻫﻮ ﻣﺘﺤﻜﻢ ﺍﳌﺆﻗﺘﺔ ‪ PIT‬ﻭﺍﻟﱵ ﺗﺮﺗﺒﻂ ﺑﺎﳌﺸﺒﻚ 0‪(IR‬‬‫ﻫﺬﻩ ﺍﻹﺷﺎﺭﺓ ﺗﺮﺳﻞ ﻋﱪ ﻣﺸﺒﻚ 0‪ ، IR‬ﺣﻴﻨﻬﺎ ﻳﻘﻮﻡ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺑﺘﺴﺠﻴﻞ ﻃﻠﺐ ﺍﳌﺘﺤﻜﻢ ‪ IRQ‬ﰲ ﻣﺴﺠﻞ ﻳﺴﻤﻰ‬‫ﻣﺴﺠﻞ ﻃﻠﺒﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ )‪ (Interrupt Request Register‬ﻭﻳﻌﺮﻑ ﺍﺧﺘﺼﺎﺭﴽ ﲟﺴﺠﻞ ‪ . IRR‬ﻫﺬﺍ ﺍﳌﺴﺠﻞ‬‫ﺑﻄﻮﻝ ٨ ﺑﺖ ﻛﻞ ﺑﺖ ﻓﻴﻪ ﳝﺜﻞ ﺭﻗﻢ ‪ IRQ‬ﻭﻳﺘﻢ ﺗﻔﻌﻴﻞ ﺃﻱ ﺑﺖ ﻋﻨﺪ ﻃﻠﺐ ﻣﻘﺎﻃﻌﺔ ﻣﻦ ﺍﳌﺘﺤﻜﻢ ، ﻭﰲ ﻣﺜﺎﻟﻨﺎ‬‫ﺳﻴﺘﻢ ﺗﻔﻌﻴﻞ ﺍﻟﺒﺖ 0 ﺑﺴﺒﺐ ﺃﻥ ﺍﳌﺆﻗﺘﺔ ﺗﺮﺗﺒﻂ ﻣﻊ 0‪ .IR‬ﺑﻌﺪ ﺫﻟﻚ ﻳﻘﻮﻡ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺑﻔﺤﺺ ﻣﺴﺠﻞ ‪Interrupt‬‬ ‫٠٤١‬
    • ‫‪Programmable Interval Timer‬‬ ‫٦.٣. ﺍﳌﺆﻗﺘﺔ‬‫‪ Mask Register‬ﻟﻴﺘﺄﻛﺪ ﻣﻦ ﺃﻧﻪ ﻻ ﺗﻮﺟﺪ ﻫﻨﺎﻙ ﻣﻘﺎﻃﻌﺔ ﺫﺍﺕ ﺃﻭﻟﻴﺔ ﺃﻋﻠﻰ ﺣﻴﺚ ﰲ ﻫﺬﻩ ﺍﳊﺎﻟﺔ ﻋﻠﻰ ﺍﳌﻘﺎﻃﻌﺔ‬‫ﺍﳉﺪﻳﺪﺓ ﺃﻥ ﺗﻨﻨﻈﺮ ﺣﱴ ﻳﺘﻢ ﲣﺪﱘ ﻛﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺫﺍﺕ ﺍﻷﻭﻟﻮﻳﺔ. ﻭﺑﻌﺪ ﺫﻟﻚ ‪‬ﺮﺳﻞ ‪ PIC‬ﺇﺷﺎﺭﺓ ﺍﱃ ﺍﳌﻌﺎﰿ ﻣﻦ‬ ‫ﻳ‬‫ﺧﻼﻝ ﻣﺸﺒﻚ ‪ INTA‬ﻷﺧﺒﺎﺭ ﺍﳌﻌﺎﰿ ﺑﺄﻥ ﻫﻨﺎﻙ ﻣﻘﺎﻃﻌﺔ ﳚﺐ ﺗﻨﻔﻴﺬﻫﺎ. ﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ ﺍﳌﻌﺎﰿ ﺣﻴﺚ ﻳﻘﻮﻡ ﺑﺎﻹﻧﺘﻬﺎء‬‫ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻷﻣﺮ ﺍﳊﺎﱄ ﺍﻟﺬﻱ ﻳﻌﻤﻞ ﻋﻠﻴﻪ ﻭﻣﻦ ﰒ ﻳﻘﻮﻡ ﺑﻔﺤﺺ ﻗﻴﻤﺔ ﺍﻟﻌﻠﻢ ‪ IF‬ﺣﻴﺚ ﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﻏﲑ ﻣﻔﻌﻠﺔ‬‫ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻮﻑ ﻳﺘﺠﺎﻫﻞ ﻃﻠﺐ ﺗﻨﻔﻴﺬ ﺍﳌﻘﺎﻃﻌﺔ، ﺃﻣﺎ ﺇﺫﺍ ﻭﺟﺪ ﺍﳌﻌﺎﰿ ﻗﻴﻤﺔ ﺍﻟﻌﻠﻢ ﻣﻔﻌﻠﺔ ﻓﺎﻧﻪ ﻳﻘﻮﻡ ﺑﺎﺭﺳﺎﻝ ﺇﺷﻌﺎﺭ‬‫)‪ (Acnowledges‬ﻋﱪ ﻣﺸﺒﻚ ‪ INTR‬ﺍﱃ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻳﺴﺘﻘﺒﻠﻬﺎ ﻣﻦ ﻣﺸﺒﻚ ‪ INTA‬ﻭﻳﻀﻊ ﺭﻗﻢ‬‫ﺍﳌﻘﺎﻃﻌﺔ ﻭﺭﻗﻢ ‪ IRQ‬ﰲ ﺍﳌﺸﺎﺑﻚ 7‪ ، D0-D‬ﻭﺃﺧﲑﺍ ﻳﻔﻌﻞ ﻗﻴﻤﺔ ﺍﻟﺒﺖ ٠ ﰲ ﻣﺴﺠﻞ ‪ In Service Register‬ﺩﻻﻟﺔ‬‫ﻋﻠﻰ ﺃﻥ ﻣﻘﺎﻃﻌﺔ ﺍﳌﺆﻗﺘﺔ ﺟﺎﺭﻱ ﺗﻨﻔﻴﺬﻫﺎ. ﻭﻋﻨﺪﻣﺎ ﳛﺼﻞ ﺍﳌﻌﺎﰿ ﻋﻠﻰ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻓﺎﻧﻪ ﻳﻘﻮﻡ ﺑﻮﻗﻒ ﺍﻟﻌﻤﻠﻴﺔ ﺍﻟﱵ‬‫ﻳﻌﻤﻞ ﻋﻠﻴﻬﺎ ﻭﳛﻔﻆ ﻗﻴﻢ ﻣﺴﺠﻞ ﺍﻷﻋﻼﻡ ﻭﻣﺴﺠﻞ ‪ CS and EIP‬ﻭﺇﺫﺍ ﻛﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻓﺈﻧﻪ‬‫ﻳﺄﺧﺬ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻳﺬﻫﺐ ‪‬ﺎ ﻛﺪﻟﻴﻞ ﺍﱃ ﺟﺪﻭﻝ ﺍﳌﻘﻄﺎﻋﺎﺕ ‪ IVT‬ﺣﻴﺚ ﳚﺪ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻣﻦ ﰒ‬‫ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ، ﺃﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﺎﻧﻪ ﻳﺄﺧﺬ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻳﺬﻫﺐ ‪‬ﺎ ﺍﱃ ﺟﺪﻭﻝ‬‫ﻭﺍﺻﻔﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺣﻴﺚ ﳚﺪ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ. ﻭﻋﻨﺪﻣﺎ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻓﺎ‪‬ﺎ ﳚﺐ‬ ‫ﺃﻥ ﺗﺮﺳﻞ ﺇﺷﺎﺭﺓ ‪ EOI‬ﺣﱴ ﻳﺘﻢ ﺗﻔﻌﻴﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﳎﺪﺩﴽ.‬ ‫‪Programmable Interval Timer‬‬ ‫٦.٣. ﺍﳌﺆﻗﺘﺔ‬‫ﺍﳌﺆﻗﺘﺔ ﻫﻲ ﺷﺮﳛﺔ )‪ Dual Inline Package (DIP‬ﲢﻮﻱ ﺛﻼﺙ ﻋﺪﺍﺩﺍﺕ )‪ (Counters or Channels‬ﺗﻌﻤﻞ‬‫ﻛﻤﺆﻗﺘﺎﺕ ﻹﺩﺍﺭﺓ ﺛﻼﺙ ﺃﺷﻴﺎء )ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ٦.٣(. ﺍﻟﻌﺪﺍﺩ ﺍﻷﻭﻝ ﻭُﻌﺮﻑ ﲟﺆﻗﺖ ﺍﻟﻨﻈﺎﻡ )‪(System Timer‬‬ ‫ﻳ‬‫ﻭﻇﻴﻔﺘﻪ ﺍﺭﺳﺎﻝ ﻃﻠﺐ ﻣﻘﺎﻃﻌﺔ )0‪ (IRQ‬ﺍﱃ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻭﺫﻟﻚ ﻟﺘﻨﻔﻴﺬ ﻣﻘﺎﻃﻌﺔ ﻣﺎ ﻛﻞ ﻓﺘﺮﺓ ﳏﺪﺩﺓ ، ﻫﺬﻩ ﺍﻟﻔﺘﺮﺓ‬‫ﻳﺘﻢ ﲢﺪﻳﺪﻫﺎ ﻋﻨﺪ ﺑﺮﳎﺔ ﻫﺬﻩ ﺍﳌﺆﻗﺘﺔ ﻭُﺴﺘﻔﺎﺩ ﻣﻦ ﻫﺬﻩ ﺍﳌﺆﻗﺘﺔ ﰲ ﻋﻤﻠﻴﺔ ﺗﺰﺍﻣﻦ ﺍﻟﻌﻤﻠﻴﺎﺕ ﻭﺗﻮﻓﲑ ﺑﻨﻴﺔ ﲢﺘﻴﺔ ﳌﻔﻬﻮﻡ‬ ‫ﻳ‬‫ﺗﻌﺪﺩ ﺍﻟﻌﻤﻠﻴﺎﺕ ﻭﺍﳌﺴﺎﻟﻚ )‪ (Mul task and Mul thread‬ﺣﻴﺚ ﺃﻥ ﺍﻟﻔﺘﺮﺓ ﺍﻟﱵ ﺗﻘﻮﻡ ‪‬ﺎ ﻣﺆﻗﺘﺔ ﺍﻟﻨﻈﺎﻡ ﻻﺻﺪﺍﺭ‬‫ﻃﻠﺐ ﺍﳌﻘﺎﻃﻌﺔ ﺳﻴﻜﻮﻥ ﻫﻮ ﺍﻟﻮﻗﺖ ﺍﳌﺤﺪﺩ ﻷﻱ ﻋﻤﻠﻴﺔ )‪ (Process‬ﻣﻮﺟﻮﺩﺓ ﰲ ﻃﺎﺑﻮﺭ ﺍﻟﻌﻤﻠﻴﺎﺕ )‪Process‬‬‫‪ (Queue‬ﻭﺑﻌﺪ ﺫﻟﻚ ﺗ ُﺳﻞ ﺍﻟﻌﻤﻠﻴﺔ ﺍﱃ ﺁﺧﺮ ﺍﻟﺼﻒ ﰲ ﺣﺎﻟﺔ ﱂ ﺗﻨﺘﻬﻲ ﻣﻦ ﻋﻤﻠﻬﺎ ﺑﻌﺪ ﻭﻳﺒﺪﺃ ﺍﳌﻌﺎﰿ ﰲ ﺗﻨﻔﻴﺬ‬ ‫ﺮ‬‫ﺍﻟﻌﻤﻠﻴﺔ ﺍﻟﺘﺎﻟﻴﺔ ﲢﺖ ﻧﻔﺲ ﺍﻟﻔﺘﺮﺓ ﺍﳌﺤﺪﺩﺓ. ﺃﻣﺎ ﺍﻟﻌﺪﺍﺩ ﺍﻟﺜﺎﱐ ﻓُﺴﺘﺨﺪﻡ ﰲ ﻋﻤﻠﻴﺔ ﺗﻨﻌﻴﺶ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ‬ ‫ﻴ‬‫)‪ (RAM refreshing‬ﺣﱴ ﲢﺎﻓﻆ ﻋﻠﻰ ﳏﺘﻮﻳﺎ‪‬ﺎ ﻣﻦ ﺍﻟﻔﻘﺪﺍﻥ ﺃﺛﻨﺎء ﻋﻤﻞ ﺍﳊﺎﺳﺐ ﻭﳚﺪﺭ ﺑﻨﺎ ﺫﻛﺮ ﺃﻥ ﻫﺬﻩ ﺍﳌﻬﻤﺔ‬‫ﻗﺪ ﹸﺣﻴﻠﺖ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ )‪ (Memory Controller‬ﻭﺃﺻﺒﺤﺖ ﻫﺬﻩ ﺍﳌﺆﻗﺘﺔ ﻻ ﺗﺴﺘﺨﺪﻡ ﰲ ﺍﻟﻌﺎﺩﺓ. ﺃﻣﺎ‬ ‫ﺃ‬ ‫)‪.(PC Speaker‬‬ ‫ﺍﻟﻌﺪﺍﺩ ﺍﻷﺧﲑ ﻓﻴﺴﺘﺨﺪﻡ ﰲ ﻋﻤﻠﻴﺔ ﺇﺭﺳﺎﻝ ﺍﻟﺼﻮﺕ ﺍﱃ ﲰﺎﻋﺎﺕ ﺍﳊﺎﺳﺐ ٧‬ ‫٧ﻻ ‪‬ﻘﺼﺪ ‪‬ﺬﻩ ﻛﺮﺕ ﺍﻟﺼﻮﺕ ﻭﺇﳕﺎ ﻳﻮﺟﺪ ﰲ ﻛﻞ ﺣﺎﺳﺐ ﲰﺎﻋﺎﺕ ﺩﺍﺧﻠﻴﺔ ﺗﺴﺘﺨﺪﻡ ﰲ ﺇﺻﺪﺍﺭ ﺍﻟﺼﻮﺕ ﻭﺍﻟﻨﻐﻤﺎﺕ ﻭﺃﺣﺪ ﺍﺳﺘﺨﺪﺍﻣﺎ‪‬ﺎ‬ ‫ﻳ‬ ‫ﻹﺻﺪﺍﺭ ﺭﺳﺎﺋﻞ ﺍﳋﻄﺄ ﺑﻌﺪ ﻋﻤﻠﻴﺔ ﻓﺤﺺ ﺍﳊﺎﺳﺐ )‪ (POST‬ﰲ ﻣﺮﺣﻠﺔ ﺍﻹﻗﻼﻉ.‬‫١٤١‬
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ ‫3528‬ ‫ﺷﻜﻞ ٦.٣.: ﺍﳌﺆﻗﺘﺔ ﺍﻟﻘﺎﺑﻠﺔ ﻟﻠﱪﳎﺔ‬ ‫‪PIT‬‬ ‫٦.٣.١. ﺑﺮﳎﺔ ﺍﳌﺆﻗﺘﺔ‬‫ﻣﺆﺧﺮﺍ ﰎ ﻧﻘﻞ ﺍﳌﺆﻗﺘﺔ ﻣﻦ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ )‪ (MotherBoard‬ﻛﺸﺮﳛﺔ ‪ DIP‬ﻣﺴﺘﻠﻘﺔ ﺍﱃ ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ )‪.(SouthBridge‬‬‫ﻭﺳﻮﻑ ﻧﺮﻛﺰ ﻋﻠﻰ ﺑﺮﳎﺔ ﺍﻟﻌﺪﺍﺩ ﺍﻷﻭﻝ ﻭﻫﻮ ﻣﺆﻗﺖ ﺍﻟﻨﻈﺎﻡ ﺣﻴﺚ ﺃﻧﻪ ﻳﻮﻓﺮ ﺍﻟﺪﻋﻢ ﺍﻟﻌﺘﺎﺩﻱ ﺍﻟﻼﺯﻡ ﻟﻠﻨﻈﺎﻡ ﺣﱴ‬ ‫ﻳﺪﻋﻢ ﺗﻌﺪﺩ ﺍﻟﻌﻤﻠﻴﺎﺕ ﻭﺍﳌﺴﺎﻟﻚ.‬ ‫‪PITs Pins‬‬ ‫ﻣﺸﺎﺑﻚ ﺍﳌﺆﻗﺘﺔ‬ ‫‪‬ﺮﺳَﻞ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﱃ ﺍﳌﺆﻗﺘﺔ ﻭﺫﻟﻚ ﻋﱪ ﻣﺴﺎﺭ‬ ‫ﺗ‬ ‫ﺍﻟﺒﻴﺎﻧﺎﺕ )‪ (Data Bus‬ﺣﻴﺚ ﻳﺮﺗﺒﻂ ﻫﺬﺍ ﺍﳌﺴﺎﺭ ﻣﻊ‬ ‫ﻣﺸﺎﺑﻚ ﺍﻟﺒﻴﺎﻧﺎﺕ ﰲ ﺍﳌﺆﻗﺘﺔ ﻭﻫﻲ ٨ ﻣﺸﺎﺑﻚ 7‪D0...D‬‬ ‫ﻭُﻤﺜﻞ ٨ ﺑﺘﺎﺕ. ﻭﻋﻨﺪ ﺇﺭﺳﺎﻝ ﺑﻴﺎﻧﺎﺕ ﺍﱃ ﺍﳌﺆﻗﺘﺔ‬ ‫ﺗ‬ ‫)ﻋﻤﻠﻴﺔ ﻛﺘﺎﺑﺔ( ﻓﺎﻥ ﻣﺸﺒﻚ ﺍﻟﻜﺘﺎﺑﺔ ‪ WR‬ﻳﺄﺧﺬ ﻗﻴﻤﺔ‬ ‫ﻣﻨﺨﻔﻀﺔ ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﻨﺎﻙ ﻋﻤﻠﻴﺔ ﺇﺭﺳﺎﻝ ﺑﻴﺎﻧﺎﺕ‬ ‫ﺍﱃ ﺍﳌﺆﻗﺘﺔ ﻭﻛﺬﻟﻚ ﰲ ﺣﺎﻟﺔ ﻗﺮﺍءﺓ ﺑﻴﺎﻧﺎﺕ ﻣﻦ ﺍﳌﺆﻗﺘﺔ‬ ‫ﻓﺈﻥ ﻣﺸﺒﻚ ﺍﻟﻘﺮﺍءﺓ ‪ RD‬ﻳﺄﺧﺬ ﻗﻴﻤﺔ ﻣﻨﺨﻔﻀﺔ ﺩﻻﻟﺔ‬ ‫ﺷﻜﻞ ٦.٤.: ﻣﺸﺎﺑﻚ ﺍﳌﺆﻗﺘﺔ ‪PIT‬‬ ‫ﻋﻠﻰ ﺃﻥ ﻫﻨﺎﻙ ﻋﻤﻠﻴﺔ ﻗﺮﺍءﺓ ﻣﻦ ﺍﳌﺆﻗﺘﺔ. ﻭﻳﺘﺤﻜﻢ ﰲ‬ ‫ﻣﺸﺒﻚ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻣﺸﺒﻚ ‪ CS‬ﺣﻴﺚ ﲢﺪﺩ ﻗﻴﻤﺘﻪ‬‫ﺗﻌﻄﻴﻞ ﺃﻭ ﺗﻔﻌﻴﻞ ﻋﻤﻞ ﺍﻟﺸﺒﻜﲔ ﺍﻟﺴﺎﺑﻘﲔ ، ﻭﻳﺮﺗﺒﻂ ﻣﺸﺒﻚ ‪ CS‬ﻣﻊ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ )‪ (Address Bus‬ﺑﻴﻨﻤﺎ ﻳﺮﺗﺒﻂ‬‫ﻣﺸﺒﻚ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻣﻊ ﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ )‪ .(Control Bus‬ﻭُﺤﺪﺩ ﻗﻴﻤﺔ ﺍﳌﺸﺒﻜﲔ 1‪- A0,A‬ﻭﺍﻟﻠﺬﺍﻥ ﻳﺮﺗﺒﻄﺎﻥ‬ ‫ﺗ‬‫ﻣﻊ ﻣﺴﺎﺭ ﺍﻟﻌﻨﻮﺍﻳﻦ- ﺍﳌﺴﺠﻼﺕ ﺍﳌﻄﻠﻮﺏ ﺍﻟﻮﺻﻮﻝ ﺍﻟﻴﻬﺎ ﺩﺍﺧﻞ ﺍﳌﺆﻗﺘﺔ. ﺃﻣﺎ ﺍﳌﺸﺎﺑﻚ )‪(CLK, OUT, and GATE‬‬‫ﻓﻬﻲ ﻟﻜﻞ ﻋﺪﺍﺩ ﺑﺪﺍﺧﻞ ﺍﳌﺆﻗﺘﺔ ﺃﻱ ﲟﻌﲎ ﺃﻧﻪ ﺗﻮﺟﺪ ﺛﻼﺙ ﻣﺸﺎﺑﻚ ﻣﻦ ﻛﻞ ﻭﺍﺣﺪﺓ ﻣﻨﻬﻢ ، ﻭﻳﻌﺘﱪ ﺍﳌﺸﺒﻜﲔ‬‫)‪ (CLK (Clock Input) and GATE‬ﻣﺸﺎﺑﻚ ﺇﺩﺧﺎﻝ ﻟﻠﻌﺪﺍﺩ ﺑﻴﻨﻤﺎ ﺍﳌﺸﺒﻚ )‪ (OUT‬ﻣﺸﺒﻚ ﺇﺧﺮﺍﺝ ﺣﻴﺚ ﻳﺴﺘﺨﺪﻡ‬‫ﻟﺮﺑﻂ ﺍﻟﻌﺪﺍﺩ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﻓﻤﺜﻼ ﻣﺸﺒﻚ ﺍﻹﺧﺮﺍﺝ ﰲ ﺍﻟﻌﺪﺍﺩ ﺍﻷﻭﻝ )ﻣﺆﻗﺘﺔ ﺍﻟﻨﻈﺎﻡ( ﻳﺮﺗﺒﻂ ﻣﻊ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺣﻴﺚ‬‫ﻣﻦ ﺧﻼﻟﻪ ﺗﺴﺘﻄﻴﻊ ﻣﺆﻗﺘﺔ ﺍﻟﻨﻈﺎﻡ ﺇﺭﺳﺎﻝ ﻃﻠﺐ ﺍﳌﻘﺎﻃﻌﺔ )0‪ (IRQ‬ﺍﱃ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻭﺍﻟﺬﻱ ﻳﻘﻮﻡ ﺑﺘﺤﻮﻳﻞ ﺍﻟﻄﻠﺐ‬ ‫ﺍﱃ ﺍﳌﻌﺎﰿ ﻟﻜﻲ ﻳﻨﻔﺬ ﺩﺍﻟﺔ ﺍﻟﺘﺨﺪﱘ.‬ ‫٢٤١‬
    • ‫‪Programmable Interval Timer‬‬ ‫٦.٣. ﺍﳌﺆﻗﺘﺔ‬ ‫‪PIT‬‬ ‫ﻣﺴﺠﻼﺕ ﺍﳌﺆﻗﺘﺔ‬‫ﺗﻮﺟﺪ ٤ ﻣﺴﺠﻼﺕ ﺑﺪﺍﺧﻞ ﺍﳌﺆﻗﺘﺔ ‪ ، PIT‬ﺛﻼﺙ ﻣﻨﻬﺎ ﺗﺴﺘﺨﺪﻡ ﻟﻠﻌﺪﺍﺩﺍﺕ )ﺍﻷﻭﻝ ﻭﺍﻟﺜﺎﱐ ﻭﺍﻟﺜﺎﻟﺚ( ﺣﻴﺚ ﻣﻦ‬‫ﺧﻼﳍﺎ ﳝﻜﻦ ﻗﺮﺍءﺓ ﻗﻴﻤﺔ ﺍﻟﻌﺪﺍﺩ ﺃﻭ ﺍﻟﻜﺘﺎﺑﺔ ﻓﻴﻪ ، ﻭﻃﻮﻝ ﻣﺴﺠﻞ ﺍﻟﻌﺪﺍﺩ ﻫﻮ ٦١ ﺑﺖ . ﻭﺑﺴﺒﺐ ﺃﻥ ﻣﺸﺎﺑﻚ‬‫ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﱵ ﺗﺮﺑﻂ ﺍﳌﺆﻗﺘﺔ ﻭﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻫﻲ ﻣﻦ ﺍﻟﻄﻮﻝ ٨ ﺑﺖ ﻓﺎﻧﻪ ﻟﻦ ﻧﺘﻤﻜﻦ ﻣﻦ ﺇﺭﺳﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ‪‬ﺬ ﺍﻟﺸﻜﻞ‬‫. ﻟﺬﻟﻚ ﳚﺐ ﺇﺳﺘﺨﺪﺍﻡ ﻣﺴﺠﻞ ﺍﺧﺮ ﻭﻫﻮ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ )‪ (Control Word‬ﲝﻴﺚ ﻗﺒﻞ ﺇﺭﺳﺎﻝ ﺑﻴﺎﻧﺎﺕ ﺃﻭ ﻗﺮﺍءﺓ‬‫ﺑﻴﺎﻧﺎﺕ ﻣﻦ ﺃﻱ ﻋﺪﺍﺩ ﻓﺎﻧﻪ ﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﳌﻄﻠﻮﺏ ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺘﻢ ﺇﺭﺳﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺃﻭ‬‫ﻗﺮﺍﺋﺘﻬﺎ. ﻭﺍﳉﺪﻭﻝ ٦.٢١ ﻳﻮﺿﺢ ﻫﺬﺍ ﺍﳌﺴﺠﻼﺕ ﻭﻋﻨﻮﺍﻥ ﻣﻨﺎﻓﺬ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﺍﳌﺴﺘﺨﺪﻣﺔ ﻟﻠﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ‬‫، ﻭﳚﺐ ﻣﻼﺣﻈﺔ ﻗﻴﻢ ﺧﻂ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻭﺧﻂ ﺍﻟﻌﻨﻮﺍﻥ )1‪ (A0,A‬ﺣﻴﺚ ﺗﺆﺛﺮ ﻗﻴﻤﻬﻢ ﰲ ﲢﺪﻳﺪ ﻧﻮﻉ ﺍﻟﻌﻤﻠﻴﺔ‬‫ﺍﳌﻄﻠﻮﺑﺔ )ﻗﺮﺍءﺓ ﺃﻡ ﻛﺘﺎﺑﺔ ﻭﺭﻗﻢ ﺍﻟﻌﺪﺍﺩ(. ﻭﺗﻮﺿﺢ ﺍﻟﺘﺮﻛﻴﺒﺔ ﺍﻟﺘﺎﻟﻴﺔ ﻣﺎﻫﻴﺔ ﺍﻟﺒﺘﺎﺕ ﺍﳌﺴﺘﺨﺪﻣﺔ ﰲ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ‬ ‫ﺟﺪﻭﻝ ٦.٢١.: ﻣﺴﺠﻼﺕ ﺍﳌﺆﻗﺘﺔ ‪8253 PIT‬‬ ‫ﺍﻟﻮﻇﻴﻔﺔ‬ ‫ﺍﳌﻨﻔﺬ ﺧﻂ ‪ RD‬ﺧﻂ ‪ WR‬ﺧﻂ 0‪ A‬ﺧﻂ 1‪A‬‬ ‫ﺭﻗﻢ‬ ‫ﺍﺳﻢ ﺍﳌﺴﺠﻞ‬ ‫ﻛﺘﺎﺑﺔ ﺍﱃ ﺍﳌﺴﺠﻞ 0‬ ‫0‬ ‫0‬ ‫0‬ ‫1‬ ‫04‪0x‬‬ ‫0 ‪Counter‬‬ ‫ﻗﺮﺍءﺓ ﺍﳌﺴﺠﻞ 0‬ ‫0‬ ‫0‬ ‫1‬ ‫0‬ ‫ﻛﺘﺎﺑﺔ ﺍﱃ ﺍﳌﺴﺠﻞ 1‬ ‫1‬ ‫0‬ ‫0‬ ‫1‬ ‫14‪0x‬‬ ‫1 ‪Counter‬‬ ‫ﻗﺮﺍءﺓ ﺍﳌﺴﺠﻞ 1‬ ‫1‬ ‫0‬ ‫1‬ ‫0‬ ‫ﻛﺘﺎﺑﺔ ﺍﱃ ﺍﳌﺴﺠﻞ 2‬ ‫0‬ ‫1‬ ‫0‬ ‫1‬ ‫24‪0x‬‬ ‫2 ‪Counter‬‬ ‫ﻗﺮﺍءﺓ ﺍﳌﺴﺠﻞ 2‬ ‫0‬ ‫1‬ ‫1‬ ‫0‬ ‫ﻛﺘﺎﺑﺔ ‪Control Word‬‬ ‫1‬ ‫1‬ ‫0‬ ‫1‬ ‫34‪0x‬‬ ‫‪Control Word‬‬ ‫ﻻ ﺗﻮﺟﺪ ﻋﻤﻠﻴﺔ‬ ‫1‬ ‫1‬ ‫1‬ ‫0‬ ‫)ﻭﻫﻮ ﻣﺴﺠﻞ ﺑﻄﻮﻝ ٨ ﺑﺖ( ﺣﻴﺚ ﳚﺐ ﺇﺭﺳﺎﻝ ﻗﻴﻢ ﻣﻌﻴﻨﺔ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﻟﻘﺮﺍءﺓ ﺃﻭ ﺍﻟﻜﺘﺎﺑﺔ ﰲ ﻋﺪﺍﺩ ﻣﺎ.‬ ‫‪• Bit 0: (BCP) Binary Counter‬‬ ‫‪– 0: Binary‬‬ ‫)‪– 1: Binary Coded Decimal (BCD‬‬ ‫.‪• Bit 1-3: (M0, M1, M2) Opera ng Mode. See above sec ons for a descrip on of each‬‬ ‫‪– 000: Mode 0: Interrupt or Terminal Count‬‬ ‫‪– 001: Mode 1: Programmable one-shot‬‬ ‫‪– 010: Mode 2: Rate Generator‬‬ ‫‪– 011: Mode 3: Square Wave Generator‬‬ ‫‪– 100: Mode 4: So ware Triggered Strobe‬‬ ‫‪– 101: Mode 5: Hardware Triggered Strobe‬‬ ‫‪– 110: Undefined; Dont use‬‬‫٣٤١‬
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬ – 111: Undefined; Dont use • Bits 4-5: (RL0, RL1) Read/Load Mode. We are going to read or send data to a counter register – 00: Counter value is latched into an internal control register at the me of the I/O write opera on. – 01: Read or Load Least Significant Byte (LSB) only – 10: Read or Load Most Significant Byte (MSB) only – 11: Read or Load LSB first then MSB • Bits 6-7: (SC0-SC1) Select Counter. See above sec ons for a descrip on of each. – 00: Counter 0 – 01: Counter 1 – 10: Counter 2 – 11: Illegal value(milliseconds ١٠ ‫001 )ﻛﻞ‬Hz ‫ﻭﺍﳌﺜﺎﻝ ٠١.٦ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺑﺮﳎﺔ ﻋﺪﺍﺩ ﻣﺆﻗﺖ ﺍﻟﻨﻈﺎﻡ ﻹﺭﺳﺎﻝ ﻃﻠﺐ ﻣﻘﺎﻃﻌﺔ ﻛﻞ‬ .‫، ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺇﺭﺳﺎﻝ ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ ﺃﻭﻻﹰ ﻭﻣﻦ ﰒ ﺇﺭﺳﺎﻝ ﺍﻟﻮﻗﺖ ﺍﳌﻄﻠﻮﺏ ﺍﱃ ﺍﻟﻌﺪﺍﺩ ﺍﳌﻄﻠﻮﺏ‬ Example ٦.١٠: PIT programming١ ; COUNT = input hz / frequency٢٣ mov dx, 1193180 / 100 ; 100hz, or 10 milliseconds٤٥ ; FIRST send the command word to the PIT. Sets binary counting,٦ ; Mode 3, Read or Load LSB first then MSB, Channel 0٧٨ mov al, 110110b٩ out 0x43, al١٠١١ ; Now we can write to channel 0. Because we set the "Load LSB first then MSB" bit, that is١٢ ; the way we send it١٣١٤ mov ax, dx١٥ out 0x40, al ;LSB١٦ xchg ah, al١٧ out 0x40, al ;MSB ١٤٤
    • ‫‪HAL‬‬ ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬ ‫‪HAL‬‬ ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬‫ﻃﺒﻘﺔ ‪ HAL‬ﺗﺒﻌﺪ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﻦ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﻭﺗﻌﻤﻞ ﻛﻮﺍﺟﻬﺔ ﺃﻭ ﻃﺒﻘﺔ ﻣﺎ ﺑﲔ ﺍﻟﻨﻮﺍﺓ ﻭﺍﻟﻌﺘﺎﺩ ، ﻭﻓﻴﻬﺎ‬‫ﳒﺪ ﺗﻌﺮﻳﻔﺎﺕ ﺍﻟﻌﺘﺎﺩ. ﻭﺳﻴﺘﻢ ﺇﺿﺎﻓﺔ ﺃﻭﺍﻣﺮ ﺑﺮﳎﺔ ﻣﺘﺤﻜﻢ ‪ PIC‬ﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺈﻋﺎﺩﺓ ﺗﻌﻴﲔ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺑﺪﺍﺧﻞ‬‫ﻫﺬﻩ ﺍﻟﻄﺒﻘﺔ ﻭﻛﺬﻟﻚ ﺳﻴﺘﻢ ﺇﺿﺎﻓﺔ ﺷﻔﺮﺓ ﺑﺮﳎﺔ ﺍﳌﺆﻗﺘﺔ ﻭ ﺍﻟﱵ ﲢﺪﺩ ﺍﻟﻮﻗﺖ ﺍﻟﻼﺯﻡ ﻟﻠﻤﺆﻗﺘﺔ ﻟﻜﻲ ﺗﻘﻮﻡ ﺑﺎﺭﺳﺎﻝ‬ ‫ﻃﻠﺐ ﺍﳌﻘﺎﻃﻌﺔ )0‪. (IRQ‬‬ ‫‪PIC‬‬ ‫٦.٤.١. ﺩﻋﻢ‬‫ﰲ ﺍﻟﻘﺴﻢ ٦.٢.٢ ﰎ ﻋﺮﺽ ﻣﺘﺤﻜﻢ ‪ PIC‬ﻭﻛﻴﻔﻴﺔ ﺑﺮﳎﺘﻪ ﺑﺎﻟﺘﻔﺼﻴﻞ ، ﻭﰲ ﻫﺬﺍ ﺍﻟﻘﺴﻢ ﺳﻴﺘﻢ ﺗﻄﺒﻴﻖ ﻣﺎ ﰎ ﻋﺮﺿﻪ‬‫ﻋﻠﻰ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ. ﻭﻳﻮﺟﺪ ﻣﻠﻔﲔ ﳌﺘﺤﻜﻢ ‪ PIC‬ﺍﻷﻭﻝ ﻫﻮ ﻣﻠﻒ ﺍﻟﺮﺃﺱ )‪ (hal/pic.h‬ﺍﻟﺬﻱ ﳛﻮﻱ ﺍﻹﻋﻼﻥ‬‫ﻋﻦ ﺍﻟﺪﻭﺍﻝ ﻭﻛﺬﻟﻚ ﺍﻟﺜﻮﺍﺑﺖ ﻭﺍﻟﺜﺎﱐ ﻫﻮ ﻣﻠﻒ ﺍﻟﺘﻄﺒﻴﻖ )‪ (hal/pic.cpp‬ﺍﻟﺬﻱ ﳛﻮﻱ ﻋﻠﻰ ﺗﻌﺮﻳﻒ ﺗﻠﻚ ﺍﻟﺪﻭﺍﻝ.‬‫ﻭﺍﳌﺜﺎﻝ ١١.٦ ﻳﻌﺮﺽ ﻣﻠﻒ ﺍﻟﺮﺃﺱ ﺍﻟﺬﻱ ﻳﻐﻠﻒ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻷﺭﻗﺎﻡ ﻭﺍﻟﻌﻨﺎﻭﻳﻦ ﰲ ﺻﻮﺭﺓ ﺛﻮﺍﺑﺖ )ﺑﺎﺳﺘﺨﺪﺍﻡ‬ ‫ﺍﳌﺎﻛﺮﻭ( ﲝﻴﺚ ﺗﺰﻳﺪ ﻣﻦ ﻣﻘﺮﻭﺋﻴﺔ ﻭﻭﺿﻮﺡ ﺍﻟﺸﻔﺮﺓ ٨.‬ ‫‪Example‬‬ ‫‪٦.١١: hal/pic.h: PIC Interface‬‬‫‪١ // PIC 1 Devices IRQ‬‬‫‪٢ #define I386 PIC IRQ TIMER‬‬ ‫0‬‫‪٣ #define I386 PIC IRQ KEYBOARD‬‬ ‫1‬‫2‪٤ #define I386 PIC IRQ SERIAL‬‬ ‫3‬‫1‪٥ #define I386 PIC IRQ SERIAL‬‬ ‫4‬‫2‪٦ #define I386 PIC IRQ PARALLEL‬‬ ‫5‬‫‪٧ #define I386 PIC IRQ DESKETTE‬‬ ‫6‬‫1‪٨ #define I386 PIC IRQ PARALLEL‬‬ ‫7‬‫٩‬‫‪١٠ // PIC 2 Devices IRQ‬‬‫‪١١ #define I386 PIC IRQ CMOSTIMER‬‬ ‫0‬‫‪١٢ #define I386 PIC IRQ CGARETRACE‬‬ ‫1‬‫‪١٣ #define I386 PIC IRQ AUXILIRY‬‬ ‫4‬‫‪١٤ #define I386 PIC IRQ FPU‬‬ ‫5‬‫‪١٥ #define I386 PIC IRQ HDC‬‬ ‫6‬‫٦١‬‫)2‪١٧ // Operation Commamd Word 2 (OCW‬‬‫1‪١٨ #define I386 PIC OCW2 MASK L‬‬ ‫1‬‫2‪١٩ #define I386 PIC OCW2 MASK L‬‬ ‫2‬‫3‪٢٠ #define I386 PIC OCW2 MASK L‬‬ ‫4‬ ‫٨ﺇﺭﺟﻊ ﺍﱃ ﺍﻟﻘﺴﻢ ٦.٢.٢ ﳌﻌﺮﻓﺔ ﻭﻇﻴﻔﺔ ﻫﺬﻩ ﺍﻟﻘﻴﻢ ﺍﻟﺜﺎﺑﺘﺔ.‬‫٥٤١‬
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٢١ #define I386 PIC OCW2 MASK EOI 0x20٢٢ #define I386 PIC OCW2 MASK SL 0x40٢٣ #define I386 PIC OCW2 MASK ROTATE 0x80٢٤٢٥٢٦ // Operation Commamd Word 3 (OCW3)٢٧ #define I386 PIC OCW3 MASK RIS 1٢٨ #define I386 PIC OCW3 MASK RIR 2٢٩ #define I386 PIC OCW3 MASK MODE 4٣٠ #define I386 PIC OCW3 MASK SMM 0x20٣١ #define I386 PIC OCW3 MASK ESMM 0x40٣٢ #define I386 PIC OCW3 MASK D7 0x80٣٣٣٤٣٥ // PIC 1 port address٣٦ #define I386 PIC1 COMMAND REG 0x20٣٧ #define I386 PIC1 STATUS REG 0x20٣٨ #define I386 PIC1 IMR REG 0x21٣٩ #define I386 PIC1 DATA REG 0x21٤٠٤١٤٢ // PIC 2 port address٤٣ #define I386 PIC2 COMMAND REG 0xa0٤٤ #define I386 PIC2 STATUS REG 0xa0٤٥ #define I386 PIC2 IMR REG 0xa1٤٦ #define I386 PIC2 DATA REG 0xa1٤٧٤٨ // Initializing Commamd Word 1 (ICW1) Mask٤٩ #define I386 PIC ICW1 MASK IC4 0x1٥٠ #define I386 PIC ICW1 MASK SNGL 0x2٥١ #define I386 PIC ICW1 MASK ADI 0x4٥٢ #define I386 PIC ICW1 MASK LTIM 0x8٥٣ #define I386 PIC ICW1 MASK INIT 0x10٥٤٥٥٥٦ // Initializing Commamd Word 4 (ICW4) Mask٥٧ #define I386 PIC ICW4 MASK UPM 0x1٥٨ #define I386 PIC ICW4 MASK AEOI 0x2٥٩ #define I386 PIC ICW4 MASK MS 0x4٦٠ #define I386 PIC ICW4 MASK BUF 0x8٦١ #define I386 PIC ICW4 MASK SFNM 0x10 ١٤٦
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬٦٢٦٣٦٤ // Initializing command 1 control bits٦٥ #define I386 PIC ICW1 IC4 EXPECT 1٦٦ #define I386 PIC ICW1 IC4 NO 0٦٧ #define I386 PIC ICW1 SNGL YES 2٦٨ #define I386 PIC ICW1 SNGL NO 0٦٩ #define I386 PIC ICW1 ADI CALLINTERVAL4 4٧٠ #define I386 PIC ICW1 ADI CALLINTERVAL8 0٧١ #define I386 PIC ICW1 LTIM LEVELTRIGGERED 8٧٢ #define I386 PIC ICW1 LTIM EDGETRIGGERED 0٧٣ #define I386 PIC ICW1 INIT YES 0x10٧٤ #define I386 PIC ICW1 INIT NO 0٧٥٧٦ // Initializing command 4 control bits٧٧ #define I386 PIC ICW4 UPM 86MODE 1٧٨ #define I386 PIC ICW4 UPM MCSMODE 0٧٩ #define I386 PIC ICW4 AEOI AUTOEOI 2٨٠ #define I386 PIC ICW4 AEOI NOAUTOEOI 0٨١ #define I386 PIC ICW4 MS BUFFERMASTER 4٨٢ #define I386 PIC ICW4 MS BUFFERSLAVE 0٨٣ #define I386 PIC ICW4 BUF MODEYES 8٨٤ #define I386 PIC ICW4 BUF MODENO 0٨٥ #define I386 PIC ICW4 SFNM NESTEDMODE 0x10٨٦ #define I386 PIC ICW4 SFNM NOTNESTED 0٨٧٨٨٨٩ extern uint8 t i386 pic read data(uint8 t pic num);٩٠ extern void i386 pic send data(uint8 t data,uint8 t pic num);٩١ extern void i386 pic send command(uint8 t cmd,uint8 t pic num);٩٢ extern void i386 pic init(uint8 t base0,uint8 t base1);‫ﻭﲢﻮﻱ ﺍﻟﻮﺍﺟﻬﺔ ٤ ﺩﻭﺍﻝ ﻣﻨﻬﺎ ﺩﺍﻟﺘﺎﻥ ﻟﻠﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻣﻦ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺩﺍﻟﺔ ﻹﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﱃ ﻣﺴﺠﻞ‬‫ﺍﻟﺘﺤﻜﻢ ﻭﺍﻟﺪﺍﻟﺔ ﺍﻷﺧﲑﺓ ﻫﻲ ﻟﺘﻬﺌﻴﺔ ﺍﳌﺘﺤﻜﻢ ﻭﻫﻲ ﺍﻟﺪﺍﻟﺔ ﺍﻟﱵ ﳚﺐ ﺍﺳﺘﺪﻋﺎﺋﻬﺎ. ﻭﺍﳌﺜﺎﻝ ٢١.٦ ﻳﻮﺿﺢ ﺗﻌﺮﻳﻒ‬ .‫ﻫﺬﻩ ﺍﻟﺪﻭﺍﻝ‬ Example ٦.١٢: hal/pic.cpp: PIC Implementa on١ uint8 t i386 pic read data(uint8 t pic num) {٢ if (pic num > 1)٣ return 0;١٤٧
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٤٥ uint8 t reg = (pic num == 1)?I386 PIC2 DATA REG:I386 PIC1 DATA REG;٦ return inportb(reg);٧ }٨٩ void i386 pic send data(uint8 t data,uint8 t pic num) {١٠ if (pic num > 1)١١ return;١٢١٣ uint8 t reg = (pic num == 1)?I386 PIC2 DATA REG:I386 PIC1 DATA REG;١٤ outportb(reg,data);١٥ }١٦١٧ void i386 pic send command(uint8 t cmd,uint8 t pic num) {١٨١٩ if (pic num > 1)٢٠ return;٢١٢٢ uint8 t reg = (pic num == 1)?I386 PIC2 COMMAND REG: I386 PIC1 COMMAND REG;٢٣ outportb(reg,cmd);٢٤ }٢٥٢٦٢٧٢٨ void i386 pic init(uint8 t base0,uint8 t base1) {٢٩٣٠ uint8 t icw = 0;٣١٣٢ disable irq(); /∗ disable hardware interrupt (cli) ∗/٣٣٣٤ /∗ init PIC, send ICW1 ∗/٣٥ icw = (icw & ˜ I386 PIC ICW1 MASK INIT) | I386 PIC ICW1 INIT YES;٣٦ icw = (icw & ˜ I386 PIC ICW1 MASK IC4) | I386 PIC ICW1 IC4 EXPECT;٣٧ /∗ icw = 0x11 ∗/٣٨٣٩ i386 pic send command(icw,0);٤٠ i386 pic send command(icw,1);٤١٤٢ /∗ ICW2 : remapping irq ∗/٤٣ i386 pic send data(base0,0); ١٤٨
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬٤٤ i386 pic send data(base1,1);٤٥٤٦ /∗ ICW3 : irq for master/slave pic∗/٤٧ i386 pic send data(0x4,0);٤٨ i386 pic send data(0x2,1);٤٩٥٠ /∗ ICW4: enable i386 mode. ∗/٥١ icw = (icw & ˜ I386 PIC ICW4 MASK UPM) | I386 PIC ICW4 UPM 86MODE ; /∗ icw = 1 ∗/٥٢ i386 pic send data(icw,0);٥٣ i386 pic send data(icw,1);٥٤٥٥ } PIT ‫٦.٤.٢. ﺩﻋﻢ‬ Example ٦.١٣: hal/pit.h: PIt Interface١ #define I386 PIT COUNTER0 REG 0x40٢ #define I386 PIT COUNTER1 REG 0x41٣ #define I386 PIT COUNTER2 REG 0x42٤ #define I386 PIT COMMAND REG 0x43٥٦ #define I386 PIT OCW MASK BINCOUNT 0x1٧ #define I386 PIT OCW MASK MODE 0xe٨ #define I386 PIT OCW MASK RL 0x30٩ #define I386 PIT OCW MASK COUNTER 0xc0١٠١١١٢ #define I386 PIT OCW BINCOUNT BINARY 0x0١٣ #define I386 PIT OCW BINCOUNT BCD 0x1١٤١٥ #define I386 PIT OCW MODE TERMINALCOUNT 0x0١٦ #define I386 PIT OCW MODE ONESHOT 0x2١٧ #define I386 PIT OCW MODE RATEGEN 0x4١٨ #define I386 PIT OCW MODE SQUAREWAVEGEN 0x6١٩ #define I386 PIT OCW MODE SOFTWARETRIG 0x8٢٠ #define I386 PIT OCW MODE HARDWARETRIG 0xa٢١١٤٩
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٢٢ #define I386 PIT OCW RL LATCH 0x0٢٣ #define I386 PIT OCW RL LSBONLY 0x10٢٤ #define I386 PIT OCW RL MSBONLY 0x20٢٥ #define I386 PIT OCW RL DATA 0x30٢٦٢٧ #define I386 PIT OCW COUNTER 0 0x0٢٨ #define I386 PIT OCW COUNTER 1 0x40٢٩ #define I386 PIT OCW COUNTER 2 0x80٣٠٣١ extern void i386 pit send command(uint8 t cmd);٣٢ extern void i386 pit send data(uint16 t data,uint8 t counter);٣٣ extern uint8 t i386 pit read data(uint16 t counter);٣٤ extern uint32 t i386 pit set tick count(uint32 t i);٣٥ extern uint32 t i386 pit get tick count();٣٦ extern void i386 pit start counter(uint32 t freq,uint8 t counter, uint8 t mode);٣٧ extern void cdecl i386 pit init();٣٨ extern bool cdecl i386 pit is initialized(); Example ٦.١٤: hal/pit.cpp: PIT Implementa on١ static volatile uint32 t pit ticks = 0;٢ static bool pit is init = false;٣٤ void cdecl i386 pit irq();٥٦ void i386 pit send command(uint8 t cmd) {٧ outportb(I386 PIT COMMAND REG,cmd);٨ }٩١٠ void i386 pit send data(uint16 t data,uint8 t counter) {١١ uint8 t port;١٢١٣ if (counter == I386 PIT OCW COUNTER 0)١٤ port = I386 PIT COUNTER0 REG;١٥ else if ( counter == I386 PIT OCW COUNTER 1)١٦ port = I386 PIT COUNTER1 REG;١٧ else١٨ port = I386 PIT COUNTER2 REG;١٩ ١٥٠
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬٢٠ outportb(port,uint8 t(data));٢١ }٢٢٢٣ uint8 t i386 pit read data(uint16 t counter) {٢٤ uint8 t port;٢٥٢٦ if (counter == I386 PIT OCW COUNTER 0)٢٧ port = I386 PIT COUNTER0 REG;٢٨ else if ( counter == I386 PIT OCW COUNTER 1)٢٩ port = I386 PIT COUNTER1 REG;٣٠ else٣١ port = I386 PIT COUNTER2 REG;٣٢٣٣ return inportb(port);٣٤ }٣٥٣٦ uint32 t i386 pit set tick count(uint32 t i) {٣٧ uint32 t prev = pit ticks;٣٨ pit ticks = i;٣٩ return prev;٤٠ }٤١٤٢ uint32 t i386 pit get tick count() {٤٣ return pit ticks;٤٤ }٤٥٤٦ void i386 pit start counter(uint32 t freq,uint8 t counter,uint8 t mode) {٤٧ if (freq == 0)٤٨ return;٤٩٥٠ uint16 t divisor = uint16 t(1193181/uint16 t(freq));٥١٥٢ /∗ send operation command ∗/٥٣ uint8 t ocw = 0;٥٤٥٥ ocw = (ocw & ˜ I386 PIT OCW MASK MODE) | mode;٥٦ ocw = (ocw & ˜ I386 PIT OCW MASK RL) | I386 PIT OCW RL DATA;٥٧ ocw = (ocw & ˜ I386 PIT OCW MASK COUNTER) | counter;٥٨٥٩ i386 pit send command(ocw);١٥١
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٦٠٦١ /∗ set frequency rate ∗/٦٢ i386 pit send data(divisor & 0xff,0);٦٣ i386 pit send data((divisor >> 8) & 0xff,0);٦٤٦٥ /∗ reset ticks count ∗/٦٦ pit ticks = 0;٦٧ }٦٨٦٩ void cdecl i386 pit init() {٧٠ set vector(32,i386 pit irq);٧١ pit is init = true;٧٢ }٧٣٧٤ bool cdecl i386 pit is initialized() {٧٥ return pit is init;٧٦ }٧٧٧٨ void cdecl i386 pit irq() {٧٩٨٠ asm {٨١ add esp,12٨٢ pushad٨٣ }٨٤٨٥ pit ticks++;٨٦٨٧ int done(0);٨٨٨٩ asm {٩٠ popad٩١ iretd٩٢ }٩٣ } ‫ ﺍﳉﺪﻳﺪﺓ‬HAL ‫٦.٤.٣. ﻭﺍﺟﻬﺔ‬ HAL ‫ﺍﳌﺜﺎﻝ ٥١.٦ ﻳﻮﺿﺢ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﻌﺎﻣﺔ ﻟﻄﺒﻘﺔ‬ Example ٦.١٥: New HAL Interface ١٥٢
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬١ extern int cdecl hal init();٢ extern int cdecl hal close();٣ extern void cdecl gen interrupt(int);٤ extern void cdecl int done(unsigned int n);٥ extern void cdecl sound(unsigned int f);٦ extern unsigned char cdecl inportb(unsigned short port num);٧ extern void cdecl outportb(unsigned short port num,unsigned char value);٨ extern void cdecl enable irq();٩ extern void cdecl disable irq();١٠ extern void cdecl set vector(unsigned int int num,void ( cdecl far & vect)());١١ extern void ( cdecl far ∗ cdecl get vector(unsigned int int num))();١٢ extern const char∗ cdecl get cpu vendor();١٣ extern int cdecl get tick count(); Example ٦.١٦: New HAL Impelmenta on١ int cdecl hal init() {٢ i386 cpu init();٣ i386 pic init(0x20,0x28);٤ i386 pit init();٥ i386 pit start counter(100,I386 PIT OCW COUNTER 0, I386 PIT OCW MODE SQUAREWAVEGEN);٦٧ /∗ enable irq ∗/٨ enable irq();٩١٠ return 0;١١ }١٢١٣ int cdecl hal close() {١٤ i386 cpu close();١٥ return 0;١٦ }١٧١٨ void cdecl gen interrupt(int n) {١٩ #ifdef MSC VER٢٠ asm {٢١ mov al, byte ptr [n]١٥٣
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٢٢ mov byte ptr [address+1], al٢٣ jmp address٢٤٢٥ address:٢٦ int 0 // will execute int n.٢٧ }٢٨ #endif٢٩ }٣٠٣١٣٢ void cdecl int done(unsigned int n) {٣٣ if (n > 16)٣٤ return;٣٥٣٦ if (n > 7)٣٧ /∗ send EOI to pic2 ∗/٣٨ i386 pic send command(I386 PIC OCW2 MASK EOI,1);٣٩٤٠ /∗ also send toi the primary pic ∗/٤١ i386 pic send command(I386 PIC OCW2 MASK EOI,0);٤٢ }٤٣٤٤ void cdecl sound(unsigned int f) {٤٥ outportb(0x61,3 | unsigned char(f << 2));٤٦ }٤٧٤٨ unsigned char cdecl inportb(unsigned short port num) {٤٩ #ifdef MSC VER٥٠ asm {٥١ mov dx,word ptr [port num]٥٢ in al,dx٥٣ mov byte ptr [port num],al٥٤ }٥٥ #endif٥٦٥٧ return unsigned char(port num);٥٨ }٥٩٦٠٦١ void cdecl outportb(unsigned short port num,unsigned char value) {٦٢ #ifdef MSC VER ١٥٤
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬ ٦٣ asm { ٦٤ mov al,byte ptr[value] ٦٥ mov dx,word ptr[port num] ٦٦ out dx,al ٦٧ } ٦٨ #endif ٦٩ } ٧٠ ٧١ void cdecl enable irq() { ٧٢ #ifdef MSC VER ٧٣ asm sti ٧٤ #endif ٧٥ } ٧٦ ٧٧ void cdecl disable irq() { ٧٨ #ifdef MSC VER ٧٩ asm cli ٨٠ #endif ٨١ } ٨٢ ٨٣ void cdecl set vector(unsigned int int num,void ( cdecl far & vect) ()) { ٨٤ i386 idt install ir(int num,I386 IDT 32BIT | I386 IDT PRESENT /∗ 10001110∗/,0x8 /∗code desc∗/,vect); ٨٥ } ٨٦ ٨٧ void ( cdecl far ∗ cdecl get vector(unsigned int int num))() { ٨٨ idt desc ∗ desc = i386 get idt ir(int num); ٨٩ ٩٠ if (desc == 0) ٩١ return 0; ٩٢ ٩٣ uint32 t address = desc− base low | (desc− base high << 16); > > ٩٤ ٩٥ I386 IRQ HANDLER irq = (I386 IRQ HANDLER) address; ٩٦ return irq; ٩٧ } ٩٨ ٩٩ const char∗ cdecl get cpu vendor() {١٠٠ return i386 cpu vendor();١٠١ } ١٥٥
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬١٠٢١٠٣ int cdecl get tick count() {١٠٤ return i386 pit get tick count();١٠٥ } Example ٦.١٧: kernel/main.cpp ١ int cdecl main() ٢ { ٣ hal init(); ٤ enable irq(); ٥ ٦ set vector(0,(void ( cdecl &)(void))divide by zero fault); ٧ set vector(1,(void ( cdecl &)(void))single step trap); ٨ set vector(2,(void ( cdecl &)(void))nmi trap); ٩ set vector(3,(void ( cdecl &)(void))breakpoint trap); ١٠ set vector(4,(void ( cdecl &)(void))overflow trap); ١١ set vector(5,(void ( cdecl &)(void))bounds check fault); ١٢ set vector(6,(void ( cdecl &)(void))invalid opcode fault); ١٣ set vector(7,(void ( cdecl &)(void))no device fault); ١٤ set vector(8,(void ( cdecl &)(void))double fault abort); ١٥ set vector(10,(void ( cdecl &)(void))invalid tss fault); ١٦ set vector(11,(void ( cdecl &)(void))no segment fault); ١٧ set vector(12,(void ( cdecl &)(void))stack fault); ١٨ set vector(13,(void ( cdecl &)(void))general protection fault); ١٩ set vector(14,(void ( cdecl &)(void))page fault); ٢٠ set vector(16,(void ( cdecl &)(void))fpu fault); ٢١ set vector(17,(void ( cdecl &)(void))alignment check fault); ٢٢ set vector(18,(void ( cdecl &)(void))machine check abort); ٢٣ set vector(19,(void ( cdecl &)(void))simd fpu fault); ٢٤ ٢٥ ... Example ٦.١٨: kernel/excep on.h ١ /∗ Execption Handler ∗/ ٢ ٣ /∗ Divide by zero ∗/ ٤ extern void cdecl divide by zero fault(uint32 t cs,uint32 t eip, uint32 t eflags); ١٥٦
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬٥٦ /∗ Single step ∗/٧ extern void cdecl single step trap(uint32 t cs,uint32 t eip,uint32 t eflags);٨٩ /∗ No Maskable interrupt trap ∗/١٠ extern void cdecl nmi trap(uint32 t cs,uint32 t eip,uint32 t eflags) ;١١١٢ /∗ Breakpoint hit ∗/١٣ extern void cdecl breakpoint trap(uint32 t cs,uint32 t eip,uint32 t eflags);١٤١٥ /∗ Overflow trap ∗/١٦ extern void cdecl overflow trap(uint32 t cs,uint32 t eip,uint32 t eflags);١٧١٨ /∗ Bounds check ∗/١٩ extern void cdecl bounds check fault(uint32 t cs,uint32 t eip, uint32 t eflags);٢٠٢١ /∗ invalid opcode instruction ∗/٢٢ extern void cdecl invalid opcode fault(uint32 t cs,uint32 t eip, uint32 t eflags);٢٣٢٤ /∗ Device not available ∗/٢٥ extern void cdecl no device fault(uint32 t cs,uint32 t eip,uint32 t eflags);٢٦٢٧ /∗ Double Fault ∗/٢٨ extern void cdecl double fault abort(uint32 t cs,uint32 t err, uint32 t eip,uint32 t eflags);٢٩٣٠ /∗ Invalid TSS ∗/٣١ extern void cdecl invalid tss fault(uint32 t cs,uint32 t err, uint32 t eip,uint32 t eflags);٣٢٣٣ /∗ Segment not present ∗/٣٤ extern void cdecl no segment fault(uint32 t cs,uint32 t err,uint32 t eip,uint32 t eflags);٣٥١٥٧
    • Interrupts ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬٣٦ /∗ Stack fault ∗/٣٧ extern void cdecl stack fault(uint32 t cs,uint32 t err,uint32 t eip, uint32 t eflags);٣٨٣٩ /∗ General Protection Fault ∗/٤٠ extern void cdecl general protection fault(uint32 t cs,uint32 t err, uint32 t eip,uint32 t eflags);٤١٤٢ /∗ Page Fault ∗/٤٣ extern void cdecl page fault(uint32 t cs,uint32 t err,uint32 t eip, uint32 t eflags);٤٤٤٥ /∗ FPU error ∗/٤٦ extern void cdecl fpu fault(uint32 t cs,uint32 t eip,uint32 t eflags );٤٧٤٨ /∗ Alignment Check ∗/٤٩ extern void cdecl alignment check fault(uint32 t cs,uint32 t err, uint32 t eip,uint32 t eflags);٥٠٥١ /∗ Machine Check ∗/٥٢ extern void cdecl machine check abort(uint32 t cs,uint32 t eip, uint32 t eflags);٥٣٥٤ /∗ FPU Single Instruction Multiple Data (SIMD) error ∗/٥٥ extern void cdecl simd fpu fault(uint32 t cs,uint32 t eip,uint32 t eflags); Example ٦.١٩: kernel/excep on.cpp١ /∗ Divide by zero ∗/٢ void cdecl divide by zero fault(uint32 t cs,uint32 t eip,uint32 t eflags) {٣ kernel panic("Divide by 0");٤ for (;;);٥ } Example ٦.٢٠: kernel/panic.cpp١ void cdecl kernel panic(const char∗ msg,...) { ١٥٨
    • HAL ‫٦.٤. ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬٢٣ disable irq();٤٥ va list args;٦ va start(args,msg);٧ /∗ missing ∗/٨ va end(args);٩١٠ char∗ panic = "nSorry, eqraOS has encountered a problem and has been shutdown.nn";١١١٢ kclear(0x1f);١٣ kgoto xy(0,0);١٤ kset color(0x1f);١٥ kputs(panic);١٦ kprintf(" ∗∗∗ STOP: %s",msg);١٧١٨ /∗ hang ∗/١٩ for (;;) ;٢٠ } HAL ‫ﺷﻜﻞ ٦.٥.: ﻭﺍﺟﻬﺔ ﺍﻟﻨﻈﺎﻡ ﺑﻌﺪ ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ‬١٥٩
    • ‫‪Interrupts‬‬ ‫٦. ﺍﳌﻘﺎﻃﻌﺎﺕ‬‫ﺷﻜﻞ ٦.٦.: ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻹﻓﺘﺮﺍﺿﻴﺔ‬ ‫٠٦١‬
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺗﻌﺘﱪ ﺫﺍﻛﺮﺓ ﺍﳊﺎﺳﺐ ﺍﻟﺮﺋﻴﺴﻴﺔ )‪ (RAM‬ﻣﻦ ﺃﻫﻢ ﺍﳌﻮﺍﺭﺩ ﺍﻟﱵ ﳚﺐ ﻋﻠﻰ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺇﺩﺍﺭ‪‬ﺎ ﺣﻴﺚ ﳝﺜﻞ ﺍﳌﺨﺰﻥ‬‫ﺍﻟﺬﻱ ﻳﻘﺮﺃ ﺍﳌﻌﺎﰿ ﻣﻨﻪ ﺍﻷﻭﺍﻣﺮ ﻭﻳﻘﻮﻡ ﺑﺘﻨﻔﻴﺬﻫﺎ ، ﻭﻻ ﳝﻜﻦ ﻟﻠﻤﻌﺎﰿ ﺍﻟﻮﺻﻮﻝ ﺍﳌﺒﺎﺷﺮ ﺍﱃ ﺃﺣﺪ ﺍﻟﺬﻭﺍﻛﺮ ﺍﻟﺜﺎﻧﻮﻳﺔ‬‫ﻣﺒﺎﺷﺮﺓ ﻭﺇﳕﺎ ﻳﺘﻢ ﲢﻤﻴﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﱪﺍﻣﺞ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﺣﱴ ﺗﺼﺒﺢ ﻣﺘﺎﺣﺔ ﻟﻠﻤﻌﺎﰿ. ﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ‬‫ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ )‪ (Memory Manager‬ﺣﻴﺚ ﻳﺮﺍﻗﺐ ﻫﺬﺍ ﺍﻟﱪﻧﺎﻣﺞ ﺃﺟﺰﺍء ﺍﻟﺬﺍﻛﺮﺓ ﻭﻳﺘﻌﺮﻑ ﻋﻠﻰ ﻣﺎ ﻫﻮ ﻣﺴﺘﺨﺪﻡ‬‫ﻭﻣﺎ ﻫﻮ ﻏﲑ ﻣﺴﺘﺨﺪﻡ ﻛﻤﺎ ﻳﻮﻓﺮ ﺩﻭﺍﻻ ﳊﺠﺰ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻭﲢﺮﻳﺮﻫﺎ ، ﻛﺬﻟﻚ ﻣﻦ ﺍﳌﻤﻜﻦ ﺃﻥ ﻳﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ‬‫ﺇﻋﺎﺩﺓ ﲡﺰﺋﺔ ﳌﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺫﻟﻚ ﻟﺘﻮﻓﲑ ﻣﺴﺎﺣﺔ ﻭﺍﺳﺘﻐﻼﻝ ﺃﻓﻀﻞ.ﻭﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﺳﻴﺘﻢ ﺩﺭﺍﺳﺔ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ ﻭﺍﻟﺘﺨﻴﻠﻴﺔ ﻭﻛﻴﻔﻴﺔ ﺑﺮﳎﺘﻬﻢ ﻛﺬﻟﻚ ﺳﻴﺘﻢ ﻋﺮﺽ ﺑﻌﺾ ﺍﻟﻄﺮﻕ ﳊﺴﺎﺏ ﺍﳌﺴﺎﺣﺔ ﺍﻟﻜﻠﻴﺔ ﻟﻠﺬﺍﻛﺮﺓ ﻭﻋﺮﺽ‬ ‫ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﳌﺴﺘﺨﺪﻣﺔ ﻣﻦ ﻗﺒﻞ ﺍﻟﻨﻈﺎﻡ.‬ ‫‪Physical Memory Management‬‬ ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬‫‪RAM‬‬ ‫ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ )‪ (Physical Memoery‬ﻫﻲ ﻛﺘﻠﺔ ﺫﺍﻛﺮﻳﺔ ﺗﻮﺟﺪ ﺑﺪﺍﺧﻞ ﺷﺮﳛﺔ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ‬‫ﻭﲣﺘﻠﻒ ﻃﺮﻳﻘﺔ ﺣﻔﻆ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻓﻴﻬﺎ ﲝﺴﺐ ﻧﻮﻉ ﺍﻟﺬﺍﻛﺮﺓ )ﻓﻤﺜﻼ ﺗﺴﺘﺨﺪﻡ ﺍﳌﻜﺜﻔﺎﺕ ﻭﺍﻟﺘﺮﺍﻧﺰﺳﺘﻮﺭﺍﺕ ﳊﻔﻆ‬‫ﺍﻟﺒﺘﺎﺕ ﰲ ﺫﺍﻛﺮﺓ ‪ ، (DRAM‬ﻭﻳﺘﻢ ﺍﻟﺘﺤﻜﻢ ﰲ ﻫﺬﻩ ﺍﻟﻜﺘﻠﺔ ﺑﻮﺍﺳﻄﺔ ﺷﺮﳛﺔ ﺩﺍﺧﻞ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ ﺗﺴﻤﻰ ﲟﺘﺤﻜﻢ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﺃﻭ ﺑﺎﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ )‪ (North Bridge‬ﺣﻴﺚ ﻳﻘﻮﻡ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﺑﻌﻤﻠﻴﺔ ﺇﻧﻌﺎﺵ ﺍﳌﻜﺜﻔﺎﺕ ﺑﺪﺍﺧﻞ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺣﱴ ﲢﺎﻓﻆ ﻋﻠﻰ ﳏﺘﻮﻳﺎ‪‬ﺎ ﻣﻦ ﺍﻟﻀﻴﺎﻉ ﻛﺬﻟﻚ ﻳﻌﻨﻮﻥ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ ﺑﺪﺍﻳﺔ ﻣﻦ ﺃﻭﻝ ٨ ﺑﺘﺎﺕ‬‫ﺣﻴﺚ ﺗﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ 0‪ 0x‬ﻭﻳﻠﻴﻬﺎ ﺍﻟﻌﻨﻮﺍﻥ 1‪ 0x‬ﻟﻠﺜﻤﺎﻧﻴﺔ ﺑﺘﺎﺕ ﺍﻟﺘﺎﻟﻴﺔ ، ﻭﻫﻜﺬﺍ ﺗﺘﻢ ﻋﻨﻮﻧﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻣﻦ‬‫ﻗﺒﻞ ﺍﳌﺘﺤﻜﻢ. ﻭﻋﻨﺪ ﻭﺻﻮﻝ ﻃﻠﺐ ﻗﺮﺍءﺓ ﺃﻭ ﻛﺘﺎﺑﺔ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻥ ﺍﳌﺘﺤﻜﻢ ﻳﻘﻮﻡ ﺑﻘﺮﺍءﺓ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻦ‬‫ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻭﺑﺎﻟﺘﺎﱄ ﻳﺘﻤﻜﻦ ﻣﻦ ﺗﻔﺴﲑ ﺍﻟﻌﻨﻮﺍﻥ ﻭﺗﻮﺟﻴﻬﻪ ﺍﱃ ﺍﳌﻜﺎﻥ ﺍﻟﺼﺤﻴﺢ ﺣﻴﺚ ﻏﺎﻟﺒﺎ ﻣﺎ ﺗﻮﺟﺪ ﺃﻛﺜﺮ ﻣﻦ‬‫ﺷﺮﳛﺔ ﺭﺍﻡ ﺑﺪﺍﺧﻞ ﺍﳊﺎﺳﺐ. ﻭﺗﺸﻜﻞ ﳎﻤﻮﻋﺔ ﻛﻞ ﺍﻟﻌﻨﺎﻭﻳﻦ ﰲ ﻛﻞ ﺷﺮﺍﺋﺢ ﺍﻟﺬﺍﻛﺮﺓ ﻣﺴﺎﺣﺔ ﻋﻨﺎﻭﻳﻦ ﻓﻴﺰﻳﺎﺋﻴﺔ‬‫)‪. (Physical Address Space‬ﻟﻜﻦ ﻗﺪ ﻳﻜﻮﻥ ﻫﻨﺎﻙ ﻋﺪﺩﺍ ﻣﻦ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ ﻓﻌﻠﻴﺎ ﻭﺫﻟﻚ ﰲ‬‫ﺣﺎﻟﺔ ﻭﺟﻮﺩ ﺷﺮﳛﺔ ﺫﺍﻛﺮﺓ ﰲ ﺍﳌﻨﻔﺬ ﺍﻷﻭﻝ ﻭﺍﻟﺜﺎﻟﺚ ﻭﻋﺪﻡ ﻭﺟﻮﺩ ﺷﺮﳛﺔ ﺫﺍﻛﺮﺓ ﰲ ﺍﳌﻨﻔﺬ ﺍﻟﺜﺎﱐ ﻭﰲ ﻫﺬﻩ ﺍﳊﺎﻟﺔ‬‫ﺍﺫﺍ ﻛﺎﻥ ﺣﺠﻢ ﻛﻞ ﺷﺮﳛﺔ ﺫﺍﻛﺮﺓ ﻫﻲ ‪ n‬ﻓﺎﻥ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻣﻦ 1-‪ n‬ﺍﱃ 1-‪ 2n‬ﻫﻲ ﻋﻨﺎﻭﻳﻦ ﻏﲑ ﻣﻮﺟﻮﺩﺓ ﺣﻘﻴﻘﺔ‬‫ﻭﺗﺴﻤﻰ ﻓﺘﺤﺎﺕ )‪ ، (Holes‬ﻭﻋﻤﻠﻴﺔ ﺍﻟﻜﺘﺎﺑﺔ ﰲ ﻫﺬﻩ ﺍﻟﻔﺘﺤﺎﺕ ﻻ ﺗﺆﺛﺮ ﺷﻲء ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ ﺑﻴﻨﻤﺎ ﻋﻨﺪ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ‬‫ﻫﺬﻩ ﺍﻟﻔﺘﺤﺎﺕ ﻓﺎﻥ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﻣﺴﺎﺭ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻫﻲ ﺍﻟﱵ ﻳﺘﻢ ﻗﺮﺍﺋﺘﻬﺎ ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃ‪‬ﺎ ﻏﲑ ﺻﺤﻴﺤﺔ.‬‫ﻭﻗﺒﻞ ﺍﳋﻮﺽ ﰲ ﺑﺮﳎﺔ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﳚﺐ ﺗﻮﻓﲑ ﻋﺪﺩﺍ ﻣﻦ ﺍﳌﻌﻠﻮﻣﺎﺕ ﻣﺜﻞ ﺟﺤﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻜﻠﻲ ﻭﻣﻨﺎﻃﻖ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺍﳌﺴﺘﺨﺪﻣﺔ ﻭﻏﲑ ﺍﳌﺴﺘﺨﺪﻣﺔ ﻭ ﺍﻟﻔﺘﺤﺎﺕ ﺍﳌﻮﺟﻮﺩﺓ ﺍﻥ ﻛﺎﻧﺖ ﻫﻨﺎﻙ ﻓﺘﺤﺎﺕ ، ﻭﻫﺬﺍ ﺣﱴ ﻳﺘﻤﻜﻦ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ‬ ‫ﻣﻦ ﺇﺩﺍﺭ‪‬ﺎ ﻋﻠﻰ ﺍﻟﻨﺤﻮ ﺍﳌﻄﻠﻮﺏ.‬‫١٦١‬
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬ ‫٧.١.١. ﺣﺴﺎﺏ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺗﻮﺟﺪ ﻋﺪﺓ ﻃﺮﻕ ﳊﺴﺎﺏ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺑﻌﻀﻬﺎ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ ﻭﺍﻷﺧﺮﻯ ﻻ ﺗﻌﺘﻤﺪ ، ﻭﰲ ﺑﺪﺍﻳﺔ ﺇﻗﻼﻉ‬‫ﺍﳊﺎﺳﺐ ﻳﻘﻮﻡ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﺑﺎﻟﺘﺨﺎﻃﺐ ﻣﻊ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺃﺧﺬ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻳﻘﻮﻡ ﲝﻔﻈﻬﺎ ﰲ ﺃﺣﺪ‬‫ﺍﻟﻌﻨﺎﻭﻳﻦ ﰲ ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﰲ ﺍﻟﺬﺍﻛﺮﺓ. ﻭﺗﻌﺘﱪ ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﻫﻲ ﺍﻷﻛﺜﺮ ﺩﻗﺔ ﰲ ﺍﳊﺼﻮﻝ ﻋﻠﻰ ﺣﺠﻢ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﻭﻟﻜﻦ ﺗﺒﻘﻰ ﻣﺸﻜﻠﺔ ﺃﻥ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﻻ ﳝﻜﻦ ﺍﺳﺘﺪﻋﺎﺋﻬﺎ ﺑﺪﺍﺧﻞ ﺍﻟﻨﻮﺍﺓ ﻭﺍﻟﱵ ﺗﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ‬‫ﺍﳌﺤﻤﻲ. ﻟﺬﻟﻚ ﺳﻴﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﻘﺎﻃﻌﺔ ﺍﳋﺎﺻﺔ ﲜﻠﺐ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻗﺒﻞ ﺃﻥ ﺗﺒﺪﺃ ﺍﻟﻨﻮﺍﺓ ﰲ ﻋﻤﻠﻬﺎ ﻭﲤﺮﻳﺮ ﻫﺬﺍ‬ ‫ﺍﳊﺠﻢ ﻣﻊ ﺑﻌﺾ ﺍﳌﻌﻠﻮﻣﺎﺕ ﺍﻻﺧﺮﻯ ﻭ ﺗﺴﻤﻰ ﻣﻌﻠﻮﻣﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ ﺍﱃ ﺍﻟﻨﻮﺍﺓ.‬ ‫21‪int 0x‬‬ ‫ﺍﳌﻘﺎﻃﻌﺔ‬‫ﺗﻘﻮﻡ ﻫﺬﺍ ﺍﳌﻘﺎﻃﻌﺔ ﲜﻠﺐ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻣﻦ ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ )ﺑﺎﻟﺘﺤﺪﻳﺪ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 314‪ (0x‬ﻟﻜﻨﻬﺎ ﻻ‬‫ﺗﺴﺘﺨﺪﻡ ﺣﺎﻟﻴﺎ ﻧﻈﺮﺍ ﻷ‪‬ﺎ ﲡﻠﺐ ﺣﺠﻢ ٤٦ ﻛﻴﻠﻮﺑﺎﻳﺖ ﻛﺤﺪ ﺃﻗﺼﻰ ﻭﺑﺎﻟﺘﺎﱄ ﺍﺫﺍ ﻛﺎﻧﺖ ﺍﻟﺬﺍﻛﺮﺓ ﻟﺪﻳﻚ ﺃﻛﱪ ﻣﻦ‬‫ﻫﺬﺍ ﺍﳊﺠﻢ ﻓﺎ‪‬ﺎ ﻻ ﲡﻠﺐ ﺍﳊﺠﻢ ﺍﻟﺼﺤﻴﺢ ، ﻟﺬﻟﻚ ﻻ ﺗﺴﺘﺨﺪﻡ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ ﺍﻻﻥ. ﻭﺍﳌﺜﺎﻝ ١.٧ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ‬ ‫ﺍﺳﺘﺨﺪﺍﻣﻬﺎ‬‫‪Example‬‬ ‫‪٧.١: Using int 0x12 to get size of memory‬‬‫١‬‫− − − − − − − − − − − − − − − − ; ٢‬ ‫−−−−−−−−−−−−−−−−−‬‫‪٣ ; get conventional memory size‬‬‫0 ‪٤ ; ret ax=KB size from address‬‬‫− − − − − − − − − − − − − − − − ; ٥‬ ‫−−−−−−−−−−−−−−−−‬‫:‪٦ get conventional memory size‬‬‫٧‬ ‫21‪int 0x‬‬‫٨‬ ‫‪ret‬‬ ‫108‪0xe‬‬ ‫ﺍﳌﻘﺎﻃﻌﺔ 51‪ 0x‬ﺍﻟﺪﺍﻟﺔ‬ ‫ﲡﻠﺐ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ ﺍﳊﺠﻢ ﺍﻟﺼﺤﻴﺢ ﻭﺗﺴﺘﺨﺪﻡ ﺩﺍﺋﻤﺎ ﳍﺬﺍ ﺍﻟﻐﺮﺽ ، ﻭﺗﻌﻮﺩ ﺑﺎﻟﻘﻴﻢ:‬ ‫ﺍﻟﻌﻠﻢ ‪ :CF‬ﺻﻔﺮ ﰲ ﺣﺎﻟﺔ ﳒﺎﺡ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺔ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :EAX‬ﻋﺪﺩ ﺍﻟﻜﻴﻠﻮﺑﺎﻳﺘﺎﺕ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ‪ 1 MB‬ﺍﱃ ‪.16 MB‬‬ ‫•‬‫ﺍﳌﺴﺠﻞ ‪ :EBX‬ﻋﺪﺩ ﺍﻟﻮﺣﺪﺍﺕ ﺍﳌﻜﻮﻧﺔ ﻣﻦ ٤٦ ﻛﻴﻠﻮﺑﺎﻳﺖ ﺑﺪﺋﺎ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ‪ ،16 MB‬ﻭﳚﺐ ﺿﺮ‪‬ﺎ ﻻﺣﻘﺎ‬ ‫•‬ ‫ﺑﺎﻟﻌﺪﺩ ٤٦ ﺣﱴ ﻳﺘﻢ ﲢﻮﻳﻠﻬﺎ ﺍﱃ ﻋﺪﺩ ﺍﻟﻜﻴﻠﻮﺑﺎﻳﺘﺎﺕ.‬ ‫٢٦١‬
    • Physical Memory Management ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬٧.٢ ‫. ﻭﺍﳌﺜﺎﻝ‬EBX ‫ ﻭ‬EAX ‫ ﺑﺪﻻ ﻣﻦ ﺍﳌﺴﺠﻠﲔ‬EDX ‫ ﻭ‬ECX ‫ﻭﰲ ﺑﻌﺾ ﺍﻷﻧﻈﻤﺔ ﻳﺴﺘﺨﺪﻡ ﺍﻟﺒﺎﻳﻮﺱ ﺍﳌﺴﺠﻠﲔ‬ .‫ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺍﺳﺘﺨﺪﺍﻡ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ‬ Example ٧.٢: Using int 0x15 Func on 0xe801 to get size of memory١٢ ; −−−−−−−−−−−−− −−−−−−−−−−−−−٣ ; get memory size:٤ ; get a total memory size.except the first MB.٥ ; return:٦ ; ax=KB between 1MB and 16MB٧ ; bx=number of 64K blocks above 16MB٨ ; bx=0 and ax= −1 on error٩ ; −−−−−−−−−−−−− −−−−−−−−−−−−−١٠ get memory size:١١١٢ push ecx١٣ push edx١٤ xor ecx,ecx١٥ xor edx,edx١٦١٧ mov ax,0x801 ; BIOS get memory size١٨ int 0x15١٩٢٠ jc .error٢١ cmp ah,0x86٢٢ je .error٢٣ cmp ah,0x80٢٤ je .error٢٥٢٦ jcxz .use eax٢٧٢٨ mov ax,cx٢٩ mov bx,dx٣٠٣١ .use eax:٣٢ pop edx٣٣ pop ecx٣٤ ret٣٥٣٦ .error:١٦٣
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬‫٧٣‬ ‫‪mov‬‬ ‫1−,‪ax‬‬‫٨٣‬ ‫‪mov‬‬ ‫0,‪bx‬‬‫٩٣‬ ‫‪pop‬‬ ‫‪edx‬‬‫٠٤‬ ‫‪pop‬‬ ‫‪ecx‬‬‫١٤‬ ‫‪ret‬‬‫ﻭﳚﺪﺭ ﻣﻼﺣﻈﺔ ﺃﻥ ﻫﺬﺍ ﺍﳌﻘﺎﻃﻌﺔ ﻻ ﲢﺴﺐ ﺃﻭﻝ ﻣﻴﺠﺎ ﺑﺎﻳﺖ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ، ﻟﺬﻟﻚ ﻋﻨﺪ ﺍﺳﺘﺨﺪﺍﻡ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﳚﺐ‬‫ﺯﻳﺎﺩﺓ ﺍﳊﺠﻢ ﺍﻟﻜﻠﻲ ﲟﻘﺪﺍﺭ ٤٢٠١ ﻛﻴﻠﻮﺑﺎﻳﺖ )ﺍﻟﺰﻳﺎﺩﺓ ﺗﻜﻮﻥ ﰲ ﻣﺴﺠﻞ ‪ ، (ax‬ﻛﺬﻟﻚ ﳚﺐ ﺿﺮﺏ ﺍﳌﺴﺠﻞ‬‫‪ bx‬ﺑﺎﻟﻌﺪﺩ ٤٦ ﻧﻈﺮﺍ ﻻﻥ ﺍﻟﻘﻴﻤﺔ ﺍﻟﱵ ﺗﻀﻌﻬﺎ ﺍﻟﺪﺍﻟﺔ ﻫﻲ ﻋﺪﺩ ﺍﻟﻮﺣﺪﺍﺕ ﺍﳌﻜﻮﻧﺔ ﻣﻦ ٤٦ ﻛﻴﻠﻮﺑﺎﻳﺖ ، ﻭﻫﺬﺍ ﻳﻌﲏ‬ ‫ﺍﻥ ﻛﺎﻥ ﺍﻟﻌﺪﺩ ﻫﻮ ٢ ﻣﺜﻼ ﻓﺎﻥ ﺍﻟﻨﺘﻴﺠﺔ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ 46*2 ﻭﺗﺴﺎﻭﻱ 821 ﻛﻴﻠﻮﺑﺎﻳﺖ.‬ ‫‪Memory Map‬‬ ‫٧.١.٢. ﺧﺮﻳﻄﺔ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺑﻌﺪ ﺃﻥ ﰎ ﺣﺴﺎﺏ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﳚﺐ ﺍﻻﻧﺘﺒﺎﻩ ﺍﱃ ﺃﻥ ﻋﺪﺩﺍ ﻣﻨﻬﺎ ﳏﺠﻮﺯ ﻟﺒﻌﺾ ﺍﻷﻏﺮﺍﺽ )ﺭﺍﺟﻊ ﻓﻘﺮﺓ ﺧﺮﻳﻄﺔ‬‫ﺍﻟﺬﺍﻛﺮﺓ ﰲ ﻓﺼﻞ ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ( ﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ ﺧﺮﻳﻄﺔ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﱵ ﺗﻌﺮﻑ ﻭﲢﺪﺩ ﻟﻨﺎ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﺍﳌﺴﺘﺨﺪﻣﺔ ﻭﺍﻟﻐﲑ ﻣﺴﺘﺨﺪﻣﺔ. ﻭﳝﻜﻦ ﺍﳊﺼﻮﻝ ﻋﻠﻰ ﺧﺮﻳﻄﺔ ﺍﻟﺬﺍﻛﺮﺓ ﺑﻮﺍﺳﻄﺔ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ 51‪ int 0x‬ﺍﻟﺪﺍﻟﺔ‬ ‫028‪ e‬ﺍﻟﱵ ﺗﺄﺧﺬ ﺍﳌﺪﺧﻼﺕ ﺍﻟﺘﺎﻟﻴﺔ:‬ ‫ﺍﻟﻌﻠﻢ ‪ :CF‬ﺻﻔﺮ ﰲ ﺣﺎﻟﺔ ﳒﺎﺡ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺔ.‬ ‫•‬‫ﺍﳌﺴﺠﻞ ‪ :eax‬ﺍﻟﻘﻴﻤﺔ 0514‪ 0x534d‬ﻭﺗﺴﺎﻭﻱ ‪ SMAP‬ﺑﺘﺮﻣﻴﺰ ‪ ،ASCII‬ﻭﰲ ﺣﺎﻟﺔ ﺣﺪﻭﺙ ﺧﻄﺄ ﻓﺎﻥ ﺭﻗﻢ‬ ‫•‬ ‫ﺍﳋﻄﺄ ﺳﻴﺤﻔﻆ ﰲ ﺍﳌﺴﺠﻞ ‪.ah‬‬ ‫ﺍﳌﺴﺠﻞ ‪ :ebx‬ﻋﻨﻮﺍﻥ ﺍﻟﺴﺠﻞ ﺍﻟﺘﺎﱄ ﺃﻭ ﺻﻔﺮ ﰲ ﺣﺎﻟﺔ ﺍﻹﻧﺘﻬﺎء.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :ecx‬ﻃﻮﻝ ﺍﳌﻘﻄﻊ ﺑﺎﻟﺒﺎﻳﺖ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻼﻥ ‪ :es:di‬ﺳﺠﻞ ﻭﺍﺻﻔﺔ ﺍﳌﻘﻄﻊ.‬ ‫•‬ ‫ﻭﺗﻌﻮﺩ ﺑﺎﳌﺨﺮﺟﺎﺕ:‬ ‫ﺍﳌﺴﺠﻞ ‪ :eax‬ﺭﻗﻢ ﺍﻟﺪﺍﻟﺔ ﻭﻫﻲ 028‪.0xe‬‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :ebx‬ﻋﻨﻮﺍﻥ ﺍﻟﺒﺪﺍﻳﺔ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :ecx‬ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﳌﺆﻗﺘﺔ )‪ (buffer‬ﻭﺗﺴﺎﻭﻱ ٠٢ ﺑﺎﻳﺖ ﻋﻠﻰ ﺍﻷﻗﻞ.‬ ‫•‬ ‫ﺍﳌﺴﺠﻞ ‪ :edx‬ﺍﻟﻘﻴﻤﺔ 0514‪ 0x534d‬ﻭﺗﺴﺎﻭﻱ ‪ SMAP‬ﺑﺘﺮﻣﻴﺰ ‪.ASCII‬‬ ‫•‬ ‫ﺍﳌﺴﺠﻼﻥ ‪ :es:di‬ﻋﻨﻮﺍﻥ ﺍﻟﺬﺍﻛﺮﺓ ‪ buffer‬ﺍﻟﱵ ﺳﺘﺤﻔﻆ ‪‬ﺎ ﺍﻟﻨﺘﺎﺋﺞ.‬ ‫•‬ ‫٤٦١‬
    • ‫‪Physical Memory Management‬‬ ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬‫ﻭﺑﻌﺪ ﺗﻨﻔﻴﺬ ﺍﳌﻘﺎﻃﻌﺔ ﻓﺎﻥ ﺍﻟﺬﺍﻛﺮﺓ ‪ Buffer‬ﻳﺘﻢ ﻣﻠﺌﻬﺎ ﺑﺄﻭﻝ ﺳﺠﻞ ﻭﻫﻮ ﺑﻄﻮﻝ ٤٢ ﺑﺎﻳﺖ ﻭﻳﺘﻢ ﺗﻜﺮﺍﺭ ﺍﺳﺘﺪﻋﺎء‬ ‫ﺍﳌﻘﺎﻃﻌﺔ ﺍﱃ ﺃﻥ ﺗﻜﻮﻥ ﻗﻴﻤﺔ ﺍﳌﺴﺠﻞ ‪ ebx‬ﻣﺴﺎﻭﻳﺔ ﻟﻠﺼﻔﺮ. ﻭﳏﺘﻮﻳﺎﺕ ﻛﻞ ﺳﺠﻞ ﻳﻮﺿﺤﻬﺎ ﺍﳌﺜﺎﻝ ٣.٧.‬ ‫‪Example‬‬ ‫‪٧.٣: Memory Map Entry Structure‬‬‫١‬‫‪٢ ; Memory Map Entry Structure‬‬‫‪٣ struc memory map entry‬‬‫٤‬ ‫1 ‪.base addr resq‬‬‫٥‬ ‫‪.length‬‬ ‫1 ‪resq‬‬‫٦‬ ‫‪.type‬‬ ‫1 ‪resd‬‬‫٧‬ ‫1 ‪.acpi null resd‬‬‫٨‬ ‫‪endstruc‬‬‫ﻭﻫﻲ ﺗﻮﺻﻒ ﻣﻘﻄﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﲢﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ﻭﻃﻮﻟﻪ ﻭﻧﻮﻉ ﺍﳌﻘﻄﻊ ﻭﺃﺧﲑﺍ ﺑﻴﺎﻧﺎﺕ ﳏﺠﻮﺯﺓ.‬ ‫ﻭﻧﻮﻉ ﺍﳌﻘﻄﻊ ﳛﺪﺩ ﻣﺎ ﺇﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ ﻣﺴﺘﺨﺪﻣﺎ ﺃﻭ ﳏﺠﻮﺯﺍ ﻭﻳﺄﺧﺬ ﻋﺪﺓ ﻗﻴﻢ:‬ ‫ﺍﻟﻘﻴﻤﺔ 1: ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﳌﻘﻄﻊ ﻣﺘﻮﻓﺮﺍ.‬ ‫•‬ ‫ﺍﻟﻘﻴﻤﺔ 2: ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﳌﻘﻄﻊ ﳏﺠﻮﺯﺍ.‬ ‫•‬ ‫ﺍﻟﻘﻴﻤﺔ 3: ‪ ACPI Reclaim Memory‬ﻭﻫﻲ ﻣﻨﻄﻘﺔ ﳏﺠﻮﺯﺓ ﻟﻜﻲ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﻟﻨﻈﺎﻡ.‬ ‫•‬ ‫ﺍﻟﻘﻴﻤﺔ 4:‪ ACPI NVS Memory‬ﻛﺬﻟﻚ ﻫﻲ ﻣﻨﻘﻄﺔ ﳏﺠﻮﺯﺓ ﻟﻠﻨﻈﺎﻡ.‬ ‫•‬ ‫ﺑﻘﻴﺔ ﺍﻟﻘﻴﻢ ﺍﻷﺧﺮﻯ ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﳌﻘﻄﻊ ﻏﲑ ﻣﻌﺮﻑ ﺃﻭ ﻏﲑ ﻣﻮﺟﻮﺩ.‬ ‫•‬ ‫ﻭﺍﳌﺜﺎﻝ ٤.٧ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺟﻠﺐ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻲ ﻳﺴﺘﻔﻴﺪ ﻣﻨﻬﺎ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻻﺣﻘﺎ.‬ ‫‪Example‬‬ ‫‪٧.٤: Get Memory Map‬‬‫; ١‬ ‫−−−−−−−−−−−−−−−−−−−−−−−−−‬ ‫−−−−−−−−−−−−−−−−−−−−−−−−‬‫:‪٢ ; get memory map‬‬‫:‪٣ ; Input‬‬‫; ٤‬ ‫= ‪EAX‬‬ ‫028‪0x0000E‬‬‫; ٥‬ ‫= ‪EBX‬‬ ‫‪continuation value or 0 to start at beginning of map‬‬‫; ٦‬ ‫= ‪ECX‬‬ ‫)‪size of buffer for result (Must be >= 20 bytes‬‬‫; ٧‬ ‫= ‪EDX‬‬ ‫)‪0x534D4150h (SMAP‬‬‫; ٨‬ ‫‪ES:DI‬‬ ‫‪= Buffer for result‬‬‫; ٩‬‫:‪١٠ ; Return‬‬‫; ١١‬ ‫‪CF = clear if successful‬‬‫٥٦١‬
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬١٢ ; EAX = 0x534D4150h (SMAP)١٣ ; EBX = offset of next entry to copy from or 0 if done١٤ ; ECX = actual length returned in bytes١٥ ; ES:DI = buffer filled١٦ ; If error, AH containes error code١٧ ; −−−−−−−−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−−−١٨ get memory map:١٩٢٠ pushad٢١ xor ebx,ebx٢٢ xor bp,bp٢٣ mov edx,PAMS ; 0x534D4150٢٤ mov eax,0xe820٢٥ mov ecx,24٢٦ int 0x15 ; BIOS get memory map.٢٧٢٨ jc .error٢٩ cmp eax,PAMS٣٠ jne .error٣١٣٢ test ebx,ebx٣٣ je .error٣٤٣٥ jmp .start٣٦٣٧ .next entry:٣٨ mov edx,PAMS ; 0x534D4150٣٩ mov eax,0xe820٤٠ mov ecx,24٤١ int 0x15 ; BIOS get memory map.٤٢٤٣ .start:٤٤ jcxz .skip entry٤٥٤٦ mov ecx,[es:di + memory map entry.length]٤٧ test ecx,ecx٤٨ jne short .good entry٤٩ mov ecx,[es:di + memory map entry.length+4]٥٠ jecxz .skip entry٥١٥٢ .good entry: ١٦٦
    • ‫‪Physical Memory Management‬‬ ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬‫٣٥‬ ‫‪inc bp‬‬‫٤٥‬ ‫42,‪add di‬‬‫٥٥‬‫٦٥‬ ‫‪.skip‬‬ ‫:‪entry‬‬‫٧٥‬ ‫‪cmp‬‬ ‫0,‪ebx‬‬‫٨٥‬ ‫‪jne‬‬ ‫‪.next entry‬‬‫٩٥‬ ‫‪jmp‬‬ ‫‪.done‬‬‫٠٦‬‫١٦‬ ‫:‪.error‬‬‫٢٦‬ ‫‪stc‬‬ ‫‪; set carry flag‬‬‫٣٦‬‫٤٦‬ ‫:‪.done‬‬‫٥٦‬ ‫‪popad‬‬‫٦٦‬ ‫‪ret‬‬‫٧٦‬‫‪٦٨ endstruc‬‬ ‫٧.١.٣. ﻣﻮﺍﺻﻔﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ‬‫ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﳏﻤﻼﺕ ﺍﻟﻨﻈﺎﻡ )‪ (Bootloader‬ﺗﺪﻋﻢ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ ﳌﺨﺘﻠﻒ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻭﺫﻟﻚ ﻋﱪ ﻣﻮﺍﺻﻔﺎﺕ‬‫ﻭﻣﻘﺎﻳﻴﺲ ﳏﺪﺩﺓ ﳚﺐ ﺃﻥ ﻳﻠﺘﺰﻡ ‪‬ﺎ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻋﻨﺪ ﲢﻤﻴﻞ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ. ﻭﻣﻦ ﺿﻤﻦ ﻫﺬﺍ ﺍﳌﻘﻴﺎﺱ ﲤﺮﻳﺮ ﺑﻴﺎﻧﺎﺕ‬‫ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ )‪ (Mul boot Informa on‬ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﱃ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ. ﻭﻣﺎ ﻳﻬﻤﻨﺎ ﺣﺎﻟﻴﺎ ﻫﻮ ﲤﺮﻳﺮ‬‫ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺧﺮﻳﻄﺔ ﺍﻟﺬﺍﻛﺮﺓ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ﺣﱴ ﻳﺘﻤﻜﻦ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻣﻦ ﺇﺩﺍﺭ‪‬ﺎ ﺑﻨﺎءﺍ ﻋﻠﻰ ﺧﺮﻳﻄﺔ ﺍﻟﺬﺍﻛﺮﺓ‬‫ﻭﺣﺠﻤﻬﺎ. ﺣﻴﺚ ﺫﻛﺮﻧﺎ ﺳﺎﺑﻘﺎ ﺃﻧﻪ ﺃﺛﻨﺎء ﻋﻤﻞ ﺍﻟﻨﻮﺍﺓ ﻻ ﺗﻮﺟﺪ ﻃﺮﻳﻘﺔ ﻣﺒﺴﻄﺔ ﻟﺘﺤﺪﻳﺪ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﻭﳐﻄﻂ‬‫ﺍﳌﻘﺎﻃﻊ ﻓﻴﻬﺎ ، ﻟﺬﻟﻚ ﰎ ﺍﻟﻠﺠﻮء ﺍﱃ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﻭﺍﻹﺳﺘﻔﺎﺩﺓ ﻣﻦ ﺧﺪﻣﺎﺗﻪ ﻭﻣﻦ ﰒ ﲤﺮﻳﺮ ﺍﻟﻨﺘﺎﺋﺞ ﺍﱃ ﻧﻮﺍﺓ‬ ‫ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﻃﺮﻳﻖ ﻫﻴﻜﻠﺔ ﻗﻴﺎﺳﻴﺔ ١.‬ ‫ﺣﺎﻟﺔ ﺍﳊﺎﺳﺐ‬‫ﻣﻦ ﺿﻤﻦ ﻫﺬﻩ ﺍﳌﻘﺎﻳﻴﺲ ﺃﻳﻀﺎ ﺗﻮﻓﺮ ﺣﺎﻟﺔ ﻣﻌﻴﻨﺔ ﻟﻠﺤﺎﺳﺐ )‪، (Machine State‬ﻭﻫﻲ ﺗﻨﺺ ﻋﻠﻰ ﺃﻧﻪ ﻋﻨﺪ ﲢﻤﻴﻞ‬ ‫ﻧﻮﺍﺓ ﺃﻱ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻓﺎﻥ ﺑﻌﺾ ﺍﳌﺴﺠﻼﺕ ﳚﺐ ﺃﻥ ﺗﺄﺧﺬ ﻗﻴﻤﺎ ﳏﺪﺩﺓ ﻛﺎﻻﰐ:‬‫ﺍﳌﺴﺠﻞ ‪ :eax‬ﳚﺐ ﺃﻥ ﻳﺄﺧﺬ ﺍﻟﺮﻗﻢ 200‪ 0x2BADB‬ﻭﻫﻲ ﺇﺷﺎﺭﺓ ﻟﻨﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﺑﺄﻥ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻳﺪﻋﻢ‬ ‫•‬ ‫ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ.‬ ‫ﺍﳌﺴﺠﻞ ‪ :ebx‬ﲢﺘﻮﻱ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻫﻴﻜﻠﺔ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ.‬ ‫•‬ ‫١ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻧﻪ ﳝﻜﻦ ﲤﺮﻳﺮ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﺄﻱ ﻃﺮﻳﻘﺔ ﺇﻻ ﺃﻥ ﺍﻹﻟﺘﺰﺍﻡ ‪‬ﻴﻜﻠﺔ ﻗﻴﺎﺳﻴﺔ ﺳﻴﻔﻴﺪ ﻻﺣﻘﺎ ﻋﻨﺪ ﺩﻋﻢ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ.‬‫٧٦١‬
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬‫0 ﻭﺍﻧﺘﻬﺎءﺍ ﺑﺎﻟﻌﻨﻮﺍﻥ‬x0 ‫: ﻭﺍﺻﻔﺔ ﺍﻟﺸﻔﺮﺓ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ٢٣ ﺑﺖ ﻗﺮﺍءﺓ/ﺗﻨﻔﻴﺬ ﺑﺪءﺍ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ‬cs ‫ﺍﳌﺴﺠﻞ‬ • .0xffffffff0x0 ‫: ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﻣﻘﺎﻃﻊ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ٢٣ ﺑﺖ ﻭﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ‬ds,es,fs,gs,ss ‫ﺍﳌﺴﺠﻼﺕ‬ • .0xffffffff ‫ﻭﺗﻨﺘﻬﻲ ﺑﺎﻟﻌﻨﻮﺍﻥ‬ .a20 ‫ﳚﺐ ﺗﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ‬ •‫: ﺍﻟﺒﺖ 0 ﳚﺐ ﺃﻥ ﻳﻔﻌﻞ )ﺗﻔﻌﻴﻞ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ( ﻭﺍﻟﺒﺖ ١٣ ﳚﺐ ﺃﻥ ﻳﻌﻄﻞ )ﺗﻌﻄﻴﻞ‬cr0 ‫ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ‬ • .(‫ﺍﻟﺘﺼﻔﻴﺢ‬ ‫ﻣﻌﻠﻮﻣﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ‬ebx ‫ﺎ ﰲ ﺍﳌﺴﺠﻞ‬‫ﺗﻌﺘﱪ ﻫﻴﻜﻠﺔ ﻣﻌﻠﻮﻣﺎﺕ ﺍﳌﺘﻌﺪﺩ ﻣﻦ ﺃﻫﻢ ﺍﳍﻴﺎﻛﻞ ﺍﻟﱵ ﳚﺐ ﲤﺮﻳﺮﻫﺎ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ، ﻭﻳﺘﻢ ﺣﻔﻆ ﻋﻨﻮﺍ‬‫ﺎ ﲤﺮﻳﺮ ﺍﳍﻴﻜﻠﺔ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ، ﻟﻜﻦ ﺑﺴﺒﺐ ﺃﻧﻨﺎ ﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﻻ ﻧﺪﻋﻢ ﺍﻹﻗﻼﻉ‬ ‫ﻭﻫﻲ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﻘﻴﺎﺳﻴﺔ ﺍﻟﱵ ﻳﺘﻢ‬‫(. ﻭﺍﳌﺜﺎﻝ ٥.٧ ﻳﻮﺿﺢ‬stack) ‫ﺎ ﺍﱃ ﺍﳌﻜﺪﺱ‬‫ﺍﳌﺘﻌﺪﺩ ﻓﻴﻤﻜﻦ ﺃﻥ ﳕﺮﺭ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﺄﻱ ﺷﻜﻞ ﻛﺎﻥ ﻛﺪﻓﻊ ﻋﻨﻮﺍ‬ .‫ﻫﻴﻜﻠﺔ ﻣﻌﻠﻮﻣﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ‬ Example ٧.٥: Mul boot Inforam on Structure١ boot info:٢٣ istruc multiboot info٤ at multiboot info.flags, dd 0٥ at multiboot info.mem low, dd 0٦ at multiboot info.mem high, dd 0٧ at multiboot info.boot device, dd 0٨ at multiboot info.cmd line, dd 0٩ at multiboot info.mods count, dd 0١٠ at multiboot info.mods addr, dd 0١١ at multiboot info.sym0, dd 0١٢ at multiboot info.sym1, dd 0١٣ at multiboot info.sym2, dd 0١٤ at multiboot info.mmap length, dd 0١٥ at multiboot info.mmap addr, dd 0١٦ at multiboot info.drives length, dd 0١٧ at multiboot info.drives addr, dd 0١٨ at multiboot info.config table, dd 0١٩ at multiboot info.bootloader name, dd 0٢٠ at multiboot info.apm table, dd 0 ١٦٨
    • Physical Memory Management ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬٢١ at multiboot info.vbe control info, dd 0٢٢ at multiboot info.vbe mode info, dw 0٢٣ at multiboot info.vbe interface seg, dw 0٢٤ at multiboot info.vbe interface off, dw 0٢٥ at multiboot info.vbe interface len, dw 0٢٦ iend‫ ﻟﺘﺤﺪﻳﺪ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﳌﺴﺘﺨﺪﻣﺔ ﰲ ﻫﻴﻜﻠﺔ ﻣﻌﻠﻮﻣﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ ﻣﻦ‬flags ‫ﻭﳛﺪﺩ ﺍﳌﻘﻴﺎﺱ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﺘﻐﲑ‬mem high ‫ ﻭ‬mem low ‫ ﻫﻲ ١ ﻓﺎﻥ ﺍﳌﺘﻐﲑﺍﺕ‬flags[0] ‫ﻏﲑ ﺍﳌﺴﺘﺨﺪﻣﺔ ، ﻓﻤﺜﻼ ﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﺍﻟﺒﺖ‬mem low ‫ ﻭﺳﻴﺘﻢ ﻭﺿﻊ ﻗﻴﻢ ﻟﻠﻤﺘﻐﲑﺍﺕ‬flags ‫ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ ﻭﻫﻜﺬﺍ.ﻭﺣﺎﻟﻴﺎ ﻟﻦ ﻳﺘﻢ ﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﺍﳌﺘﻐﲑ‬‫ ﻭﺍﻟﱵ ﲢﻮﻱ ﺣﺠﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ ﻭﺍﻟﱵ ﰎ ﺟﻠﺒﻬﺎ ﺑﻮﺍﺳﻄﺔ ﺍﻟﺒﺎﻳﻮﺱ ، ﻭﻛﺬﻟﻚ ﺍﳌﺘﻐﲑﺍﺕ‬mem high ‫ﻭ‬‫ ﻭﺍﻟﱵ ﺗﻮﺿﺢ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﰎ ﺟﻠﺒﻪ ﺃﻳﻀﺎ ﺑﻮﺍﺳﻄﺔ ﺍﻟﺒﺎﻳﻮﺱ‬mmap length ‫ ﻭ‬mmap addr‫ﻭﻛﺬﻟﻚ ﻃﻮﳍﺎ.ﻭﺍﳌﺜﺎﻝ ٦.٧ ﻳﻮﺿﺢ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﰎ ﺇﺿﺎﻓﺘﻬﺎ ﺍﱃ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻟﺪﻋﻢ ﺍﻹﻗﻼﻉ‬ .‫ﺍﳌﺘﻌﺪﺩ ﻭﻛﻴﻔﻴﺔ ﺣﻔﻆ ﻣﻌﻠﻮﻣﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ ﻭﺍﺭﺳﺎﳍﺎ ﺍﱃ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ‬ Example ٧.٦: snippet from stage2 bootloader١٢ ...٣ ; when stage2 begin started, BIOS put drive number where stage1 are loaded from in dl٤ mov [boot info+multiboot info.boot device],dl٥ ...٦٧ ; − − − − − − − − −−−−−−−−٨ ; Get Memory Size٩ ; − − − − − − − − −−−−−−−−١٠ xor eax,eax١١ xor ebx,ebx١٢ call get memory size١٣١٤ mov [boot info+multiboot info.mem low],ax١٥ mov [boot info+multiboot info.mem high],bx١٦١٧ ...١٨١٩ ; − − − − − − − − − − − − − − − − − − − − −−−−−−−−−−−−−−−−−−−−−٢٠ ; Pass MultiBoot Info to the Kernel٢١ ; − − − − − − − − − − − − − − − − − − − −−−−−−−−−−−−−−−−−−−−٢٢ mov eax,0x2badb002١٦٩
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬٢٣ mov ebx,0٢٤ mov edx,[kernel size]٢٥ push dword boot info٢٦٢٧ call ebp ; Call Kernel‫ﻭﻋﻨﺪ ﺍﺳﺘﺪﻋﺎء ﺍﻟﻨﻮﺍﺓ ﻓﺎﻥ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﱵ ﰎ ﺩﻓﻌﻬﺎ ﺍﱃ ﺍﳌﻜﺪﺱ ﺗﻌﺘﱪ ﻛﻮﺳﻴﻂ ﻟﻠﺪﺍﻟﺔ ، ﻭﰎ ﺍﻧﺸﺎء ﻫﻴﻜﻠﺔ ﺑﻠﻐﺔ‬‫ﺎ ﺑﺸﻜﻞ ﻣﺒﺴﻂ‬‫ﺍﻟﺴﻲ )ﺑﺪﺍﺧﻞ ﺍﻟﻨﻮﺍﺓ( ﺑﻨﻔﺲ ﺣﺠﻢ ﺍﳍﻴﻜﻠﺔ ﺍﻟﱵ ﰎ ﺩﻓﻌﻬﺎ ﺍﱃ ﺍﳌﻜﺪﺱ ﻭﺫﻟﻚ ﻟﻘﺮﺍءﺓ ﳏﺘﻮﻳﺎ‬ .‫ﻭﻣﻘﺮﻭء.ﻭﺍﳌﺜﺎﻝ ٧.٧ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻟﻨﻮﺍﺓ ﳍﺬﻩ ﺍﳍﻴﻜﻠﺔ‬ Example ٧.٧: Kernel Entry١٢ void cdecl kernel entry (multiboot info ∗ boot info)٣ {٤٥ #ifdef i386٦ asm {٧ cli٨٩ mov ax, 10h // select data descriptor in GDT.١٠ mov ds, ax١١ mov es, ax١٢ mov fs, ax١٣ mov gs, ax١٤ }١٥ #endif١٦١٧ // Execute global constructors١٨ init ctor();١٩٢٠ // Call kernel entry point٢١ main(boot info);٢٢٢٣ // Cleanup all dynamic dtors٢٤ exit();٢٥٢٦ #ifdef i386٢٧ asm {٢٨ cli٢٩ hlt ١٧٠
    • Physical Memory Management ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬٣٠ }٣١ #endif٣٢٣٣ for(;;);٣٤ } ‫٧.١.٤. ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬ Example ٧.٨: Physical Memory Manager Interface١٢ #ifndef PMM H٣ #define PMM H٤٥ #include <stdint.h>٦٧ extern void pmm init(size t size,uint32 t base);٨ extern void pmm init region(uint32 t base,size t size);٩ extern void pmm deinit region(uint32 t base,size t size);١٠ extern void∗ pmm alloc();١١ extern void∗ pmm allocs(size t size);١٢ extern void pmm dealloc(void∗);١٣ extern void pmm deallocs(void∗,size t);١٤ extern size t pmm get mem size();١٥ extern uint32 t pmm get block count();١٦ extern uint32 t pmm get used block count();١٧ extern uint32 t pmm get free block count();١٨ extern uint32 t pmm get block size();١٩ extern void pmm enable paging(bool);٢٠ extern bool pmm is paging();٢١ extern void pmm load PDBR(uint32 t);٢٢ extern uint32 t pmm get PDBR();٢٣٢٤ #endif // PMM H Example ٧.٩: Physical Memory Manager Implemeta on١١٧١
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬٢ #include <string.h>٣ #include "pmm.h"٤ #include "kdisplay.h"٥٦ #define PMM BLOCK PER BYTE 8٧ #define PMM PAGE SIZE 4096٨ #define PMM BLOCK SIZE PMM PAGE SIZE٩ #define PMM BLOCK ALIGN PMM BLOCK SIZE١٠١١ static uint32 t pmm mem size = 0;١٢ static uint32 t pmm max blocks = 0;١٣ static uint32 t pmm used blocks = 0;١٤ static uint32 t ∗ pmm mmap = 0;١٥١٦ inline void mmap set(int bit) {١٧ pmm mmap[bit/32] = pmm mmap[bit/32] | (1 << (bit%32)) ;١٨ }١٩٢٠ inline void mmap unset(int bit) {٢١ pmm mmap[bit/32] = pmm mmap[bit/32] & ˜(1 << (bit%32));٢٢ }٢٣٢٤ inline bool mmap test(int bit) {٢٥ return pmm mmap[bit/32] & (1 << (bit%32));٢٦ }٢٧٢٨ int mmap find first() {٢٩٣٠ for (uint32 t i=0;i<pmm get free block count()/32;++i) {٣١ if ( pmm mmap[i] != 0xffffffff) {٣٢ for (int j=0;j<32;++j) {٣٣ int bit = 1 << j;٣٤ if (!( pmm mmap[i] & bit))٣٥ return i∗32+j;٣٦ }٣٧ }٣٨ }٣٩٤٠ return −1;٤١ }٤٢ ١٧٢
    • Physical Memory Management ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬٤٣ int mmap find squence(size t s) {٤٤ if (s == 0)٤٥ return −1;٤٦٤٧ if (s == 1)٤٨ return mmap find first();٤٩٥٠ for (uint32 t i=0;i<pmm get free block count()/32;++i) {٥١ if ( pmm mmap[i] != 0xffffffff) {٥٢ for (int j=0;j<32;++j) {٥٣ int bit = 1 << j;٥٤ if (!( pmm mmap[i] & bit)) {٥٥٥٦ int start bit = i∗32 + bit;٥٧ uint32 t free bit = 0;٥٨٥٩ for (uint32 t count=0;count<=s;++count) {٦٠ if (!(mmap test(start bit+count)))٦١ free bit++;٦٢٦٣ if (free bit == s)٦٤ return i∗32+j;٦٥ }٦٦ }٦٧ }٦٨ }٦٩ }٧٠٧١ return −1;٧٢ }٧٣٧٤٧٥ void pmm init(size t size,uint32 t mmap base) {٧٦ pmm mem size = size;٧٧ pmm mmap = (uint32 t ∗)mmap base;٧٨ pmm max blocks = pmm mem size ∗1024 / PMM BLOCK SIZE;٧٩ pmm used blocks = pmm max blocks; // all memory used by default٨٠٨١ memset( pmm mmap,0xf, pmm max blocks/PMM BLOCK PER BYTE);٨٢ }٨٣١٧٣
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬ ٨٤ void pmm init region(uint32 t base,size t size) { ٨٥ int align = base/PMM BLOCK SIZE; ٨٦ int blocks = size/PMM BLOCK SIZE; ٨٧ ٨٨ for (;blocks >=0;blocks−−) { ٨٩ mmap unset(align++); ٩٠ pmm used blocks−−; ٩١ } ٩٢ ٩٣ mmap set(0); ٩٤ } ٩٥ ٩٦ void pmm deinit region(uint32 t base,size t size) { ٩٧ int align = base/PMM BLOCK SIZE; ٩٨ int blocks = size/PMM BLOCK SIZE; ٩٩١٠٠ for (;blocks >=0;blocks−−) {١٠١ mmap set(align++);١٠٢ pmm used blocks++;١٠٣ }١٠٤ }١٠٥١٠٦ void∗ pmm alloc() {١٠٧ if (pmm get free block count() <= 0)١٠٨ return 0;١٠٩١١٠ int block = mmap find first();١١١١١٢ if (block == −1)١١٣ return 0;١١٤١١٥ mmap set(block);١١٦١١٧ uint32 t addr = block ∗ PMM BLOCK SIZE;١١٨ pmm used blocks++;١١٩١٢٠ return (void∗) addr;١٢١ }١٢٢١٢٣ void∗ pmm allocs(size t s) {١٢٤ if (pmm get free block count() <= s) ١٧٤
    • Physical Memory Management ‫٧.١. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ‬١٢٥ return 0;١٢٦١٢٧ int block = mmap find squence(s);١٢٨١٢٩ if (block == −1)١٣٠ return 0;١٣١١٣٢ for (uint32 t i=0;i<s;++i)١٣٣ mmap set(block+i);١٣٤١٣٥ uint32 t addr = block ∗ PMM BLOCK SIZE;١٣٦ pmm used blocks += s;١٣٧١٣٨ return (void∗) addr;١٣٩ }١٤٠١٤١ void pmm dealloc(void∗ p) {١٤٢ uint32 t addr = (uint32 t)p;١٤٣ int block = addr / PMM BLOCK SIZE;١٤٤ mmap unset(block);١٤٥ pmm used blocks−−;١٤٦ }١٤٧١٤٨ void pmm deallocs(void∗ p,size t s) {١٤٩ uint32 t addr = (uint32 t)p;١٥٠ int block = addr / PMM BLOCK SIZE;١٥١١٥٢ for (uint32 t i=0;i<s;++i)١٥٣ mmap unset(block+i);١٥٤١٥٥ pmm used blocks −= s;١٥٦ }١٥٧١٥٨ size t pmm get mem size() {١٥٩ return pmm mem size;١٦٠ }١٦١١٦٢ uint32 t pmm get block count() {١٦٣ return pmm max blocks;١٦٤ }١٦٥ ١٧٥
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬١٦٦ uint32 t pmm get used block count() {١٦٧ return pmm used blocks;١٦٨ }١٦٩١٧٠ uint32 t pmm get free block count() {١٧١ return pmm max blocks − pmm used blocks;١٧٢ }١٧٣١٧٤ uint32 t pmm get block size() {١٧٥ return PMM BLOCK SIZE;١٧٦ }١٧٧١٧٨ void pmm enable paging(bool val) {١٧٩ #ifdef MSC VER١٨٠ asm {١٨١١٨٢ mov eax,cr0١٨٣ cmp [val],1١٨٤ je enable١٨٥ jmp disable١٨٦١٨٧ enable:١٨٨ or eax,0x80000000 // set last bit١٨٩ mov cr0,eax١٩٠ jmp done١٩١١٩٢ disable:١٩٣ and eax,0x7fffffff // unset last bit١٩٤ mov cr0,eax١٩٥١٩٦ done:١٩٧ }١٩٨١٩٩ #endif٢٠٠ }٢٠١٢٠٢ bool pmm is paging() {٢٠٣ uint32 t val = 0;٢٠٤ #ifdef MSC VER٢٠٥ asm {٢٠٦ mov eax,cr0 ١٧٦
    • Virtual Memory Management ‫٧.٢. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ‬٢٠٧ mov [val],eax٢٠٨ }٢٠٩٢١٠ if ( val & 0x80000000 )٢١١ false;٢١٢ else٢١٣ true;٢١٤ #endif٢١٥ }٢١٦٢١٧ void pmm load PDBR(uint32 t addr) {٢١٨ #ifdef MSC VER٢١٩ asm {٢٢٠ mov eax,[addr]٢٢١ mov cr3,eax٢٢٢ }٢٢٣ #endif٢٢٤ }٢٢٥٢٢٦ uint32 t pmm get PDBR() {٢٢٧ #ifdef MSC VER٢٢٨ asm {٢٢٩ mov eax,cr3٢٣٠ ret٢٣١ }٢٣٢ #endif٢٣٣ } Virtual Memory Management ‫٧.٢. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ‬ Example ٧.١٠: Virtual Memory Manager Interface ١ ٢ #ifndef VMM H ٣ #define VMM H ٤ ٥ #include <stdint.h> ٦ ٧ #include "vmm pte.h" ٨ #include "vmm pde.h" ١٧٧
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬٩١٠ #define PTE N 1024١١ #define PDE N 1024١٢١٣ struct page table {١٤ uint32 t pte[PTE N];١٥ };١٦١٧ struct page dir table {١٨ uint32 t pde[PDE N];١٩ };٢٠٢١ extern void vmm init();٢٢ extern bool vmm alloc page(uint32 t ∗ e);٢٣ extern void vmm free page(uint32 t ∗ e);٢٤ extern bool vmm switch page dir table(page dir table ∗);٢٥ extern page dir table ∗ vmm get page dir table();٢٦ extern void vmm flush tlb entry(uint32 t addr);٢٧ extern void vmm page table clear(page table ∗ pt);٢٨ extern uint32 t vmm vir to page table index(uint32 t addr);٢٩ extern uint32 t ∗ vmm page table lookup entry(page table ∗ pt,uint32 t addr);٣٠ extern uint32 t vmm vir to page dir table index(uint32 t addr);٣١ extern void vmm page dir table clear(page dir table ∗ pd);٣٢ extern uint32 t ∗ vmm page dir table lookup entry(page dir table ∗ pd, uint32 t addr);٣٣٣٤٣٥ #endif // VMM H Example ٧.١١: Virtual Memory Manager Implemeta on١٢ #include "vmm.h"٣٤ #include <string.h>٥ #include "vmm.h"٦ #include "pmm.h"٧٨ #define PAGE SIZE 4096 ١٧٨
    • Virtual Memory Management ‫٧.٢. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ‬٩ #define PT ADDRESS SPACE SIZE 0x400000١٠ #define PD ADDRESS SPACE SIZE 0x100000000١١١٢ page dir table ∗ cur page dir = 0;١٣ uint32 t cur page dir base register = 0;١٤١٥ void vmm init() {١٦ page table ∗ pt = (page table ∗) pmm alloc();١٧ if (!pt)١٨ return ;١٩٢٠ vmm page table clear(pt);٢١٢٢ for (int i=0, frame =0; i < 1024 ; ++i, frame += 4096) {٢٣ uint32 t page = 0;٢٤ pte add attrib(&page,I386 PTE PRESENT);٢٥ pte set frame(&page,frame);٢٦٢٧ pt− pte[vmm vir to page table index(frame)] = page; >٢٨ }٢٩٣٠ page dir table ∗ pd = (page dir table ∗) pmm allocs(3);٣١ if (!pd)٣٢ return ;٣٣٣٤ vmm page dir table clear(pd);٣٥٣٦ uint32 t ∗ pde = vmm page dir table lookup entry(pd,0);٣٧ pde add attrib(pde,I386 PDE PRESENT);٣٨ pde add attrib(pde,I386 PDE WRITABLE);٣٩ pde set frame(pde,(uint32 t)pt);٤٠٤١ cur page dir base register = (uint32 t) &pd− pde; >٤٢ vmm switch page dir table(pd);٤٣٤٤ pmm enable paging(true);٤٥٤٦ }٤٧٤٨ bool vmm alloc page(uint32 t ∗ e) {٤٩ void∗ p = pmm alloc();١٧٩
    • ‫٧. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ‬٥٠ if (!p)٥١ return false;٥٢٥٣ pte set frame(e,(uint32 t)p);٥٤ pte add attrib(e,I386 PTE PRESENT);٥٥٥٦ return true;٥٧ }٥٨٥٩ void vmm free page(uint32 t ∗ e) {٦٠ void∗ p = (void∗)pte get frame(∗e);٦١٦٢ if (p)٦٣ pmm dealloc(p);٦٤٦٥ pte del attrib(e,I386 PTE PRESENT);٦٦٦٧ }٦٨٦٩٧٠ bool vmm switch page dir table(page dir table ∗ pd) {٧١ if (!pd)٧٢ return false;٧٣٧٤ cur page dir = pd;٧٥ pmm load PDBR( cur page dir base register);٧٦ return true;٧٧ }٧٨٧٩ page dir table ∗ vmm get page dir table() {٨٠ return cur page dir;٨١ }٨٢٨٣ void vmm flush tlb entry(uint32 t addr) {٨٤ #ifdef MSC VER٨٥ asm {٨٦ cli٨٧ invlpg addr٨٨ sti٨٩ }٩٠ #endif ١٨٠
    • Virtual Memory Management ‫٧.٢. ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ‬ ٩١ } ٩٢ ٩٣ void vmm page table clear(page table ∗ pt) { ٩٤ if (pt) ٩٥ memset(pt,0,sizeof(page table)); ٩٦ } ٩٧ ٩٨ uint32 t vmm vir to page table index(uint32 t addr) { ٩٩ if ( addr >= PT ADDRESS SPACE SIZE )١٠٠ return 0;١٠١ else١٠٢ return addr / PAGE SIZE;١٠٣ }١٠٤١٠٥ uint32 t ∗ vmm page table lookup entry(page table ∗ pt,uint32 t addr) {١٠٦ if (pt)١٠٧ return &pt− pte[vmm vir to page table index(addr)]; >١٠٨ else١٠٩ return 0;١١٠ }١١١١١٢ uint32 t vmm vir to page dir table index(uint32 t addr) {١١٣ if ( addr >= PD ADDRESS SPACE SIZE )١١٤ return 0;١١٥ else١١٦ return addr / PAGE SIZE;١١٧ }١١٨١١٩ void vmm page dir table clear(page dir table ∗ pd) {١٢٠ if (pd)١٢١ memset(pd,0,sizeof(page dir table));١٢٢ }١٢٣١٢٤ uint32 t ∗ vmm page dir table lookup entry(page dir table ∗ pd,uint32 t addr) {١٢٥ if (pd)١٢٦ return &pd− pde[vmm vir to page table index(addr)]; >١٢٧ else١٢٨ return 0;١٢٩ } ١٨١
    • Device Driver ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬ Keyboard Driver ‫٨.١. ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬ Example ٨.١: Keybaord Driver Interface١٢ #ifndef KEYBOARD H٣ #define KEYBOARD H٤٥ #include <stdint.h>٦٧ enum KEY CODE {٨ KEY SPACE = ,٩ KEY 0 = 0,١٠ KEY 1 = 1,١١ KEY 2 = 2,١٢ KEY 3 = 3,١٣ KEY 4 = 4,١٤ KEY 5 = 5,١٥ KEY 6 = 6,١٦ KEY 7 = 7,١٧ KEY 8 = 8,١٨ KEY 9 = 9,١٩ KEY A = a,٢٠ KEY B = b,٢١ KEY C = c,٢٢ KEY D = d,٢٣ KEY E = e,٢٤ KEY F = f,٢٥ KEY G = g,٢٦ KEY H = h,٢٧ KEY I = i,٢٨ KEY J = j,٢٩ KEY K = k,١٨٣
    • Device Driver ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬٣٠ KEY L = l,٣١ KEY M = m,٣٢ KEY N = n,٣٣ KEY O = o,٣٤ KEY P = p,٣٥ KEY Q = q,٣٦ KEY R = r,٣٧ KEY S = s,٣٨ KEY T = t,٣٩ KEY U = u,٤٠ KEY V = v,٤١ KEY W = w,٤٢ KEY X = x,٤٣ KEY Y = y,٤٤ KEY Z = z,٤٥ KEY RETURN = r,٤٦ KEY ESCAPE = 0x1001,٤٧ KEY BACKSPACE = b,٤٨ KEY UP = 0x1100,٤٩ KEY DOWN = 0x1101,٥٠ KEY LEFT = 0x1102,٥١ KEY RIGHT = 0x1103,٥٢ KEY F1 = 0x1201,٥٣ KEY F2 = 0x1202,٥٤ KEY F3 = 0x1203,٥٥ KEY F4 = 0x1204,٥٦ KEY F5 = 0x1205,٥٧ KEY F6 = 0x1206,٥٨ KEY F7 = 0x1207,٥٩ KEY F8 = 0x1208,٦٠ KEY F9 = 0x1209,٦١ KEY F10 = 0x120a,٦٢ KEY F11 = 0x120b,٦٣ KEY F12 = 0x120b,٦٤ KEY F13 = 0x120c,٦٥ KEY F14 = 0x120d,٦٦ KEY F15 = 0x120e,٦٧ KEY DOT = .,٦٨ KEY COMMA = ,,٦٩ KEY COLON = :,٧٠ KEY SEMICOLON = ;, ١٨٤
    • Keyboard Driver ‫٨.١. ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬ ٧١ KEY SLASH = /, ٧٢ KEY BACKSLASH = , ٧٣ KEY PLUS = +, ٧٤ KEY MINUS = −, ٧٥ KEY ASTERISK = ∗, ٧٦ KEY EXCLAMATION = !, ٧٧ KEY QUESTION = ?, ٧٨ KEY QUOTEDOUBLE = ", ٧٩ KEY QUOTE = , ٨٠ KEY EQUAL = =, ٨١ KEY HASH = #, ٨٢ KEY PERCENT = %, ٨٣ KEY AMPERSAND = &, ٨٤ KEY UNDERSCORE = , ٨٥ KEY LEFTPARENTHESIS = (, ٨٦ KEY RIGHTPARENTHESIS = ), ٨٧ KEY LEFTBRACKET = [, ٨٨ KEY RIGHTBRACKET = ], ٨٩ KEY LEFTCURL = {, ٩٠ KEY RIGHTCURL = }, ٩١ KEY DOLLAR = $, ٩٢ KEY POUND = £, ٩٣ KEY EURO = $, ٩٤ KEY LESS = <, ٩٥ KEY GREATER = >, ٩٦ KEY BAR = | , ٩٧ KEY GRAVE = `, ٩٨ KEY TILDE = ˜, ٩٩ KEY AT = @,١٠٠ KEY CARRET = ˆ,١٠١ KEY KP 0 = 0,١٠٢ KEY KP 1 = 1,١٠٣ KEY KP 2 = 2,١٠٤ KEY KP 3 = 3,١٠٥ KEY KP 4 = 4,١٠٦ KEY KP 5 = 5,١٠٧ KEY KP 6 = 6,١٠٨ KEY KP 7 = 7,١٠٩ KEY KP 8 = 8,١١٠ KEY KP 9 = 9,١١١ KEY KP PLUS = +, ١٨٥
    • Device Driver ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬١١٢ KEY KP MINUS = −,١١٣ KEY KP DECIMAL = .,١١٤ KEY KP DIVIDE = /,١١٥ KEY KP ASTERISK = ∗,١١٦ KEY KP NUMLOCK = 0x300f,١١٧ KEY KP ENTER = 0x3010,١١٨ KEY TAB = 0x4000,١١٩ KEY CAPSLOCK = 0x4001,١٢٠ KEY LSHIFT = 0x4002,١٢١ KEY LCTRL = 0x4003,١٢٢ KEY LALT = 0x4004,١٢٣ KEY LWIN = 0x4005,١٢٤ KEY RSHIFT = 0x4006,١٢٥ KEY RCTRL = 0x4007,١٢٦ KEY RALT = 0x4008,١٢٧ KEY RWIN = 0x4009,١٢٨ KEY INSERT = 0x400a,١٢٩ KEY DELETE = 0x400b,١٣٠ KEY HOME = 0x400c,١٣١ KEY END = 0x400d,١٣٢ KEY PAGEUP = 0x400e,١٣٣ KEY PAGEDOWN = 0x400f,١٣٤ KEY SCROLLLOCK = 0x4010,١٣٥ KEY PAUSE = 0x4011,١٣٦ KEY UNKNOWN,١٣٧ KEY NUMKEYCODES١٣٨ };١٣٩١٤٠ extern bool keyboard get scroll lock();١٤١ extern bool keyboard get caps lock();١٤٢ extern bool keyboard get num lock();١٤٣ extern bool keyboard get alt();١٤٤ extern bool keyboard get ctrl();١٤٥ extern bool keyboard get shift();١٤٦ extern void keyboard ignore resend();١٤٧ extern bool keyboard check resend();١٤٨ extern bool keyboard get diagnostic res();١٤٩ extern bool keyboard get bat res();١٥٠ extern bool keyboard self test();١٥١ extern uint8 t keyboard get last scan();١٥٢ extern KEY CODE keyboard get last key(); ١٨٦
    • Keyboard Driver ‫٨.١. ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬١٥٣ extern void keyboard discard last key();١٥٤ extern void keyboard set leds(bool nums,bool caps,bool scroll);١٥٥ extern char keyboard key to ascii(KEY CODE k);١٥٦ extern void keyboard enable();١٥٧ extern void keyboard disable();١٥٨ extern bool keyboard is disabled();١٥٩ extern void keyboard reset system();١٦٠ extern void keyboard install(int);١٦١١٦٢ #endif // KEYBOARD H Example ٨.٢: Keybaord Driver Implemeta on ١ ٢ void keyboard install(int irq) { ٣ // Install interrupt handler (irq 1 uses interrupt 33) ٤ set vector(irq, i386 keyboard irq); ٥ ٦ // assume BAT test is good. If there is a problem, the IRQ handler where catch the error ٧ keyboard bat res = true; ٨ scancode = 0; ٩ ١٠ // set lock keys and led lights ١١ numlock = scrolllock = capslock = false; ١٢ keyboard set leds (false, false, false); ١٣ ١٤ // shift, ctrl, and alt keys ١٥ shift = alt = ctrl = false; ١٦ } ١٧ ١٨ ١٩ // keyboard interrupt handler ٢٠ void cdecl i386 keyboard irq () { ٢١ ٢٢ asm add esp, 12 ٢٣ asm pushad ٢٤ asm cli ٢٥ ٢٦ static bool extended = false; ١٨٧
    • Device Driver ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬٢٧٢٨ int code = 0;٢٩٣٠ // read scan code only if the keyboard controller output buffer is full (scan code is in it)٣١ if (keyboard ctrl read status () & KEYBOARD CTRL STATS MASK OUT BUF ) {٣٢٣٣ // read the scan code٣٤ code = keyboard enc read buf ();٣٥٣٦ // is this an extended code? If so, set it and return٣٧ if (code == 0xE0 | | code == 0xE1)٣٨ extended = true;٣٩ else {٤٠٤١ // either the second byte of an extended scan code or a single byte scan code٤٢ extended = false;٤٣٤٤ // test if this is a break code (Original XT Scan Code Set specific)٤٥ if (code & 0x80) { //test bit 7٤٦٤٧ // covert the break code into its make code equivelant٤٨ code −= 0x80;٤٩٥٠ // grab the key٥١ int key = keyboard scancode std [code];٥٢٥٣ // test if a special key has been released & set it٥٤ switch (key) {٥٥٥٦ case KEY LCTRL:٥٧ case KEY RCTRL:٥٨ ctrl = false;٥٩ break;٦٠٦١ case KEY LSHIFT:٦٢ case KEY RSHIFT:٦٣ shift = false; ١٨٨
    • Keyboard Driver ‫٨.١. ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ‬ ٦٤ break; ٦٥ ٦٦ case KEY LALT: ٦٧ case KEY RALT: ٦٨ alt = false; ٦٩ break; ٧٠ } ٧١ } ٧٢ else { ٧٣ ٧٤ // this is a make code − set the scan code ٧٥ scancode = code; ٧٦ ٧٧ // grab the key ٧٨ int key = keyboard scancode std [code]; ٧٩ ٨٠ // test if user is holding down any special keys & set it ٨١ switch (key) { ٨٢ ٨٣ case KEY LCTRL: ٨٤ case KEY RCTRL: ٨٥ ctrl = true; ٨٦ break; ٨٧ ٨٨ case KEY LSHIFT: ٨٩ case KEY RSHIFT: ٩٠ shift = true; ٩١ break; ٩٢ ٩٣ case KEY LALT: ٩٤ case KEY RALT: ٩٥ alt = true; ٩٦ break; ٩٧ ٩٨ case KEY CAPSLOCK: ٩٩ capslock = ( capslock) ? false : true;١٠٠ keyboard set leds ( numlock, capslock, scrolllock);١٠١ break;١٠٢١٠٣ case KEY KP NUMLOCK:١٠٤ numlock = ( numlock) ? false : true; ١٨٩
    • Device Driver ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬١٠٥ keyboard set leds ( numlock, capslock, scrolllock);١٠٦ break;١٠٧١٠٨ case KEY SCROLLLOCK:١٠٩ scrolllock = ( scrolllock) ? false : true;١١٠ keyboard set leds ( numlock, capslock, scrolllock);١١١ break;١١٢ }١١٣ }١١٤ }١١٥١١٦ // watch for errors١١٧ switch (code) {١١٨١١٩ case KEYBOARD ERR BAT FAILED:١٢٠ keyboard bat res = false;١٢١ break;١٢٢١٢٣ case KEYBOARD ERR DIAG FAILED:١٢٤ keyboard diag res = false;١٢٥ break;١٢٦١٢٧ case KEYBOARD ERR RESEND CMD:١٢٨ keyboard resend res = true;١٢٩ break;١٣٠ }١٣١ }١٣٢١٣٣ // tell hal we are done١٣٤ int done(0);١٣٥١٣٦ // return from interrupt handler١٣٧ asm sti١٣٨ asm popad١٣٩ asm iretd١٤٠ } ١٩٠
    • ‫ﺍﳋﺎﲤﺔ‬‫ﻭﻫﻜﺬﺍ ﻧﺼﻞ ﺍﱃ ‪‬ﺎﻳﺔ ﺍﳌﻄﺎﻑ ﳍﺬﺍ ﺍﻟﺒﺤﺚ ﺍﳌﺘﻮﺍﺿﻊ ﻭﺍﻟﺬﻱ ﻧﺮﺟﻮ ﺃﻥ ﻳﻜﻮﻥ ﺇﺿﺎﻓﺔ ﻭﻟﻮ ﻳﺴﲑﺓ ﻟﻠﻤﻜﺘﺒﺔ ﺍﻟﻌﺮﺑﻴﺔ‬‫ﻭﻟﻠﻘﺎﺭﺉ ﺍﻟﻌﺮﰊ ﰲ ﳎﺎﻝ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ. ﻭﻧﺴﺄﻝ ﺍﷲ ﺗﻌﺎﱃ ﺃﻥ ﻳﻨﻔﻌﻨﺎ ﲟﺎ ﻋﻠﻤﻨﺎ ﻭﺃﻥ ﻳﻨﻔﻊ ﺑﻨﺎ ﺍﻹﺳﻼﻡ‬‫ﻭﺍﳌﺴﻠﻤﲔ ﻭﺃﻥ ﻳﻌﻴﻨﻨﺎ ﻋﻠﻰ ﺗﻌﻠﻢ ﺍﻟﻌﻠﻢ ﻭﺗﺒﻠﻴﻐﻪ ﺍﻧﻪ ﻭﱄ ﺫﻟﻚ ﻭﺍﻟﻘﺎﺩﺭ ﻋﻠﻴﻪ. ﻭﺃﺧﲑﺍ ﻣﺎ ﻛﺎﻥ ﻣﻦ ﺧﻄﺄ ﻓﻤﻦ ﻧﻔﺴﻲ‬ ‫ﻭﺍﻟﺸﻴﻄﺎﻥ ﻭﻣﺎ ﻛﺎﻥ ﻣﻦ ﺻﻮﺍﺏ ﻓﻤﻦ ﺍﷲ ﻋﺰ ﻭﺟﻞ.‬ ‫ﻭﺻﻠﻰ ﺍﻟﻠﻬﻢ ﻭﺳﻠﻢ ﻋﻠﻰ ﻧﺒﻴﻨﺎ ﳏﻤﺪ ﻭﻋﻠﻰ ﺁﻟﻪ ﻭﺻﺤﺒﻪ ﺃﲨﻌﲔ . ﻭﺁﺧﺮ ﺩﻋﻮﺍﻧﺎ ﺃﻥ ﺍﳊﻤﺪ ﷲ ﺭﺏ ﺍﻟﻌﺎﳌﲔ.‬ ‫ﺍﻟﻨﺘﺎﺋﺞ‬ ‫ﺍﻟﺘﻮﺻﻴﺎﺕ‬‫ﺣﱴ ﻳﺼﻞ ﺍﻟﺒﺤﺚ ﳌﺮﺣﻠﺔ ﻣﻨﺎﺳﺒﺔ ﻓﺎﻧﻪ ﳚﺐ ﺍﳊﺪﻳﺚ ﻋﻦ ﻋﺪﺩﺍ ﻣﻦ ﺍﳌﻮﺿﻴﻊ ﺍﻟﱵ ﰎ ﲡﺎﻫﻠﻬﺎ ﻟﺴﺒﺐ ﺃﻭ ﻵﺧﺮ‬‫، ﻓﺒﺪﺍﻳﺔ ﻣﻦ ﺍﻟﻔﺼﻞ ﺍﻷﻭﻝ ﻭﺍﻟﺬﻱ ﻳﻌﺘﱪ ﻣﻘﺪﻣﺔ ﻋﺎﻣﺔ ﺍﱃ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺣﻴﺚ ﳝﻜﻦ ﺃﻥ ﺗﻀﺎﻑ ﻟﻪ ﺍﻟﻌﺪﻳﺪ‬‫ﻣﻦ ﺍﳌﻌﻠﻮﻣﺎﺕ ﻋﻦ ﺍﻷﻧﻈﻤﺔ ﺍﳊﺎﻟﻴﺔ ﻭﻛﺬﻟﻚ ﻣﺰﻳﺪﺍ ﻣﻦ ﺍﻟﺘﻮﺿﻴﺤﺎﺕ ﻋﻦ ﻣﺎﻫﻴﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ. ﺃﻣﺎ ﺍﻟﻔﺼﻞ‬‫ﺍﻟﺜﺎﱐ ﻓﻠﻢ ﻳﺘﺤﺪﺙ ﺳﻮﻯ ﻋﻦ ﺍﻟﻘﺸﻮﺭ ﰲ ﻣﻌﻤﺎﺭﻳﺔ ﺍﳊﺎﺳﺐ ﺣﻴﺚ ﺃﻧﻪ ﻳﺘﻄﻠﺐ ﻛﺘﺎﺑﺎ ﻣﺘﻜﺎﻣﻼ ﻟﺸﺮﺡ ﻛﻞ ﺟﺰﺋﻴﺔ‬‫ﻭﻟﻜﻦ ﰎ ﺍﻹﳚﺎﺯ ﻭﺍﳊﺪﻳﺚ ﻋﻦ ﺍﳌﻮﺍﺿﻴﻊ ﺍﻟﱵ ﻳﻜﺜﺮ ﺗﻨﺎﻭﳍﺎ ﻋﻨﺪ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ. ﻭﻗﺒﻞ ﺍﻹﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻔﺼﻞ‬‫ﺍﻟﺜﺎﻟﺚ ﳝﻜﻦ ﻛﺘﺎﺑﺔ ﻓﺼﻞ ﺟﺪﻳﺪ ﻋﻦ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﲝﻴﺚ ﻳﺸﺮﺡ ﺃﺳﺎﺳﻴﺎﺕ ﺍﻟﻠﻐﺔ ﻣﻊ ﻣﺘﺮﺟﻢ ‪ NASM‬ﻻﻧﻪ ﺍﳌﺘﺮﺟﻢ‬‫ﺍﳌﺴﺘﺨﺪﻡ ﰲ ﻋﻤﻠﻴﺔ ﲡﻤﻴﻊ ﺍﻟﱪﺍﻣﺞ ﺣﻴﺚ ﺃﻧﻪ ﳛﻮﻱ ﺃﻭﺍﻣﺮ ﺧﺎﺻﺔ ﺑﻪ ﳚﺐ ﺍﻟﻮﻗﻮﻑ ﻋﻨﺪﻫﺎ ﻭﺗﻮﺿﻴﺤﻬﺎ ﺑﺸﻜﻞ‬‫ﺟﻴﺪ. ﺃﻣﺎ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﻟﺚ ﻭﺍﻟﺮﺍﺑﻊ ﻓﺘﻢ ﺍﳊﺪﻳﺚ ﻓﻴﻬﺎ ﻋﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﰎ ﺑﺮﳎﺘﻪ ﻟﺘﺤﻤﻴﻞ ﻧﻈﺎﻡ ﺇﻗﺮﺃ ﻭﳝﻜﻦ‬‫ﻫﻨﺎ ﺍﳊﺪﻳﺚ ﻋﻦ ﺃﻱ ﻣﻦ ﺍﳌﺤﻤﻼﺕ ﺍﳌﻔﺘﻮﺣﺔ ﺍﳌﺼﺪﺭ )ﻣﺜﻞ ﳏﻤﻞ ‪ GRUB‬ﻭﺍﻟﺬﻱ ﻳﻌﺘﱪ ﻣﻦ ﺃﺷﻬﺮ ﺍﳌﺤﻤﻼﺕ‬‫ﻭﺃﻛﺜﺮﻫﻢ ﺍﺳﺘﺨﺪﺍﻣﺎ( ﻭﻛﻴﻔﻴﺔ ﲢﻤﻴﻞ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﺒﺎﺷﺮﺓ ﻣﻦ ﺧﻼﳍﻢ. ﻭﺍﻟﻔﺼﻞ ﺍﳋﺎﻣﺲ ﲢﺪﺙ ﻋﻦ ﺍﻟﻨﻮﺍﺓ ﻭﻃﺮﻕ‬‫ﺗﺼﻤﻴﻤﻬﺎ ﺑﺸﻜﻞ ﳐﺘﺼﺮ ﻭﱂ ﻳﺘﻨﺎﻭﻝ ﺍﻻﺧﺘﻼﻑ ﺑﻴﻨﻬﻢ ﻭﻃﺮﻕ ﺑﺮﳎﺔ ﻛﻞ ﻣﻨﻬﻢ ﻋﻠﻰ ﺣﺪﺓ ﻭﻳﻌﺘﱪ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﳎﺎﻻ‬‫ﻛﺎﻣﻼ ﻟﻠﺒﺤﺚ ﻓﻴﻪ . ﺃﻣﺎ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺩﺱ ﻓﻬﻮ ﻣﻜﺘﻤﻞ ﺗﻘﺮﻳﺒﺎ ﻭﳝﻜﻦ ﺍﺿﺎﻓﺔ ﺍﳌﺰﻳﺪ ﻣﻦ ﺍﻟﻌﻠﻮﻣﺎﺕ ، ﺑﻴﻨﻤﺎ ﺍﻟﻔﺼﻞ‬‫ﺍﻟﺴﺎﺑﻊ ﱂ ﻳﺘﺤﺪﺙ ﻋﻦ ﺧﻮﺍﺭﺯﻣﻴﺎﺕ ﺍﺩﺭﺍﺓ ﺍﻟﺬﺍﻛﺮﺓ ﻭﰎ ﺗﻄﺒﻴﻖ ﺧﻮﺍﺭﺯﻣﻴﺔ ‪ First Fit‬ﻟﻠﺒﺤﺚ ﻋﻦ ﺃﻣﺎﻛﻦ ﺷﺎﻏﺮﺓ‬‫ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻭﳝﻜﻦ ﺗﻄﺒﻴﻖ ﺃﻱ ﻣﻦ ﺍﳋﻮﺍﺭﺯﻣﻴﺎﺕ ﺍﻟﺸﻬﲑﺓ ، ﻛﺬﻟﻚ ﳝﻜﻦ ﺗﻄﺒﻴﻖ ﺍﻟﻘﺎﺋﻤﺔ ﺍﳌﺘﺼﻠﺔ ﳌﺘﺎﺑﻌﺔ ﺍﻷﻣﺎﻛﻦ‬‫ﺍﻟﺸﺎﻏﺮﺓ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﺑﺪﻻ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ‪ .Bit Map‬ﺃﻣﺎ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﻣﻦ ﻓﻬﻮ ﻋﻦ ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ ﻟﻜﻦ ﻧﻈﺮﺍ‬‫ﻟﻀﻴﻖ ﺍﻟﻮﻗﺖ ﻓﻘﺪ ﰎ ﺍﳊﺪﻳﺚ ﻋﻦ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﻛﻴﻔﻴﺔ ﻗﺮﺍءﺓ ﺍﻷﺣﺮﻑ ﺍﳌﺪﺧﻠﺔ ﻣﻨﻪ ، ﻭﳝﻜﻦ ﰲ ﻫﺬﺍ‬‫ﺍﻟﻔﺼﻞ ﺍﺿﺎﻓﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ ﻣﺜﻞ ﻣﺸﻐﻞ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻭﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ ﻭﻣﺸﻐﻞ ﻟﻜﺮﺕ ﺍﻟﺸﺒﻜﺔ‬‫١٩١‬
    • ‫‪Device Driver‬‬ ‫٨. ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ‬‫ﻭﻛﺮﺕ ﺍﻟﺼﻮﺕ ﻭﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺸﻐﻼﺕ ﺍﻟﻀﺮﻭﺭﻳﺔ. ﺃﺧﲑﺍ ﳝﻜﻦ ﺇﺿﺎﻓﺔ ﻓﺼﻞ ﻟﻠﺤﺪﻳﺚ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ‬ ‫ﻭﻛﻴﻔﻴﺔ ﺑﺮﳎﺘﻬﻢ ﻣﺜﻞ ‪ FAT12,FAT16,FAT32,EXT3,EXT4,...etc‬ﻭﻓﺼﻞ ﻟﱪﳎﺔ ﺍﳌﺠﺪﻭﻝ ﻟﺪﻋﻢ ﺗﻌﺪﺩ ﺍﳌﻬﺎﻡ.‬ ‫ﻭﻣﻦ ﻧﺎﺣﻴﺔ ﻧﻈﺎﻡ ﺇﻗﺮﺃ ﻓﺎﻧﻪ ﲝﺎﺟﺔ ﺍﱃ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻹﺿﺎﻓﺎﺕ ﻭﺍﻟﺘﺤﺴﻴﻨﺎﺕ:‬ ‫• ﺩﻋﻢ ﻭﺍﺟﻬﺔ ‪.POSIX‬‬ ‫ﺩﻋﻢ ﻷﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ‪.FAT12,FAT16,FAT32,EXT3,EXT4,...etc‬‬ ‫•‬ ‫ﺩﻋﻢ ﻟﺘﻌﺪﺩ ﺍﳌﻬﺎﻡ.‬ ‫•‬ ‫ﻧﻘﻞ )‪ (port‬ﻣﺘﺮﺟﻢ ++‪ gcc,g‬ﻭﻭﺍﺟﻬﺔ 11‪ x‬ﺍﱃ ﻧﻈﺎﻡ ﺇﻗﺮﺃ.‬ ‫•‬ ‫٢٩١‬
    • Bibliography [١] William Stallings, Operating System: Internals and Design Principles. Prentice Hall, 5th Edition, 2004. [٢] Andrew S. Tanenbaum ,Albert S Woodhull, Operating Systems Design and Implementation. Prentice Hall, 3rd Edition, 2006. [٣] Michael Tischer, Bruno Jennrich, PC Intern: The Encyclopedia of System Programming. Abacus Software, 6th Edition, 1996. [٤] Hans-Peter Messmer, The Indispensable PC Hardware Book. Addison-Wesley Profes- sional, 4th Edition, 2001. [٥] Andrew S. Tanenbaum, Structured Computer Organization. Prentice Hall, 4th Edition, 1998. [٦] Ytha Yu,Charles Marut, Asssembly Language Programming and Organization IBM PC. McGraw-Hill/Irwin, 1st Edition, 1992. [٧] Intel® Manuals, Intel® 64 and IA-32 Architectures Software Developers Manuals. http: //www.intel.com/products/processor/manuals/ [٨] OSDev: http://wiki.osdev.org [٩] brokenthorn: http://brokenthorn.com[١٠] Computer Sciense Students Community in Sudan: http://sudancs.com[١١] Wikipedia: http://wikipedia.org١٩٣
    • ‫ﺍ. ﺗﺮﲨﺔ ﻭﺗﺸﻐﻴﻞ ﺍﻟﱪﺍﻣﺞ‬‫ﻟﺘﻄﻮﻳﺮ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﳎﻤﻮﻋﺔ ﻣﻦ ﺍﻻﺩﻭﺍﺕ ﻭﺍﻟﻠﻐﺎﺕ ﺍﻟﱵ ﺗﺴﺎﻋﺪ ﻭﺗﻴﺴﲑ ﻋﻤﻠﻴﺔ ﺍﻟﺘﻄﻮﻳﺮ ﻭﰲ ﻫﺬﺍ‬ ‫ﺍﻟﻔﺼﻞ ﺳﻴﺘﻢ ﻋﺮﺽ ﻫﺬﻩ ﺍﻷﺩﻭﺍﺕ ﻭﻛﻴﻔﻴﺔ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ.‬ ‫ﺍﻋﺪﺍﺩ ﻣﺘﺮﺟﻢ ﻓﻴﺠﻮﺍﻝ ﺳﻲ++ ﻟﱪﳎﺔ ﺍﻟﻨﻮﺍﺓ.‬ ‫ﺍ.١. ﻧﻈﺎﻡ ﻭﻳﻨﺪﻭﺯ‬ ‫ﺍ.٢. ﻧﻈﺎﻡ ﻟﻴﻨﻮﻛﺲ‬‫٥٩١‬
    • ‫ﺏ. ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ‬ ‫ﻛﻮﺩ ﺍﻟﻨﻈﺎﻡ‬‫٧٩١‬