Build OS2
Build OS2
اﻟﺒﻮﺻﻠﺔ اﻟﺘﻘﻨﻴﺔ
www.boosla.com
ﺑﺴﻢ ﺍﷲ ﺍﻟﺮﲪﻦ ﺍﻟﺮﺣﻴﻢ
٣ﻳﻮﻟﻴﻮ ٢٠١٠
ﺟﺎﻣﻌﺔ ﺍﳋﺮﻃﻮﻡ.
ﻛﻠﻴﺔ ﺍﻟﻌﻠﻮﻡ ﺍﻟﺮﻳﺎﺿﻴﺔ -ﻗﺴﻢ ﺍﳊﺎﺳﻮﺏ.
ﰎ ﻛﺘﺎﺑﺔ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻧﻈﺎﻡ .LATEX
⃝ ٢٠١٠ﺃﲪﺪ ﻋﺼﺎﻡ ﻋﺒﺪ ﺍﻟﺮﺣﻴﻢ ﺃﲪﺪ. ﲨﻴﻊ ﺍﳊﻘﻮﻕ ﳏﻔﻮﻇﺔ c
ﻳﺴﻤﺢ ﺑﻨﺴﺦ ،ﺗﻮﺯﻳﻊ ﻭ/ﺃﻭ ﺗﻌﺪﻳﻞ ﻫﺬﺍ ﺍﳌﺴﺘﻨﺪ ﺿﻤﻦ ﺷﺮﻭﻁ ﺇﺗﻔﺎﻗﻴﺔ ﺗﺮﺧﻴﺺ ﺍﳌﺴﺘﻨﺪﺍﺕ ﺍﳊﺮﺓ ﺟﻨﻮ ﺍﻹﺻﺪﺍﺭ ١.٢ﺃﻭ ﺃﻱ ﺇﺻﺪﺍﺭﹴ ﻻﺣ ﹴﻖ
ﰎ ﻧﺸﺮﻩ ﻣﻦ ﻗﺒﻞ ﻣﺆﺳﺴﺔ ﺍﻟﱪﳎﻴﺎﺕ ﺍﳊﺮﺓ ،ﺩﻭﻥ ﺃﻳﺔ ﺃﻗﺴﺎﻡ ﺛﺎﺑﺘﺔ ،ﻧﺼﻮﺹ ﻏﻼﻑ ﺃﻣﺎﻣﻲ ﻭﻧﺼﻮﺹ ﻏﻼﻑ ﺧﻠﻔﻲ .ﻟﻘﺪ ﲤﺖ ﺇﺿﺎﻓﺔ
ﻧﺴﺨﺔ ﻣﻦ ﺇﺗﻔﺎﻗﻴﺔ ﺍﻟﺘﺮﺧﻴﺺ ﰲ ﺍﻟﻘﺴﻢ ﺍﳌﻌﻨﻮﻥ )ﺇﺗﻔﺎﻗﻴﺔ ﺗﺮﺧﻴﺺ ﺍﳌﺴﺘﻨﺪﺍﺕ ﺍﳊﺮﺓ .(GNU
ﺍﳌﺤﺘﻮﻳﺎﺕ
ﺝ
ﺍﳌﺤﺘﻮﻳﺎﺕ
ﺩ
ﺍﳌﺤﺘﻮﻳﺎﺕ
١٠٧ . . . . . . . . . . . . . . . . .٣.٣.٥ﺍﻟﻨﻮﺍﺓ ﺍﳍﺠﻴﻨﺔ . Hybrid Kernel
١٠٧ . . . . . . . . . . . . . . . . .٤.٥ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ . . . . . . . . . . .
١٠٨ . . . . . . . . . . . . . . . . .١.٤.٥ﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﻧﻮﺍﺓ . . . . PE
١١١ . . . . . . . . . . . . . . . . .٢.٤.٥ﺗﻄﻮﻳﺮ ﺑﻴﺌﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻠﻐﺔ ﺳﻲ++
١١٦ . . . . . . . . . . . . . . . . .٣.٤.٥ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﻨﻮﺍﺓ . . . .
١١٧ . . . . . . . . . . . . . . . . .٥.٥ﻧﻈﺮﺓ ﻋﻠﻰ ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ . . . . . . .
١١٨ . . . . . . . . . . . . . . . . .٦.٥ﻣﻜﺘﺒﺔ ﺍﻟﺴﻲ ﺍﻟﻘﻴﺎﺳﻴﺔ . . . . . . . . .
ﻫ
ﺍﳌﺤﺘﻮﻳﺎﺕ
ﻭ
ﺍﻷﻣﺜﻠﺔ ﺍﻟﺘﻮﺿﻴﺤﻴﺔ
٤ . . . . . . . . . . . . . . . . . . . . . . . . . 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 .٤.١٤
ﺯ
ﺍﻷﻣﺜﻠﺔ ﺍﻟﺘﻮﺿﻴﺤﻴﺔ
ﺡ
ﺍﻷﻣﺜﻠﺔ ﺍﻟﺘﻮﺿﻴﺤﻴﺔ
ﻁ
ﻗﺎﺋﻤﺔ ﺍﻷﺷﻜﺎﻝ
٣ . . . . . . . . . . . . . . .
ﺍﻟﺸﻜﻞ ﺍﻟﻌﺎﻡ ﻷﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ . . . . . . x86 .١.١
٥ . . . . . . . . . . . . . . .
ﻃﺒﻘﺎﺕ ﺍﳊﺎﺳﺐ . . . . . . . . . . . . .٢.١
٧ . . . . . . . . . . . . . . .
ﺁﻟﺔ ﺑﺎﺳﻜﺎﻝ . . . . . . . . . . . . . . .٣.١
٧ . . . . . . . . . . . . . . .
ﺁﻟﺔ Step Reckonerﰲ ﻣﺘﺤﻒ ﺑﺄﳌﺎﻧﻴﺎ . . . .٤.١
٨ . . . . . . . . . . . . . . .
ﳏﺮﻙ ﺍﻟﻔﺮﻭﻕ ﺑﻌﺪ ﺃﻥ ﻗﺎﻡ ﺍﺑﻦ ﺑﺎﺑﺒﺎﺝ ﺑﺘﺠﻤﻴﻌﻪ . .٥.١
٩ . . . . . . . . . . . . . . .
ﺍﳌﺤﺮﻙ ﺍﻟﺘﺤﻠﻴﻠﻲ ﲟﺘﺤﻒ ﰲ ﻟﻨﺪﻥ . . . . . .٦.١
٩ . . . . . . . . . . . . . . .
ﺣﺎﺳﺒﺔ Z1ﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺍﻧﺸﺎﺋﻬﺎ ﰲ ﻣﺘﺤﻒ ﺑﺄﳌﺎﻧﻴﺎ .٧.١
١٠ . . . . . . . . . ﺣﺎﺳﺒﺔ Atanasoffﺑﻌﺪ ﺇﻋﺎﺩﺓ ﺍﻧﺸﺎﺋﻬﺎ ﰲ ﺟﺎﻣﻌﺔ Iowa State .٨.١
١٠ . . . . . . . . . ﺣﺎﺳﺒﺔ . . . . . . . . . . . . . . . Harvard Mark I .٩.١
١١ . . . . . . . . . ﺁﻟﺔ ﺇﳒﻤﺎ ﺍﻷﳌﺎﻧﻴﺔ ﻟﺘﺸﻔﲑ ﺍﻟﺮﺳﺎﺋﻞ ﻭﻓﻜﻬﺎ . . . . . . . . . .١٠.١
١٢ . . . . . . . . . ﺍﳊﺎﺳﺒﺔ colossusﺍﻟﱵ ﻛﺴﺮﺕ ﺷﻔﺮﺓ ﺇﳒﻤﺎ . . . . . . . .١١.١
١٢ . . . . . . . . . ﺍﳊﺎﺳﺒﺔ . . . . . . . . . . . . . . . . . . ENIAC .١٢.١
١٣ . . . . . . . . . ﺍﳊﺎﺳﺒﺔ . . . . . . . . . . . . . . . . . . EDVAC .١٣.١
١٥ . . . . . . . . . . . . . . . . . . ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ . . . . . . x86 .١.٢
١٦ . . . . . . . . . . . . . . . . . . ﺍﳌﺴﺎﺭﺍﺕ ﰲ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﺸﺨﺼﻴﺔ x86 .٢.٢
١٨ . . . . . . . . . . . . . . . . . . ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ . . . . . . . . . . .٣.٢
٢٤ . . . . . . . . . . . . . . . . . . ﺗﺪﺍﺧﻞ ﺍﳌﻘﺎﻃﻊ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ . . .٤.٢
٢٥ . . . . . . . . . . . . . . . . . . ﺣﻠﻘﺎﺕ ﺍﳌﻌﺎﰿ . . . . . . . . . . .٥.٢
٣٦ .١.٣ﳐﻄﻂ ﳏﺘﻮﻳﺎﺕ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ . . . . . . . . . . . . . . . . . . . . .
٥١ .٢.٣ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ FAT12ﻋﻠﻰ ﺍﻟﻘﺮﺹ . . . . . . . . . . . . . . . . . . . . .
.١.٤ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺃﺛﻨﺎء ﺍﻟﻌﻤﻞ ١٠٠ . . . . . . . . . . . . . . . . . . . . . . . .
.٢.٤ﺑﺪء ﺗﻨﻔﻴﺬ ﺍﻟﻨﻮﺍﺓ ١٠٠ . . . . . . . . . . . . . . . . . . . . . . . . . . .
١٣٣ . . . . . . . . . . . . . . . . . 8259A ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ .١.٦
١٣٥ . . . . . . . . . . . . . . . . . . . ﻣﺸﺎﺑﻚ ﻣﺘﺤﻜﻢ . . . . . . PIC .٢.٦
١٤٢ . . . . . . . . . . . . . . . . . . . ﺍﳌﺆﻗﺘﺔ ﺍﻟﻘﺎﺑﻠﺔ ﻟﻠﱪﳎﺔ . . . . 8253 .٣.٦
١٤٢ . . . . . . . . . . . . . . . . . . . ﻣﺸﺎﺑﻚ ﺍﳌﺆﻗﺘﺔ . . . . . . . PIT .٤.٦
١٥٩ . . . . . . . . . . . . . . . . . . . ﻭﺍﺟﻬﺔ ﺍﻟﻨﻈﺎﻡ ﺑﻌﺪ ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ HAL .٥.٦
١٦٠ . . . . . . . . . . . . . . . . . . . ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻹﻓﺘﺮﺍﺿﻴﺔ . . .٦.٦
ﻳﺎ
ﻗﺎﺋﻤﺔ ﺍﳉﺪﺍﻭﻝ
٢٠ .. ........... . . . ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ ﳊﻮﺍﺳﻴﺐ . . . . . . x86 .١.٢
٢١ .. ........... . . . ﻣﻨﺎﻓﺬ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﳊﻮﺍﺳﻴﺐ . x86 .٢.٢
٢٦ .. ........... . . . ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﺗﺘﻄﻠﺐ ﺻﻼﺣﻴﺔ ﺍﳊﻠﻘﺔ ﺻﻔﺮ . .٣.٢
٢..٤ EFLAGSﺍﻷﻋﻼﻡ ﻣﺴﺠﻞ . . . ................... . . ٢٩
٦..١ Interrupt Vector Table .. . . . . . . . . . . . . . . . . . . . . . . ١٢٤
١٢٨ . . . . . . . . . . . . . . . . . . . x86 Processor Excep ons Table .٢.٦
١٣٤ . . .٣.٦ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩ ﳊﻮﺍﺳﻴﺐ . . . . . . . . . . . . . . . . . . . x86
١٣٦ . . .٤.٦ﻣﺴﺠﻞ . . . . . . . . . . . . . . . . . . . . . . . IRR/ISR/IMR
١٣٦ . . .٥.٦ﻋﻨﺎﻭﻳﻦ ﺍﳌﻨﺎﻓﺬ ﳌﺘﺤﻜﻢ . . . . . . . . . . . . . . . . . . . . . PIC
١٣٧ . . .٦.٦ﺍﻷﻣﺮ ﺍﻷﻭﻝ . . . . . . . . . . . . . . . . . . . . . . . . ICW1
٦..٧ ICW3 for Primary PIC . . . . . . . . . . . ١٣٨ﺍﻟﺮﺋﻴﺴﻲ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻟﺚ ﺍﻷﻣﺮ
٦..٨ ICW3 for Slave PIC . . . . . . . . . . . . . ١٣٨ﺍﻟﺜﺎﻧﻮﻱ ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻟﺚ ﺍﻷﻣﺮ
٦..٩ ICW4 . . . . . . . . . . . . . . . . . . . . . . . . . . ١٣٩ﺍﻟﺮﺍﺑﻊ ﺍﻷﻣﺮ
١٤٠ . . .١٠.٦ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ ﺍﻟﺜﺎﱐ . . . . . . . . . . . . . . . . . . . . . OCW2
١٤٠ . . .١١.٦ﺃﻣﺮ . . . . . . . . . . . . . . . . . . . . . . . . . . . OCW2
١٤٣ . . .١٢.٦ﻣﺴﺠﻼﺕ ﺍﳌﺆﻗﺘﺔ . . . . . . . . . . . . . . . . . . . . 8253 PIT
ﻳﺞ
ﻣﻠﺨﺺ ﺍﻟﺒﺤﺚ
ﻫﺪﻑ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﻫﻮ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ )ﻧﻈﺎﻡ ﺇﻗﺮﺃ( ﻟﻺﺳﺘﺨﺪﺍﻣﺎﺕ ﺍﻟﺘﻌﻠﻴﻤﻴﺔ ﻭﺍﻷﻛﺎﺩﳝﻴﺔ ﲝﻴﺚ ﻳﻤﻜﱢﻦ ﺍﻟﻄﺎﻟﺐ
ﻣﻦ ﺗﻄﺒﻴﻖ ﻣﺎ ﺗﻌﻠﻤﻪ ﻣﻦ ﻧﻈﺮﻳﺎﺕ ﺧﻼﻝ ﻓﺘﺮﺓ ﺍﻟﺪﺭﺍﺳﺔ ﻋﻠﻰ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﺣﻘﻴﻘﻲ ﳑﺎ ﻳﻜﺴﺒﻪ ﺧﱪﺓ ﻭﻳﺆﻫﻠﻪ ﻟﻠﻤﺸﺎﺭﻛﺔ
ﰲ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺗﺸﻐﻴﻞ ﺿﺨﻤﺔ ﻣﺜﻞ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ .ﻛﺬﻟﻚ ﻳﻬﺪﻑ ﺍﱃ ﺗﻮﻓﲑ ﲝﺜﺎ ﺑﺎﻟﻠﻐﺔ ﺍﻟﻌﺮﺑﻴﺔ ﻳﺸﺮﺡ ﺍﻷﺳﺲ
ﺍﻟﻌﻠﻤﻴﺔ ﻟﻜﻴﻔﻴﺔ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻣﻦ ﺍﻟﺼﻔﺮ ﺩﻭﻥ ﺍﻹﻋﺘﻤﺎﺩ ﻋﻠﻰ ﺃﻱ ﻣﻜﻮﻧﺎﺕ ﺧﺎﺭﺟﻴﺔ ﰲ ﺍﻟﻮﻗﺖ ﺍﻟﺬﻱ ﺗﻨﺪﺭ
ﺗﻮﻓﺮ ﻣﺜﻞ ﻫﺬﻩ ﺍﻟﺒﺤﻮﺙ ﺍﳌﻔﻴﺪﺓ ﻟﻠﻄﺎﻟﺐ ﻭﺧﺎﺻﺔ ﰲ ﻫﺬﺍ ﺍﳌﺠﺎﻝ ﺍﻟﺬﻱ ﻳﻌﺘﱪ ﻣﻦ ﺃﻫﻢ ﺍﳌﺠﺎﻻﺕ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﻮﺏ.
ﻭﺗﻨﺎﻭﻟﺖ ﻫﺬﻩ ﺍﻟﺪﺭﺍﺳﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺃﺳﺎﺳﻴﺎﺕ ﻭﻣﻔﺎﻫﻴﻢ ﻧﻈﻢ ﺍﻟﺘﺸﻐﻴﻞ ﺑﺪءﺍ ﻣﻦ ﻣﺮﺣﻠﺔ ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﺍﻹﻧﺘﻘﺎﻝ
ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﺍﻧﺘﻬﺎءﺍ ﺑﱪﳎﺔ ﻣﺪﻳﺮﺍ ﻟﻠﺬﺍﻛﺮﺓ ﻭﺗﻌﺮﻳﻔﺎﺕ ﻟﺒﻌﺾ ﺍﻟﻌﺘﺎﺩ.
ﻭ ﺭﺅﻳﺔ ﺍﻟﺒﺎﺣﺚ ﰲ ﻫﺬﻩ ﺍﻟﺪﺭﺍﺳﺔ ﻫﻲ ﺃﻥ ﺗﺴﺘﺨﺪﻡ ﻛﻤﻨﻬﺞ ﻟﺘﺪﺭﻳﺲ ﺍﻟﻄﻼﺏ ﰲ ﻣﺎﺩﺓ ﻧﻈﻢ ﺍﻟﺘﺸﻐﻴﻞ ﻭﺃﻥ ﺗﺪﺭﱠﺱ
ﺍﻟﺸﻔﺮﺓ ﺍﳌﺼﺪﺭﻳﺔ ﻟﻠﻨﻈﺎﻡ .ﻭﻻ ﻳﻘﺘﺼﺮ ﻋﻠﻰ ﺫﻟﻚ ﺑﻞ ﻳﺴﺘﻤﺮ ﺍﻟﺘﻄﻮﻳﺮ ﰲ ﺍﻟﻨﻈﺎﻡ ﻟﻴﻜﻮﻥ ﺃﺩﺍﺓ ﺗﻌﻠﻴﻤﻴﺔ )ﻣﻔﺘﻮﺣﺔ
ﺍﳌﺼﺪﺭ( ﻟﻠﻄﻼﺏ ﻭﺍﻟﺒﺎﺣﺜﲔ.
ﻳﻪ
ﻣﻘﺪﻣﺔ ﺍﻟﺒﺤﺚ
ﺗﻠﻌﺐ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺩﻭﺭﴽ ﻣﻬﻤﺎ ﰲ ﺷﱴ ﳎﺎﻻﺕ ﺍﳊﻴﺎﺓ ﺣﻴﺚ ﺃﺻﺒﺤﺖ ﺃﺣﺪ ﺃﻫﻢ ﺍﻟﺮﻛﺎﺋﺰ ﺍﻷﺳﺎﺳﻴﺔ ﻟﺘﺸﻐﻴﻞ
ﻭﺍﺩﺍﺭﺓ ﺃﻱ ﺟﻬﺎﺯ ﺃﻭ ﻋﺘﺎﺩ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺸﺮﺍﺋﺢ ﺍﻻﻟﺘﻜﺮﻭﻧﻴﺔ ﺍﳌﺘﻜﺎﻣﻠﺔ ،ﻓﺒﺪءﺍ ﻣﻦ ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ ﺍﻟﺸﺨﺼﻲ
ﻭ ﺍﳉﻮﺍﻻﺕ ﻭ ﺍﻷﺟﻬﺰﺓ ﺍﻟﻜﻔﻴﺔ ﻭﺍﳌﻀﻤﻨﺔ ) (Embedded Deviceﻭ ﺃﺟﻬﺰﺓ ﺍﻷﻟﻌﺎﺏ ﻭﺍﻟﺼﺮﺍﻓﺎﺕ ﺍﻵﻟﻴﺔ ﻭﺣﱴ
ﺃﺟﻬﺰﺓ ﺍﻟﻔﻀﺎء ﻭﺍﻟﺪﻭﺭﺍﺕ ) (Orbiterﻛﻠﻬﺎ ﺗﻌﻤﻞ ﺑﺄﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ .ﻭﻧﻈﺮﴽ ﻟﺬﻟﻚ ﻓﺎﻥ ﳎﺎﻝ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ﻳﻌﺘﱪ ﻣﻦ ﺃﻫﻢ ﺍﳌﺠﺎﻻﺕ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﺐ ﺍﻟﱵ ﳚﺐ ﺃﻥ ﺗﺄﺧﺬ ﻧﺼﻴﺒﻬﺎ ﻣﻦ ﺍﻟﺒﺤﺚ ﺍﻟﻌﻠﻤﻲ ﻭﺍﻟﺘﻄﺒﻴﻖ ﺍﻟﱪﳎﻲ.
ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﳘﻴﺔ ﻫﺬﺍ ﺍﳌﺠﺎﻝ ﺍﻻ ﺍﻧﻪ ﻳﻨﺪﺭ ﻭﺟﻮﺩ ﲝﻮﺛﺎ ﻓﻴﻪ ﻭﻳﻌﻮﺩ ﺫﻟﻚ ﻟﻌﺪﺓ ﺃﺳﺒﺎﺏ :ﺍﻷﻭﻝ ﻫﻮ ﺗﻨﻮﻉ
ﺍﳌﺠﺎﻻﺕ ﺍﻟﱵ ﳚﺐ ﺩﺭﺍﺳﺘﻬﺎ ﻗﺒﻞ ﺍﳋﻮﺽ ﰲ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﺣﻴﺚ ﻻ ﺑﺪ ﻟﻠﻄﺎﻟﺐ ﺃﻭ ﺍﻟﺒﺎﺣﺚ ﺍﻹﳌﺎﻡ ﺑﻠﻐﺔ
ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ ++ﻭﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ) (Assemblyﺑﺎﻹﺿﺎﻓﺔ ﺍﱃ ﺍﳌﻌﺮﻓﺔ ﺍﻟﺘﺎﻣﺔ ﲟﻌﻤﺎﺭﻳﺔ ﺍﳊﺎﺳﺐ ﻣﻦ ﻣﻌﺎﰿ ﻭﺫﺍﻛﺮﺓ
ﻭﻭﺣﺪﺍﺕ ﺇﺩﺧﺎﻝ ﻭﺇﺧﺮﺍﺝ .ﺃﻣﺎ ﺍﻟﺴﺒﺐ ﺍﻟﺜﺎﱐ ﻓﻬﻮ ﻋﺪﻡ ﺗﻮﻓﺮ ﻣﺮﺍﺟﻊ ﻭﻛﺘﺒﺎ ﺑﺎﻟﻠﻐﺔ ﺍﻟﻌﺮﺑﻴﺔ ﺗﺸﺮﺡ ﺍﻷﺳﺲ ﺍﻟﻌﻠﻤﻴﺔ
ﻟﱪﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ .ﻭﺍﻟﺴﺒﺐ ﺍﻟﺜﺎﻟﺚ ﻫﻮ ﺗﻮﻓﺮ ﻛﻤﻴﺔ ﻛﺒﲑﺓ ﻣﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﰲ ﺍﻟﻮﻗﺖ ﺍﳊﺎﱄ ﲡﻌﻞ ﺍﻟﻄﺎﻟﺐ
ﻳﻌﺘﻘﺪ ﺑﻌﺪﻡ ﺍﳊﻮﺟﺔ ﻟﻠﺒﺤﺚ ﰲ ﻫﺬﺍ ﺍﳌﺠﺎﻝ ﻭﻫﺬﺍ ﻣﻔﻬﻮﻡ ﺧﺎﻃﺊ ﺣﻴﺚ ﺃﻥ ﻣﱪﻣﺞ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻟﻴﺲ ﺑﺎﻟﻀﺮﻭﺭﺓ
ﺃﻥ ﻳﱪﻣﺞ ﻧﻈﺎﻣﺎ ﻣﻦ ﺍﻟﺼﻔﺮ ﻭﺍﳕﺎ ﳝﻜﻦ ﺃﻥ ﻳﻘﻮﻡ ﺑﺎﻟﺘﻌﺪﻳﻞ ﻭﺍﻟﺘﻄﻮﻳﺮ ﰲ ﺃﺣﺪ ﺍﻷﻧﻈﻤﺔ ﺍﳌﻔﺘﻮﺣﺔ ﺍﳌﺼﺪﺭ ﻛﺬﻟﻚ ﺭﲟﺎ
ﻳﻌﻤﻞ ﰲ ﺑﺮﳎﺔ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﱵ ﺗﺘﻄﻠﺐ ﺍﳌﺎﻣﺎ ﺗﺎﻣﺎ ﺑﻔﺎﻫﻴﻢ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻣﺜﻞ ﺑﺮﳎﺔ ﺑﺮﺍﻣﺞ ﺍﺻﻼﺡ ﺍﻟﻘﺎﻃﺎﻋﺎﺕ
ﺍﻟﺘﺎﻟﻔﺔ ) (Bad Sectorsﻭﺍﺳﺘﺮﺟﺎﻉ ﺍﳌﻠﻔﺎﺕ ﺍﳌﻔﻘﻮﺩﺓ ﻭﻏﲑﻫﺎ ﻣﻦ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ.
ﻭﻗﺪ ﻭﺿﻊ ﺍﻟﻜﺎﺗﺐ ﻧﺼﺐ ﻋﻴﻨﻴﻪ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺍﻟﺘﻄﺮﻕ ﻟﻸﻣﻮﺭ ﺍﻟﱪﳎﻴﺔ ﺑﺘﻔﺎﺻﻴﻠﻬﺎ ﻭﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﻛﻴﻔﻴﺔ ﻛﺘﺎﺑﺔ
ﺍﻟﺸﻔﺮﺓ ﻟﻜﻞ ﺟﺰﺋﻴﺔ ﰲ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ .ﻭ ﱂ ﻳﺘﻢ ﺫﻛﺮ ﻛﻞ ﺍﳉﻮﺍﻧﺐ ﺍﻟﻨﻈﺮﻳﺔ ﰲ ﺍﳌﻮﺿﻮﻉ ﻭﻫﺬﺍ ﺑﺴﺒﺐ ﺃﻥ ﺍﻷﻣﻮﺭ
ﺍﻟﻨﻈﺮﻳﺔ ﰲ ﺍﻟﻐﺎﻟﺐ ﺗﺄﺧﺬ ﺑﺎﻟﻄﺎﻟﺐ ﺑﻌﻴﺪﺍ ﻭﲢﺠﺐ ﺭﺅﻳﺘﻪ ﻋﻦ ﺣﻘﻴﻘﺔ ﻋﻤﻞ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ .ﻭﻗﺪ ﰎ ﺑﺮﳎﺔ ﺍﻟﻨﻈﺎﻡ
ﻣﻦ ﺍﻟﺼﻔﺮ ﺩﻭﻥ ﺍﻹﻋﺘﻤﺎﺩ ﻋﻠﻰ ﺃﻱ ﻣﻜﻮﻧﺎﺕ ﺃﻭ ﺷﻔﺮﺍﺕ ﺟﺎﻫﺰﺓ )ﻣﻔﺘﻮﺣﺔ ﺍﳌﺼﺪﺭ( ﻭﻻ ﳝﻜﻦ ﺍﻋﺘﺒﺎﺭ ﻫﺬﺍ ﺇﻋﺎﺩﺓ
ﺍﺧﺘﺮﺍﻉ ﻟﻠﻌﺠﻠﺔ ! ﺑﻞ ﻫﻮ ﺃﺳﺎﺱ ﳝﻜﻦ ﺍﻻﻋﺘﻤﺎﺩ ﻋﻠﻴﻪ ﻭﺗﻌﻠﻴﻢ ﺍﻟﻄﻼﺏ ﻋﻠﻴﻪ ﻭﻫﻜﺬﺍ ﻳﺘﻄﻮﺭ ﺍﳌﺸﺮﻭﻉ ﻭﻳﺘﻘﺪﻡ ﺍﱃ
ﺍﻷﻣﺎﻡ ﻭﰲ ﻧﻔﺲ ﺍﻟﻮﻗﺖ ﺗﺰﺩﺍﺩ ﺧﱪﺓ ﺍﻟﻄﺎﻟﺐ ﺍﻟﻌﻤﻠﻴﺔ ﰲ ﺍﳌﺠﺎﻝ.
ﻭ ﳚﺪﺭ ﺑﻨﺎ ﺍﻳﻀﺎﺡ ﺃﻥ ﻫﺪﻑ ﺍﻟﻨﻈﺎﻡ )ﻧﻈﺎﻡ ﺇﻗﺮﺃ( ﻫﻮ ﻟﻼﺳﺘﺨﺪﺍﻣﺎﺕ ﺍﻷﻛﺎﺩﳝﻴﺔ ﻭﺍﻟﺘﻌﻠﻴﻤﻴﺔ ﻭﻟﻴﺲ ﻟﻠﻤﺴﺘﺨﺪﻡ ﺍﻷﺧﲑ
،ﺣﻴﺚ ﺃﻥ ﺍﳍﺪﻑ ﻫﻮ ﺗﻌﻠﻴﻢ ﺍﻟﻄﺎﻟﺐ ﻋﻠﻰ ﻫﺬﻩ ﺍﻷﺩﺍﺓ ﻭﺍﻋﺪﺍﺩﻩ ﻟﻠﻌﻤﻞ ﻋﻠﻰ ﺃﻧﻈﻤﺔ ﺿﺨﻤﺔ ﻣﺜﻞ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ.
ﻳﺰ
ﺍﻟﻘﺴﻢ .I
Basics ﺍﻷﺳﺎﺳﻴﺎﺕ
.١ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ ﻫﻮ ﳎﻤﻮﻋﺔ ﻣﻦ ﺍﻟﺸﺮﺍﺋﺢ ﺍﻹﻟﻜﺘﺮﻭﻧﻴﺔ ﻭﺍﻟﻌﺘﺎﺩﻳﺎﺕ ﻭﺍﳌﺘﺤﻜﻤﺎﺕ ﺍﳌﺮﺗﺒﻄﺔ ﻣﻊ ﺑﻌﻀﻬﺎ ﻟﺘﻮﻓﲑ ﻣﻨﺼﺔ
ﺗﺸﻐﻴﻠﻴﺔ ﻟﻠﱪﺍﻣﺞ ﻭ ﺍﻟﱵ ﺑﺪﻭﺎ ﻟﻦ ﻳﻌﻤﻞ ﻫﺬﺍ ﺍﳉﻬﺎﺯ .ﻭﳝﻜﻦ ﺗﻘﺴﻴﻢ ﺍﻟﱪﺍﻣﺞ ﲝﺴﺐ ﻃﺒﻴﻌﺔ ﻋﻤﻠﻬﺎ ﻭﻭﻇﻴﻔﺘﻬﺎ ﺍﱃ
ﻗﺴﻤﲔ ﳘﺎ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﻭﺍﻟﱵ ﺻﻤﻤﺖ ﺧﺼﻴﺼﴼ ﳊﻞ ﻣﺸﺎﻛﻞ ﺍﳌﺴﺘﺨﺪﻡ ﻭ ﺑﺮﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﻭﺍﻟﱵ ﺗﺘﺤﻜﻢ ﰲ
ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ،ﻭﻳﻌﺘﱪ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻣﺜﺎﻻ ﻟﱪﺍﻣﺞ ﺍﻟﻨﻈﺎﻡ ﺣﻴﺚ ﻳﺪﻳﺮ ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ ﺑﺎﻹﺿﺎﻓﺔ
ﺍﱃ ﻣﻴﺰﺓ ﻣﻬﻤﺔ ﻭﻫﻲ ﺗﻮﻓﺮ ﺑﻴﺌﺔ ﺗﺸﻐﻴﻞ ﻭﳘﻴﺔ ) (Virtual Machineﻟﱪﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ.
ﻭﻳﻮﺿﺢ ﺍﻟﺘﻌﺮﻳﻒ ﺍﻟﺴﺎﺑﻖ ﻋﺪﺩﴽ ﻣﻦ ﺍﳌﻔﺎﻫﻴﻢ ﺍﻟﱵ ﳚﺐ ﺍﻟﻮﻗﻮﻑ ﻋﻠﻴﻬﺎ ﻭﺗﻮﺿﺤﻴﻬﺎ ﺑﺸﻜﻞ ﻣﻔﺼﻞ .ﻓﺠﻬﺎﺯ
ﺍﳊﺎﺳﺐ ﻫﻮ ﻣﻨﺼﺔ ﺗﺸﻐﻴﻠﻴﺔ ﺣﻘﻴﻘﻴﺔ ﻟﻸﻭﺍﻣﺮ ﻭﻳﺄﰐ ﺫﻟﻚ ﺑﺴﺒﺐ ﻭﺟﻮﺩ ﻣﺘﺤﻜﻢ ﺧﺎﺹ ﳌﻌﺎﳉﺔ ﺍﻷﻭﺍﻣﺮ ﻭﺗﻨﻔﻴﺬﻫﺎ
،ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﻫﻮ ﺍﳌﻌﺎﰿ ) (Processorﺣﻴﺚ ﻳﻌﻤﻞ ﻋﻠﻰ ﺗﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ )ﻣﻦ ﻋﻤﻠﻴﺎﺕ ﺣﺴﺎﺑﻴﺔ ﻭﻣﻨﻄﻘﻴﺔ( ﻭﺇﺭﺳﺎﻝ
ﺍﻟﻨﺘﺎﺋﺞ ﺍﱃ ﺍﻷﻣﺎﻛﻦ ﺍﳌﻄﻠﻮﺑﺔ .ﻭﺗﺴﻤﻰ ﳎﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﻳﻨﻔﺬﻫﺎ ﺍﳌﻌﺎﰿ ﺑﺎﺳﻢ ﺍﻟﱪﺍﻣﺞ ،ﻭﺑﺴﺒﺐ ﺗﻜﻠﻔﺔ ﺑﻨﺎء
ﺍﳌﻌﺎﰿ ﻓﺎﻧﻪ ﻏﺎﻟﺒﴼ ﻣﺎ ﻳﺘﻌﺮﻑ ﻋﻠﻰ ﻋﺪﺩﴽ ﻣﻌﻴﻨﺎ ﻣﻦ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﱵ ﺗﻌﺮﻑ ﲟﺠﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ ).(Instruc on Set
ﻟﺬﻟﻚ ﺣﱴ ﻳﺘﻢ ﺗﻨﻔﻴﺬ ﺃﻭﺍﻣﺮ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﻓﺎﺎ ﳚﺐ ﺃﻥ ﺗﻜﺘﺐ ﻭﻓﻘﺎ ﳌﺠﻤﻮﻋﺔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﻳﺪﻋﻤﻬﺎ ﺍﳌﻌﺎﰿ .١ﻭﺍﻟﺸﻜﻞ
١.١ﻳﻮﺿﺢ ﳕﻮﺫﺟﴼ ﻋﺎﻣﺎ ﻟﺘﻌﻠﻴﻤﺎﺕ ﻭﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ ﺍﻟﱵ ﺗﺘﻜﻮﻥ ﻣﻨﻬﺎ ﺍﻟﱪﺍﻣﺞ .ﻭﺟﺰءﺍ ﻣﻨﻬﺎ ﻫﻲ ﺍﺧﺘﻴﺎﺭﻳﺔ ﻭﺳﻨﺮﻛﺰ
ﻫﻨﺎ ﻋﻠﻰ ﺍﻝ OPCODEﻭﺍﻟﱵ ﲤﺜﻞ ﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ.
ﻭﺗﺸﻜﻞ ﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ ﻟﻐﺔ ﺑﺮﳎﻴﺔ ﻣﻦ ﺧﻼﳍﺎ ﳝﻜﻦ ﺑﺮﳎﺔ ﺍﳊﺎﺳﺐ ﻭﻛﺘﺎﺑﺔ ﺍﻟﱪﺍﻣﺞ ﳊﻞ ﻣﺸﺎﻛﻞ ﺍﳌﺴﺘﺨﺪﻡ ،ﻫﺬﻩ
ﺍﻟﻠﻐﺔ ﺗﺴﻤﻰ ﺑﻠﻐﺔ ﺍﻵﻟﺔ ) . (Machine Languageﻭﺗﺘﻜﻮﻥ ﻫﺬﻩ ﺍﻟﻠﻐﺔ ﻣﻦ ﺍﻟﺮﻣﻮﺯ 0ﻭ 1ﺣﻴﺚ ﺃﻥ ﺃﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ
ﻣﺎ ﻫﻲ ﺍﻻ ﺳﻠﺴﻠﺔ ﻣﻌﻴﻨﺔ ﻣﻦ ﻫﺬﻩ ﺍﻟﺮﻣﻮﺯ .ﻓﻤﺜﻼ ﻟﺘﻌﻴﲔ ﺍﻟﻘﻴﻤﺔ 31744ﻟﻠﻤﺴﺠﻞ ٢ AXﳚﺐ ﺃﻥ ﳛﻮﻱ ﺍﻟﱪﻧﺎﻣﺞ
ﻋﻠﻰ ﺍﻷﻣﺮ .101110001100000000000111ﻭﺑﺎﻟﺘﺎﱄ ﺗﻜﻮﻥ ﻋﻤﻠﻴﺔ ﻛﺘﺎﺑﺔ ﺑﺮﻧﺎﻣﺞ ﻣﺘﻜﺎﻣﻞ ﺬﻩ ﺍﻟﻠﻐﺔ ﺃﻣﺮﴽ
١ﺳﻨﺘﺤﺪﺙ ﻋﻦ ﻣﻌﺎﳉﺎﺕ ﺍﻧﺘﻞ ٣٢ﺑﺖ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﻧﻈﺮﴽ ﻷﺎ ﺍﻷﻛﺜﺮ ﺍﻧﺘﺸﺎﺭﴽ.
٢ﺍﳌﺴﺠﻼﺕ ﻫﻲ ﺫﻭﺍﻛﺮ ﺑﺪﺍﺧﻞ ﺍﳌﻌﺎﰿ.
٣
.١ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ﰲ ﻏﺎﻳﺔ ﺍﻟﺼﻌﻮﺑﺔ ﻭﻛﺬﻟﻚ ﻣﻬﻤﺔ ﺗﻨﻘﻴﺢ ﺍﻟﱪﻧﺎﻣﺞ ﻭﺗﻄﻮﻳﺮﻩ ﰲ ﺍﳌﺴﺘﻘﺒﻞ ﻫﻲ ﻣﻌﻘﺪﺓ ﺃﻳﻀﺎ .ﻟﺬﻟﻚ ﻇﻬﺮﺕ ﻟﻐﺔ
ﺍﻟﺘﺠﻤﻴﻊ ﳊﻞ ﻫﺬﻩ ﺍﳌﺸﻜﻠﺔ ﺣﻴﺚ ﺃﻥ ﺍﻟﻠﻐﺔ ﺗﺪﻋﻢ ﻣﺴﻤﻴﺎﺕ ﻭﳐﺘﺼﺮﺍﺕ ﻟﻠﻤﺴﺠﻼﺕ ﻭﻷﻭﺍﻣﺮ ﺍﳌﻌﺎﰿ ،ﻓﻤﺜﻼ
ﺍﻷﻣﺮ ﺍﻟﺴﺎﺑﻖ ﰲ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻳﻜﻮﻥ ﺑﺎﻟﺼﻮﺭﺓ ﺍﻟﺘﺎﻟﻴﺔ.
Example ١.١: Assembly Language
١ MOV AX,0x7C00 ; Instead of 101110001100000000000111
ﻭﺍﻟﺬﻱ ﳚﺐ ﲢﻮﻳﻠﻪ ﺍﱃ ﻟﻐﺔ ﺍﻵﻟﺔ ﺣﱴ ﻳﺘﻤﻜﻦ ﺍﳌﻌﺎﰿ ﻣﻦ ﺗﻨﻔﻴﺬﻩ ،ﻫﺬﺍ ﺍﳌﺤﻮﻝ ﻳﺴﻤﻰ ﺑﺎﳌﺠﻤﻊ ﻭﺍﻟﺬﻱ ﻳﻘﻮﻡ
ﺑﺘﺤﻮﻳﻞ ﺃﻣﺮ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺍﱃ ﻣﺎ ﻳﻘﺎﺑﻠﻪ ﺑﻠﻐﺔ ﺍﻵﻟﺔ .٣ﻭﱂ ﺗﻨﺠﺢ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﰲ ﺗﻮﻓﲑ ﻟﻐﺔ ﻋﺎﻟﻴﺔ ﺍﳌﺴﺘﻮﻯ ﺗﺒﺴﻂ
ﻋﻤﻠﻴﺔ ﺑﺮﳎﺔ ﺍﻟﱪﺍﻣﺞ ﺑﺸﻜﻞ ﺃﻛﱪ ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﺎ ﳐﺘﺼﺮﺍﺕ ﻟﻠﻐﺔ ﺍﻵﻟﺔ ﻟﺬﻟﻚ ﺳﺮﻋﺎﻥ ﻣﺎ ﰎ ﺗﻄﻮﻳﺮ ﻟﻐﺎﺕ ﻋﺎﻟﻴﺔ
ﺍﳌﺴﺘﻮﻯ ﻣﺜﻞ ﻟﻐﺔ ﺍﻟﺴﻲ ٤ﻭﺍﻟﺴﻲ ++ﲝﻴﺚ ﺗﻜﺘﺐ ﺍﻟﱪﺍﻣﺞ ﻓﻴﻬﺎ ﺑﺸﻜﻞ ﻣﺒﺴﻂ ﺑﻌﻴﺪﴽ ﻋﻦ ﺗﻌﻘﻴﺪﺍﺕ ﺍﻵﻟﺔ ﻭﺃﻭﺍﻣﺮﻫﺎ
ﻭﻣﺴﺠﻼﺎ ﻭﺗﺪﻋﻢ ﻫﺬﻩ ﺍﻟﻠﻐﺎﺕ ﻋﺪﺩﺍ ﻣﻦ ﺍﻟﺘﺮﺍﻛﻴﺐ ﻭﲨﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻟﻌﺎﻟﻴﺔ ﺍﳌﺴﺘﻮﻯ .ﻭﻟﻜﻲ ﻳﻨﻔﺬ ﺍﳌﻌﺎﰿ ﺑﺮﺍﻣﺞ
ﻫﺬﻩ ﺍﻟﻠﻐﺎﺕ ﻓﺎﻧﻪ ﳚﺐ ﺃﻭﻻ ﺗﺮﲨﺔ ﺍﻟﺸﻔﺮﺓ ﺍﳌﺼﺪﺭﻳﺔ ﺍﱃ ﻣﺎ ﻳﻘﺎﺑﻠﻬﺎ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺑﺮﻧﺎﻣﺞ
ﻳﺴﻤﻰ ﺍﳌﺘﺮﺟﻢ ) (Compilerﻭﺑﻌﺪﻫﺎ ﻳﻘﻮﻡ ﺍﳌﺠﻤﻊ ﺑﺘﺤﻮﻳﻞ ﺷﻔﺮﺓ ﺍﻟﺘﺠﻤﻴﻊ ﺍﱃ ﺑﺮﻧﺎﳎﴼ ﺑﻠﻐﺔ ﺍﻵﻟﺔ ﻭﺍﻟﺬﻱ ﻳﺴﺘﻄﻴﻊ
ﺍﳌﻌﺎﰿ ﺗﻨﻔﻴﺬﻩ.
2ﲞﺼﻮﺹ ﲤﺜﻴﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﱪﺍﻣﺞ ﰲ ﺍﳊﺎﺳﺐ ﻓﺈﺎ ﲤﺜﻞ ﺑﻄﺮﻕ ﳐﺘﻠﻔﺔ ﲣﺘﻠﻒ ﻋﻠﻰ ﺣﺴﺐ ﻭﺣﺪﺓ
ﺍﻟﺘﺨﺰﻳﻦ ﻭ ﻟﻜﻨﻬﺎ ﰲ ﺍﻵﺧﺮ ﺗﺴﺘﺨﺪﻡ ﺍﳌﻨﻄﻖ ﺍﻟﺜﻨﺎﺋﻲ ﻭﻫﻮ ﻭﺟﻮﺩ ﻃﺎﻗﺔ ﻛﻬﺮﺑﺎﺋﻴﺔ ﺃﻡ ﻻ ،ﻓﻤﺜﻼ ﺗﺘﻜﻮﻥ
ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ 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ﻭﻟﻴﺲ ﰲ ﺍﳌﺴﺘﻮﻳﺎﺕ ﺍﻷﺧﺮﻯ .٥
٥ﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﱐ ﺑﺈﺫﻥ ﺍﷲ ﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﻣﺴﺘﻮﻳﺎﺕ ﺍﳊﻤﺎﻳﺔ ﰲ ﺍﳌﻌﺎﳉﺎﺕ.
٥
.١ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
٦
.٢.١ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ﻭﺑﻌﺪ ﺣﻮﺍﱄ ٣٠ﻋﺎﻣﴼ ﻗﺎﻡ ﺍﻟﻌﺎﱂ ﺍﻟﺮﻳﺎﺿﻲ ﺟﻮﺗﻔﺮﻳﺪ ﻟﻴﺒﱰ Go ried Wilhelm Leibnizﺑﺒﻨﺎء ﺁﻟﺔ ﺣﺴﺎﺑﻴﺔ
ﻣﻴﻜﺎﻧﻴﻜﻴﺔ ﺃﺧﺮﻯ )ﰎ ﺍﻹﻧﺘﻬﺎء ﻣﻨﻬﺎ ﰲ ﻋﺎﻡ ١٦٩٤ﻭﲰﻴﺖ ﺑﺎﻻﺳﻢ (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ﻭﲰﻴﺖ ﲜﻬﺎﺯ ) Z1ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ (٧.١ﻭﺗﻌﺘﱪ ﺃﻭﻝ ﺣﺎﺳﺒﺔ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺮﻳﻼﻱ ﻭﻋﻠﻰ ﺍﳌﻨﻄﻖ
٧ﰲ ﻋﺎﻡ ١٩٩١ﻗﺎﻡ ﻣﺘﺤﻒ ﺍﻟﻌﻠﻮﻡ ﺑﻠﻨﺪﻥ ﺑﺒﻨﺎء ﳕﻮﺫﺝ ﻣﻜﺘﻤﻞ ﳌﺤﺮﻙ ﺍﻟﻔﺮﻭﻕ.
٨
.٢.١ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ﺍﻟﺜﻨﺎﺋﻲ ﰲ ﻋﻤﻠﻬﺎ .ﻭﻟﺴﻮء ﺍﳊﻆ ﰎ ﺗﺪﻣﲑ ﺍﳊﺎﺳﺒﺔ Z1ﰲ ﺍﻧﻔﺠﺎﺭ ﰲ ﺑﺮﻟﲔ ﺃﺛﻨﺎء ﺍﳊﺮﺏ ﺍﻟﻌﺎﳌﻴﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻋﺎﻡ .١٩٤٣
ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻥ ﺗﺼﻤﻴﻢ Z1ﱂ ﻳﺆﺛﺮ ﰲ ﺗﺼﺎﻣﻴﻢ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﱵ ﺗﻠﻴﻪ ﺑﺴﺒﺐ ﺗﺪﻣﲑﻩ ﻫﻮ ﻭﲨﻴﻊ ﺧﻄﻂ ﺑﻨﺎﺋﻪ
ﺇﻻ ﺃﻧﻪ ﻳﻌﺘﱪ ﺃﺣﺪ ﺍﻟﺘﺼﺎﻣﻴﻢ ﺍﻟﱵ ﻛﺎﻥ ﳍﺎ ﺃﺛﺮﻫﺎ ﺫﺍﻙ ﺍﻟﻮﻗﺖ .ﻭﺑﻌﺪ ﺑﺮﻫﺔ ﻣﻦ ﺍﻟﺰﻣﻦ ﻗﺎﻡ ﺟﻮﻥ ﺃﺗﺎﻧﺎﺳﻮﻑ John
Vincent Atanasoffﺑﺘﺼﻤﻴﻢ ﺟﻬﺎﺯ )Atanasoffﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ??( ﻭﺍﻟﺬﻱ ﻛﺎﻥ ﻣﺪﻫﺸﺎ ﰲ ﻭﻗﺘﻪ ﺣﻴﺚ ﻳﺴﺘﺨﺪﻡ
ﺍﻟﺘﺤﺴﻴﺐ ﺍﻟﺜﻨﺎﺋﻲ ) (Binray Arithme cﻭﳛﻮﻱ ﻣﻜﺜﻔﺎﺕ ﻟﻠﺬﺍﻛﺮﺓ ﻭﻟﻜﻦ ﺍﳉﻬﺎﺯ ﱂ ﻳﻜﻦ ﻋﻤﻠﻴﺎ .ﻭﰲ ﺑﺪﺍﻳﺎﺕ
١٩٤٠ﻗﺎﻡ ﻫﻮﺍﺭﺩ ﺍﻳﻜﲔ Howard Aikenﺑﺘﺼﻤﻴﻢ ﺍﳊﺎﺳﺒﺔ - ASCCﻭﺍﻟﱵ ﺃﻋﻴﺪ ﺗﺴﻤﻴﺘﻬﺎ ﺍﱃ Harvard Mark
- Iﰲ ﺟﺎﻣﻌﺔ ﻫﺎﻓﺎﺭﺩ )ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ .(٩.١ﻭﻗﺪ ﺃﺗﺒﻊ ﻫﻮﺍﺭﺩ ﻧﻔﺲ ﻣﻨﻬﺞ ﺑﺎﺑﺒﺎﺝ ﻭﻗﺮﺭ ﺃﻥ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺍﻟﺮﻳﻼﻱ
ﻭﺃﻥ ﻳﺼﻤﻢ ﺣﺎﺳﺒﺔ ﻟﻸﻏﺮﺍﺽ ﺍﻟﻌﺎﻣﺔ ﻭﺍﻟﱵ ﻓﺸﻞ ﺎ ﺷﺎﺭﻟﺰ ﺑﺎﺑﺒﺎﺝ.ﻭﰲ ﻋﺎﻡ ١٩٤٤ﰎ ﺍﻹﻧﺘﻬﺎء ﻣﻦ ﺗﺼﻤﻴﻤﻬﺎ ﻭﰎ
ﺗﺼﻤﻴﻢ ﻧﺴﺨﺔ ﳏﺴﻨﺔ ﺃﻳﻀﺎ ﲰﻴﺖ ﺏ .Harvard Mark IIﻭﻣﻊ ﻫﺬﺍ ﺍﻟﺘﺼﻤﻴﻢ ﺍﻧﺘﻬﻰ ﻋﺼﺮ ﺍﳊﺎﺳﺒﺎﺕ ﺍﳌﻴﻜﺎﻧﻴﻜﻴﺔ
٩
.١ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
)ﺏ( ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻭﺍﻟﺘﺤﻜﻢ Mark I )ﺍ( ﺍﳉﺰء ﺍﻷﻳﺴﺮ ﻣﻦ ﺣﺎﺳﺒﺔ
Harvard Mark I ﺷﻜﻞ :.٩.١ﺣﺎﺳﺒﺔ
١٠
.٢.١ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ﺳﺮﻳﺎ ﳛﻮﻱ ﻋﻠﻰ ﺣﺎﺳﺒﺔ ﺍﻟﻜﺘﺮﻭﻧﻴﺔ ﻋﺮﻓﺖ ﺑﺎﻻﺳﻢ .Colossusﻫﺬﻩ ﺍﳊﺎﺳﺒﺔ ﰎ ﺗﺼﻤﻴﻤﻬﺎ ﻣﻦ ﻗﺒﻞ ﻋﺪﺓ ﺃﺷﺨﺎﺹ
ﻭﺷﺎﺭﻙ ﻓﻴﻬﺎ ﺍﻟﻌﺎﱂ ﺁﻻﻥ ﺗﻮﺭﻧﺞ ﻭﺃﺻﺒﺤﺖ ﺟﺎﻫﺰﺓ ﻟﻠﻌﻤﻞ ﰲ ﻋﺎﻡ .١٩٤٣ﻭﺑﺴﺒﺐ ﻛﻮﻥ ﺍﳌﺸﺮﻭﻉ ﺳﺮﻳﺎ ﻭﰎ
ﺍﻟﺘﻜﺘﻢ ﻋﻠﻴﻪ ﳌﺎ ﻳﻘﺎﺭﺏ ٣٠ﻋﺎﻣﺎ ﻓﺎﻥ ﻫﺬﺍ ﺍﻟﻨﻮﻉ ﻣﻦ ﺍﳊﻮﺍﺳﻴﺐ ﱂ ﻳﺆﺛﺮ ﻋﻠﻰ ﺗﺼﺎﻣﻴﻢ ﺍﳊﻮﺍﺳﻴﺐ ﺍﳊﺪﻳﺜﺔ ﻭﻟﻜﻦ
ﳚﺪﺭ ﺑﺎﻟﺬﻛﺮ ﺃﻥ ﻫﺬﻩ ﺍﳊﺎﺳﺒﺔ ﺗﻌﺘﱪ ﺃﻭﻝ ﺣﺎﺳﺒﺔ ﺇﻟﻜﺘﺮﻭﻧﻴﺔ ﻗﺎﺑﻠﺔ ﻟﻠﱪﳎﺔ ﺗﺴﺘﺨﺪﻡ ﺍﻟﺼﻤﺎﻣﺎﺕ ﺍﳍﻮﺍﺋﻴﺔ ﰲ ﺣﺴﺎﺑﺎﺎ.
ﻭﰲ ﻋﺎﻡ ١٩٤٣ﻗﺪﻡ ﺟﻮﻥ ﻣﻮﻛﻠﻲ John Mauchleyﻣﻘﺘﺮﺣﴼ ﺍﱃ ﺍﳉﻴﺶ ﺍﻷﻣﺮﻳﻜﻲ ﻃﺎﻟﺒﴼ ﲤﻮﻳﻠﻪ ﺑﺎﳌﺎﻝ ﻟﻠﺒﺪء
ﺑﺘﺼﻤﻴﻢ ﺣﺎﺳﺒﺔ ﺇﻟﻜﺘﺮﻭﻧﻴﺔ ﳊﺴﺎﺏ ﺟﺪﺍﻭﻝ ﺇﻃﻼﻕ ﺍﳌﺪﻓﻌﻴﺎﺕ ﺑﺪﻻﹰ ﻣﻦ ﺣﺴﺎﺎ ﻳﺪﻭﻳﺎ ﻭﺫﻟﻚ ﻟﺘﻘﻠﻴﻞ ﺍﻷﺧﻄﺎء
ﻭﻛﺴﺐ ﺍﻟﻮﻗﺖ ،ﻭﻗﺪ ﲤﺖ ﺍﳌﻮﺍﻓﻘﺔ ﻋﻠﻰ ﺍﳌﺸﺮﻭﻉ ﻭﺑﺪﺃ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ﻭﻃﺎﻟﺒﻪ ﺍﳋﺮﻳﺞ ﺇﻳﻜﺮﻳﺖ ﺑﺒﻨﺎء ﺣﺎﺳﺒﺔ
ﰎ ﺗﺴﻤﻴﺘﻬﺎ ﺑﺎﻻﺳﻢ ﺇﻳﻨﺎﻙ ENIACﺍﺧﺘﺼﺎﺭﺍ ﻟﻠﺠﻤﻠﺔ .Electronic Numerical Integrator And Computer
ﻭﺗﺘﻜﻮﻥ ﻣﻦ ١٨٠٠٠ﺻﻤﺎﻣﺎ ﻣﻔﺮﻏﺎ ) (Vacuum Tubesﻭ ١٥٠٠ﺣﺎﻛﻤﺔ ) ، (Relaysﻭﺗﺰﻥ ﺍﳊﺎﺳﺒﺔ ٣٠
ﻃﻦ ﻭﺗﺴﺘﻬﻠﻚ ١٤٠ﻛﻴﻠﻮ ﻭﺍﻁ ﻣﻦ ﺍﻟﻄﺎﻗﺔ .ﻭﺩﺍﺧﻠﻴﺎ ﲢﺘﻮﻱ ﺍﳊﺎﺳﺒﺔ ﻋﻠﻰ ٢٠ﻣﺴﺠﻞ ﻛﻞ ﻣﻨﻬﻢ ﻳﺴﻊ ﻋﺪﺩﺍ
ﺻﺤﻴﺤﺎ ﺑﻄﻮﻝ ١٠ﺧﺎﻧﺎﺕ .ﻭﺗﺘﻢ ﺑﺮﳎﺔ ﺇﻳﻨﺎﻙ ﻋﻦ ﻃﺮﻳﻖ ٦٠٠٠ﻣﻔﺘﺎﺡ .Switch
ﻭﻗﺪ ﰎ ﺍﻹﻧﺘﻬﺎء ﻣﻦ ﺗﺼﻤﻴﻢ ﺇﻳﻨﺎﻙ ﻋﺎﻡ ، ١٩٤٦ﺍﻟﻮﻗﺖ ﺍﻟﺬﻱ ﻛﺎﻧﺖ ﺍﳊﺮﺏ ﻗﺪ ﺍﻧﺘﻬﺖ ﻭﱂ ﺗﺴﺘﺨﺪﻡ ﺍﳊﺎﺳﺒﺔ
ﳍﺪﻓﻬﺎ ﺍﻟﺮﺋﻴﺴﻲ .ﻭﺑﻌﺪ ﺫﻟﻚ ﻧﻈﻢ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ﻭﻃﺎﻟﺒﻪ ﺇﻳﻜﺮﻳﺖ ﻣﺪﺭﺳﺔ ﺻﻴﻔﻴﺔ ﻟﻮﺻﻒ ﻣﺸﺮﻭﻋﻬﻢ ﻟﻠﺒﺎﺣﺜﲔ
ﻭﺍﳌﻬﺘﻤﲔ .ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﺃﺳﻔﺮ ﻋﻦ ﻇﻬﻮﺭ ﻋﺪﺩ ﻛﺒﲑ ﻣﻦ ﺍﳊﺎﺳﺒﺎﺕ ﺍﻟﻀﺨﻤﺔ .ﻭﺃﻭﻝ ﺣﺎﺳﺒﺔ ﺑﻌﺪﻫﺎ ﻛﺎﻧﺖ
١١
.١ﻣﻘﺪﻣﺔ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
ILLIAC EDSACﰲ ﻋﺎﻡ ١٩٤٩ﺑﻮﺍﺳﻄﺔ ﻭﻳﻠﻜﺲ ﰲ ﺟﺎﻣﻌﺔ ﻛﺎﻣﱪﺩﺝ .ﻛﺬﻟﻚ ﺗﻠﺘﻪ ﺍﳊﺎﺳﺒﺎﺕ JOHNIACﻭ
ﻭﻏﲑﻫﻢ.ﺑﻌﺪ ﺫﻟﻚ ﺑﺪﺃ ﺟﻮﻥ ﻣﻮﻛﻠﻲ ﻭﺇﻳﻜﺮﻳﺖ ﺑﺎﻟﻌﻤﻞ ﻋﻠﻰ ﺣﺎﺳﺒﺔ ﺃﺧﺮﻯ ﲰﻴﺖ ﺑﺎﻻﺳﻢ EDVACﺍﺧﺘﺼﺎﺭﺍ
ﻟﻠﺠﻤﻠﺔ Electronic Discrete Variable Automa c Computerﻭﺍﻟﱵ ﻛﺎﻧﺖ ﺗﻌﻤﻞ ﺑﺎﻷﺭﻗﺎﻡ ﺍﻟﺜﻨﺎﺋﻴﺔ ﺑﺪﻻ ﻣﻦ
ﺍﻟﻌﺸﺮﻳﺔ )ﻛﻤﺎ ﰲ ﺇﻳﻨﺎﻙ(.ﺑﻌﺪ ﺫﻟﻚ ﺗﻮﻗﻒ ﺍﳌﺸﺮﻭﻉ ﺑﺴﺒﺐ ﺃﻥ ﺟﻮﻥ ﻭﺇﻳﻜﺮﻳﺖ ﻗﺪ ﺃﻧﺸﺌﺎ ﺷﺮﻛﺘﻬﻢ ﺍﳋﺎﺻﺔ.
١٢
.٢.١ﺗﺎﺭﻳﺦ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ
١٣
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
ﺣﻮﺍﺳﻴﺐ ﻋﺎﺋﻠﺔ x86ﺗﺘﺒﻊ ﳌﻌﻤﺎﺭﻳﺔ ﺍﻟﻌﺎﱂ ﺟﻮﻥ ﻓﻮﻥ ﻧﻴﻮﻣﺎﻥ ) (John von Neumann architectureﻭﺍﻟﱵ ﺗﻨﺺ
ﻋﻠﻰ ﺃﻥ ﺃﻱ ﺗﺼﻤﻴﻢ ﳉﻬﺎﺯ ﺣﺎﺳﺐ ﳚﺐ ﺃﻥ ﻳﺘﻜﻮﻥ ﻣﻦ ﺍﻟﺜﻼﺙ ﻭﺣﺪﺍﺕ ﺍﻟﺘﺎﻟﻴﺔ :
.١ﻣﻌﺎﰿ ﺃﻭ ﻭﺣﺪﺓ ﻣﻌﺎﳉﺔ ﻣﺮﻛﺰﻳﺔ ).(Central Processing Unit
.٢ﺫﺍﻛﺮﺓ ).(Memory
.٣ﺃﺟﻬﺰﺓ ﺇﺩﺧﺎﻝ ﻭﺇﺧﺮﺍﺝ ).(I/O Devices
ﺍﻟﻮﺣﺪﺓ ﺍﻻﻭﱃ ﻫﻲ ﻭﺣﺪﺓ ﺍﳌﻌﺎﳉﺔ ﻭﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﻭﺍﻟﻌﻤﻠﻴﺎﺕ ﺍﳊﺴﺎﺑﻴﺔ ،ﺃﻣﺎ ﺍﻟﻮﺣﺪﺓ ﺍﻟﺜﺎﻧﻴﺔ ﻓﻬﻲ
ﲢﻮﻱ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﺘﻌﻠﻴﻤﺎﺕ ﻭﺍﻷﻭﺍﻣﺮ ﺍﻟﱵ ﳚﺐ ﻋﻠﻰ ﻭﺣﺪﺓ ﺍﳌﻌﺎﳉﺔ ﺃﻥ ﺗﻨﻔﺬﻫﺎ ،ﻭﺃﺧﲑﴽ ﻭﺣﺪﺍﺕ ﺍﻹﺩﺧﺎﻝ
ﻭﺍﻹﺧﺮﺍﺝ ﻭﻫﻲ ﺍﻻﺟﻬﺰﺓ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﰲ ﺍﺩﺧﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﺧﺮﺍﺟﻬﺎ).ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ ١.٢ﺣﻴﺚ ﻳﻮﺿﺢ ﻣﺜﺎﻻً
ﳍﺬﻩ ﺍﳌﻌﻤﺎﺭﻳﺔ( ﻭﻳﺮﺑﻂ ﺑﲔ ﻛﻞ ﻫﺬﻩ ﺍﻷﺟﺰﺍء ﻫﻮ ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ ) (System Busﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺳﻨﺴﺘﻌﺮﺽ ﻭﻇﻴﻔﺔ
ﻛﻞ ﺟﺰء ﻋﻠﻰ ﺣﺪﺓ.
١٥
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
.١.٢ﻣﻌﻤﺎﺭﻳﺔ ﺍﻟﻨﻈﺎﻡ
ﻳﺮﺑﻂ ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ (System Bus) ١ﻭﺣﺪﺓ ﺍﳌﻌﺎﳉﺔ ﺍﳌﺮﻛﺰﻳﺔ ) (CPUﻣﻊ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ .ﻭ ﻭﻇﻴﻔﺔ
ﻫﺬﻩ ﺍﳌﺴﺎﺭﺍﺕ ﻫﻲ ﻧﻘﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﲔ ﺃﺟﺰﺍء ﺍﳊﺎﺳﺐ ﺍﳌﺨﺘﻠﻔﺔ .ﻭﺍﻟﺸﻜﻞ ٢.٢ﻳﻮﺿﺢ ﺍﻟﺼﻮﺭﺓ ﺍﻟﻌﺎﻣﺔ ﻟﻠﻤﺴﺎﺭﺍﺕ
ﰲ ﺃﺟﻬﺰﺓ ﺍﳊﻮﺍﺳﻴﺐ ﺍﻟﺸﺨﺼﻴﺔ ) .(Personal Computersﻭﻳﺘﺄﻟﻒ ﻣﺴﺎﺭ ﺍﻟﻨﻈﺎﻡ ﻣﻦ ﺛﻼﺙ ﻣﺴﺎﺭﺍﺕ :ﻣﺴﺎﺭ
ﺍﻟﺒﻴﺎﻧﺎﺕ ) (Data Busﻭﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ) (Address Busﻭﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ ).(Control Bus
١٦
.١.٢ﻣﻌﻤﺎﺭﻳﺔ ﺍﻟﻨﻈﺎﻡ
١٧
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
.٢.١.٢ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ
ﻗﺒﻞ ﺫﻛﺮ ﻭﻇﻴﻔﺔ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﳚﺐ ﺇﻋﻄﺎء ﻧﺒﺬﺓ ﻋﻦ ﻣﺎﻫﻴﺔ ﺍﳌﺘﺤﻜﻤﺎﺕ ) (Controllersﰲ ﺟﻬﺎﺯ ﺍﳊﺎﺳﺐ.
ﻭﻳُﻌﺮﱠﻑ ﺍﳌﺘﺤﻜﻢ ﺑﺄﻧﻪ ﺷﺮﳛﺔ ﺗﺘﺤﻜﻢ ﺑﻌﺘﺎﺩ ﻣﺎ ﲢﻮﻱ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﺍﻟﺪﺍﺧﻠﻴﺔ ﻭﻇﻴﻔﺘﻬﺎ ﻫﻲ ﺍﺳﺘﻘﺒﺎﻝ
ﺍﻷﻭﺍﻣﺮ ﻭﺗﻨﻔﻴﺬﻫﺎ ﻋﻠﻰ ﺍﻟﻌﺘﺎﺩ .ﻭﳝﻜﻦ ﺗﻌﺮﻳﻔﻬﺎ ﻛﺬﻟﻚ ﺑﺄﺎ ﺷﺮﳛﺔ ﻟﻠﺮﺑﻂ ﻣﺎ ﺑﲔ ﺍﻷﻭﺍﻣﺮ ﺍﻟﱪﳎﻴﺔ ﺍﱃ ﺃﻭﺍﻣﺮ ﺗﻨﻔﺬ
ﻋﻠﻰ ﻋﺘﺎﺩ ﻣﺎ .ﻭﺃﻱ ﻣﺘﺤﻜﻢ ﳛﻮﻱ ﻏﺎﻟﺒﺎ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺴﺠﻼﺕ ﺳﻮﺍءﺍ ﻛﺎﻧﺖ ﻹﺭﺳﺎﻝ ﻭﺍﺳﺘﻘﺒﺎﻝ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺃﻭ
ﻟﻸﻭﺍﻣﺮ ،ﻭﺃﻱ ﻣﺴﺠﻞ ﳚﺐ ﺃﻥ ﻳﺄﺧﺬ ﺭﻗﻢ ﻓﺮﻳﺪ ﳝﻴﺰﻩ ﻋﻦ ﺑﻘﻴﺔ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﺃﻭ ﰲ
ﺃﻱ ﻣﺘﺤﻜﻢ ﺁﺧﺮ ﻭﺫﻟﻚ ﺣﱴ ﳝﻜﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ ﺑﺮﳎﻴﴼ ،ﻫﺬﺍ ﺍﻟﺮﻗﻢ ﻳﻌﺮﻑ ﺑﺎﺳﻢ ﺍﳌﻨﻔﺬ ) (Portﻭﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ
ﻋﻨﻪ ﻻﺣﻘﴼ .ﻭﻋﻤﻞ ﺍﳌﺘﺤﻜﻢ ﻳﺒﺪﺃ ﻋﻨﺪﻣﺎ ﻳﺮﺳﻞ ﺃﻣﺮ ﺍﻟﻴﻪ ﺣﻴﺚ ﻳﺒﺪﺃ ﺍﳌﺘﺤﻜﻢ ﰲ ﺗﻨﻔﻴﺬ ﻫﺬﺍ ﺍﻷﻣﺮ ﻭﻣﻦ ﰒ ﻳﻀﻊ
ﺍﻟﻨﺘﻴﺠﺔ ﰲ ﺃﺣﺪ ﻣﺴﺠﻼﺗﻪ ﻭﻳﺮﺳﻞ ﺇﺷﺎﺭﺓ ) (Interruptﺍﱃ ﺍﳌﻌﺎﰿ ﻟﻜﻲ ﻳﻘﻮﻡ ﺑﻘﺮﺍﺋﺔ ﺍﻟﻘﻴﻤﺔ.
ﻭﻋﻮﺩﺓ ﺑﺎﳊﺪﻳﺚ ﻋﻦ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺍﻟﺬﻱ ﻳﺘﻮﺍﺟﺪ ﻏﺎﻟﺒﺎ ﻋﻠﻰ ﻣﺘﺤﻜﻢ ﺍﳉﺴﺮ ﺍﻟﺸﻤﺎﱄ )(NorthBridge
ﺇﻧﻈﺮ ﺍﻟﺸﻜﻞ . ٣.٢ﺣﻴﺚ ﺗﻜﻤﻦ ﻭﻇﻴﻔﺘﻪ ﺍﻷﺳﺎﺳﻴﺔ ﰲ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺗﻨﻔﻴﺬﻫﺎ ،ﻭﻳﻘﻮﻡ
ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﺑﺘﻮﺟﻴﻪ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﺃﻱ ﻣﻦ ﺷﺮﺍﺋﺢ ﺍﻟﺬﺍﻛﺮﺓ ﻛﺬﻟﻚ ﻳﻘﻮﻡ ﺑﺈﻋﺎﺩﺓ ﺗﻨﻌﻴﺶ ) (Refreshﻫﺬﻩ
ﺍﻟﺬﺍﻛﺮﺓ ﻃﻴﻠﺔ ﻋﻤﻞ ﺍﳊﺎﺳﺐ ﺣﱴ ﻻ ﺗﻔﻘﺪ ﺍﻟﺬﺍﻛﺮﺓ ﳏﺘﻮﻳﺎﺎ.
١٨
.٢.٢ﺍﳌﻌﺎﰿ
(Soﲝﻴﺚ ﲤﻴﺰ ﻫﺬﻩ ﺍﻷﺭﻗﺎﻡ ﺍﳌﺴﺠﻼﺕ )ware Ports ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﺗﺄﺧﺬ ﺃﺭﻗﺎﻣﺎ ﻣﻌﻴﻨﺔ ﺗﺴﻤﻰ ﻣﻨﺎﻓﺬ ﺑﺮﳎﻴﺔ
ﻣﻦ ﺑﻌﻀﻬﺎ ﺍﻟﺒﻌﺾ .٣
Ports ﺍﳌﻨﺎﻓﺬ
ﻳﺴﺘﺨﺪﻡ ﻣﻔﻬﻮﻡ ﺍﳌﻨﺎﻓﺬ ﰲ ﻋﻠﻮﻡ ﺍﳊﺎﺳﺐ ﻟﻠﺪﻻﻟﺔ ﻋﻠﻰ ﻋﺪﺓ ﺃﺷﻴﺎء ﻓﻤﺜﻼ ﰲ ﳎﺎﻝ ﺑﺮﳎﺔ ﺍﻟﺸﺒﻜﺎﺕ ﺗﻜﻮﻥ ﺑﺮﺍﻣﺞ
ﺍﳋﺎﺩﻡ ﳍﺎ ﺭﻗﻢ ﻣﻨﻔﺬ ﻣﻌﲔ ﺣﱴ ﺗﺴﻤﺢ ﻟﱪﺍﻣﺞ ﺍﻟﻌﻤﻴﻞ ﺑﺎﻻﺗﺼﺎﻝ ﻣﻌﻬﺎ ،ﻛﺬﻟﻚ ﺭﲟﺎ ﻳﻘﺼﺪ ﺑﺎﳌﻔﻬﻮﻡ ﺍﳌﻨﺎﻓﺬ ﺍﳌﻮﺟﻮﺩﺓ
ﰲ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ ﻟﻮﺻﻞ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ﺎ ،ﺃﻳﻀﺎ ﻗﺪ ﻳﺪﻝ ﺍﳌﻔﻬﻮﻡ ﻋﻠﻰ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﰲ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻋﻠﻰ
ﺍﳉﻬﺎﺯ ﻭﻫﺬﺍ ﻣﺎ ﺳﻨﻘﺼﺪﻩ ﰲ ﺣﺪﻳﺜﻨﺎ ﻋﻦ ﺍﳌﻨﺎﻓﺬ ﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ .ﻭ ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﳌﻨﺎﻓﺬ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻭﺍﻟﱵ
ﺗﻌﺮﻑ ﺏ I/O portsﺑﺎﺳﺘﺨﺪﺍﻡ ﺗﻌﻠﻴﻤﺔ ﺍﳌﻌﺎﰿ in port addressﻭﺍﻟﺘﻌﻠﻴﻤﺔ out port address
ﺣﻴﺚ ﺗﺴﺘﺨﺪﻡ ﺍﻷﻭﱃ ﻟﻘﺮﺍءﺓ ﻗﻴﻤﺔ ﻣﻦ ﻣﺴﺠﻞ ﰲ ﻣﺘﺤﻜﻢ ﻭﻭﺿﻌﻬﺎ ﰲ ﺃﺣﺪ ﻣﺴﺠﻼﺕ ﺍﳌﻌﺎﰿ ﺃﻣﺎ ﺍﻟﺘﻌﻠﻴﻤﺔ
ﺍﻟﺜﺎﻧﻴﺔ ﺗﺴﺘﺨﺪﻡ ﻟﻜﺘﺎﺑﺔ ﻗﻴﻤﺔ ﰲ ﻣﺴﺠﻞ ﻟﻠﻤﻌﺎﰿ ﺍﱃ ﻣﺴﺠﻞ ﰲ ﺍﳌﺘﺤﻜﻢ .ﻭﻋﻨﺪ ﺍﺳﺘﺨﺪﺍﻡ ﺃﺣﺪ ﻫﺬﻳﻦ ﺍﻷﻣﺮﻳﻦ
ﻓﺎﻥ ﺫﻟﻚ ﻳﻌﲏ ﺃﻥ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻮﺟﻪ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻭﻟﻴﺲ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﻳﻘﻮﻡ ﺍﳌﻌﺎﰿ
ﺑﺘﻌﲔ ﻗﻴﻤﺔ ﺍﳋﻂ ACCESSﺍﳌﻮﺟﻮﺩ ﰲ ﻣﺴﺎﺭ ﺍﻟﺘﺤﻜﻢ ) (Control Busﻭﺑﺎﻟﺘﺎﱄ ﻳﺴﺘﺠﻴﺐ ﻣﺘﺤﻜﻢ ﺍﻹﺩﺧﺎﻝ
ﻭﺍﻹﺧﺮﺍﺝ ﻭﻳﻘﺮﺃ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻭﻳﻘﻮﻡ ﺑﺘﻮﺟﻴﻬﻪ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﳌﻄﻠﻮﺏ .ﻭﻫﻨﺎﻙ ﺑﻌﺾ ﺍﻷﺟﻬﺰﺓ ﺗﺴﺘﺨﺪﻡ ﻋﻨﻮﺍﻳﻦ
ﺍﻟﺬﺍﻛﺮﺓ ﻟﻠﻮﺻﻮﻝ ﻟﻠﻤﺘﺤﻜﻢ ﺍﳋﺎﺹ ﺎ ﻭﻫﻮ ﻣﺎ ﻳﻌﺮﻑ ﺏ Memory Mapped I/Oﺣﻴﺚ ﻋﻨﺪ ﻛﺘﺎﺑﺔ ﺃﻱ ﺑﻴﺎﻧﺎﺕ
ﻋﻠﻰ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻓﺎﻥ ﺫﻟﻚ ﻳﻌﲏ ﻛﺘﺎﺑﺔ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻋﻠﻰ ﻣﺘﺤﻜﻤﺎﺕ ﻟﻸﺟﻬﺰﺓ ﻭﻟﻴﺲ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ.
ﻓﻤﺜﻼً ﻋﻨﺪ ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺍﻟﺬﺍﻛﺮﺓ 0xa000:0x0ﻓﺎﻥ ﻫﺬﺍ ﻳﺆﺩﻱ ﺍﱃ ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻰ ﺷﺎﺷﺔ ﺍﳊﺎﺳﺐ ﻧﻈﺮﴽ
ﻻﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ ﻣﻮﺟﻪ ) (Memory Mappedﻣﻊ ﻣﺘﺤﻜﻢ ﺷﺎﺷﺔ ﺍﳊﺎﺳﺐ ﻭﺍﳉﺪﻭﻝ ١.٢ﻳﻮﺿﺢ ﺧﺮﻳﻄﺔ
ﺍﻟﺬﺍﻛﺮﺓ ﰲ ﺣﻮﺍﺳﻴﺐ ،x86ﻭﻻ ﲢﺘﺎﺝ ﺍﻟﻜﺘﺎﺑﺔ ﳌﺜﻞ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻷﻭﺍﻣﺮ in/outﺑﻌﻜﺲ ﺍﻟﻜﺘﺎﺑﺔ
ﰲ ﻋﻨﻮﺍﻳﻦ ﺍﳌﻨﺎﻓﺬ . port I/O
ﻋﻨﺎﻭﻳﻦ ﻣﻨﺎﻓﺬ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ) (Port I/Oﻫﻲ ﻋﻨﺎﻭﻳﻦ ﺗﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﺴﺠﻼﺕ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﺘﺤﻜﻤﺎﺕ
ﻭﻳﻘﻮﻡ ﺍﻟﺒﺎﻳﻮﺱ ﲟﻬﻤﺔ ﺗﺮﻗﻴﻢ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ،ﻭﺍﳉﺪﻭﻝ ٢.٢ﻳﻌﺮﺽ ﻗﺎﺋﻤﺔ ﺑﻌﻨﺎﻭﻳﻦ ﺍﳌﻨﺎﻓﺬ ﻭﻭﻇﻴﻔﺔ ﻛﻞ ﻣﻨﻬﻢ.
.٢.٢ﺍﳌﻌﺎﰿ
ﻳﻌﺘﱪ ﺍﳌﻌﺎﰿ ﻫﻮ ﺍﳌﺤﺮﻙ ﺍﻟﺮﺋﻴﺴﻲ ﳉﻬﺎﺯ ﺍﳊﺎﺳﺐ ﺣﻴﺚ ﻳﺴﺘﻘﺒﻞ ﺍﻷﻭﺍﻣﺮ ﻭﻳﻘﻮﻡ ﺑﺘﻔﻴﺬﻫﺎ .
٣ﻫﻨﺎﻙ ﺑﻌﺾ ﺍﳌﺴﺠﻼﺕ ﻟﺒﻌﺾ ﺍﳌﺘﺤﻜﻤﺎﺕ ﺗﺄﺧﺬ ﻧﻔﺲ ﺍﻟﺮﻗﻢ ،ﻟﻜﻦ ﻃﺒﻴﻌﺔ ﺍﻷﻣﺮ ﺍﳌُﺮﺳﻞ )ﻗﺮﺍءﺓ ﺃﻭ ﻛﺘﺎﺑﺔ( ﻫﻮ ﺍﻟﺬﻱ ﳛﺪﺩ ﺍﳌﺴﺠﻞ
ﺍﻟﺬﻱ ﳚﺐ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ.
١٩
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
ﺃﻭﻻﹰ ﻣﺮﺣﻠﺔ ﺟﻠﺐ ﺍﻟﺒﻴﺎﻧﺎﺕ ) (Fetchﻭﻓﻴﻬﺎ ﻳﺘﻢ ﺟﻠﺐ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﺍﱃ ﺍﳌﺴﺠﻼﺕ ﺑﺪﺍﺧﻞ
ﺍﳌﻌﺎﰿ.
ﺛﺎﻧﻴﴼ ﻣﺮﺣﻠﺔ ﺗﻔﺴﲑ ﺍﻟﺒﻴﺎﻧﺎﺕ ).(Decode
ﺛﺎﻟﺜﴼ ﻣﺮﺣﻠﺔ ﺗﻨﻔﻴﺬ ﺍﻟﺒﻴﺎﻧﺎﺕ ).(Execute
ﺭﺍﺑﻌﴼ ﻣﺮﺣﻠﺔ ﺣﻔﻆ ﺍﻟﻨﺘﺎﺋﺞ ).(Write back
٢٠
ﺍﳌﻌﺎﰿ.٢.٢
ﺍﳌﻌﺎﰿ ﺃﺛﻨﺎء ﻋﻤﻠﻪ ﻟﺘﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﻓﻤﺜﻼ ﳛﺪﺩ ﺍﻟﻨﻤﻂ ﺍﳌﺴﺘﺨﺪﻡ ﻣﺎ ﺇﺫﺍ ﻛﺎﻥ ﻫﻨﺎﻙ ﲪﺎﻳﺔ ﻟﻌﻨﻮﺍﻳﻦ ﺍﻟﺬﺍﻛﺮﺓ ﲝﻴﺚ ﻻ
ﳝﻜﻦ ﻟﱪﻧﺎﻣﺞ ﻻ ﳝﺘﻠﻚ ﺻﻼﺣﻴﺎﺕ ﻣﻌﻴﻨﺔ ﺍﻟﻮﺻﻮﻝ ﻷﻱ ﻣﻨﻄﻘﺔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ.
٢٢
.٢.٢ﺍﳌﻌﺎﰿ
0x0 ﺑﺘﺤﻤﻴﻞ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻮﺏ ﺍﻟﻮﺻﻞ ﺍﻟﻴﻪ ﺍﱃ ﺃﻱ ﻣﻦ ﻣﺴﺠﻼﺕ ﺍﻟﻘﻴﻢ )ﺗﺒﺪﺃ ﺍﻟﻌﻨﺎﻭﻳﻦ ﰲ ﺃﻱ ﻣﻘﻄﻊ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ
ﺍﱃ .(0xffffﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﱵ ﺍﻗﺘﺮﺣﺘﻬﺎ ﺍﻧﺘﻞ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﻋﻨﺎﻭﻳﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺧﻠﻘﺖ ﻟﻨﺎ ﻣﻔﻬﻮﻡ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ
) (Logical Addressﺣﻴﺚ ﻟﻜﻲ ﻧﺼﻞ ﺍﱃ ﺃﻱ ﻣﻜﺎﻥ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻧﻪ ﳚﺐ ﲢﺪﻳﺪ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﻭﺍﻟﻌﻨﻮﺍﻥ ﺑﺪﺍﺧﻞ
ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻭﺫﻟﻚ ﻋﻠﻰ ﺍﻟﺸﻜﻞ Segment:Offsetﺣﻴﺚ ﺍﳉﺰء ﺍﻷﻭﻝ ﳛﺪﺩ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ﻭﺍﳉﺰء ﺍﻟﺜﺎﱐ ﳛﺪﺩ
ﺍﻟﻌﻨﻮﺍﻥ ﺑﺪﺍﺧﻞ ﺍﳌﻘﻄﻊ .ﻣﻬﻤﺔ ﺍﳌﻌﺎﰿ ﺣﺎﻟﻴﺎ ﻫﻲ ﲢﻮﻳﻞ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ ﺍﱃ ﻋﻨﻮﺍﻥ ﻓﻴﺰﻳﺎﺋﻲ ﺃﻭ ﺣﻘﻴﻘﻲ ﻟﻜﻲ ﻳﻘﻮﻡ
ﺑﺎﺭﺳﺎﻟﻪ ﻋﱪ ﻣﺴﺎﺭ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﱃ ﻣﺘﺤﻜﻢ ﺍﻟﺬﺍﻛﺮﺓ ،ﻭ ﻃﺮﻳﻘﺔ ﺍﻟﺘﺤﻮﻳﻞ ﺗﻌﺘﻤﺪ ﻋﻠﻰ ﺃﻥ ﺍﻹﺯﺍﺣﺔ ) (Offsetﻳﺘﻢ
ﲨﻌﻬﺎ ﺍﱃ ﻋﻨﻮﺍﻥ ﺍﳌﻘﻄﻊ ) ٥ (Segmentﻭﻟﻜﻦ ﺑﻌﺪ ﺃﻥ ﻳﺘﻢ ﺿﺮﺎ ﰲ ﺍﻟﻌﺪﺩ ١٦ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺃﻱ ﻣﻘﻄﻊ
ﻳﺒﺪﺃ ﺑﻌﺪ ١٦ﺑﺎﻳﺖ ﻣﻦ ﺍﳌﻘﻄﻊ ﺍﻟﺴﺎﺑﻖ ﻟﻪ .ﻭﺍﻟﺘﺤﻮﻳﻞ ﻳﺘﻢ ﻛﺎﻷﰐ :
physical address = segment ∗ 0x10 + of f set
ﻓﻤﺜﻼ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ 0x07c0:0x0000ﻳﺘﻢ ﲢﻮﻳﻠﻪ ﻭﺫﻟﻚ ﺑﻀﺮﺏ ﺍﻟﻌﻨﻮﺍﻥ 0x07c0ﺑﺎﻟﻌﺪﺩ ) ١٦ﺃﻭ ﺍﻟﻌﺪﺩ 0x10
ﺑﺎﻟﻨﻈﺎﻡ ﺍﻟﺴﺎﺩﺱ ﻋﺸﺮ( ﻟﻴﺼﺒﺢ ﻫﻜﺬﺍ ،0x07c00ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺘﻢ ﲨﻌﻪ ﺍﱃ ﺍﻝ Offsetﻟﻴﺨﺮﺝ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ
.0x07c00
٢٣
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
ﺍﳌﻬﺎﻡ .ﻭﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﻣﻌﺎﳉﺎﺕ ٣٢ﺑﺖ ﺑﺎﻋﺘﺒﺎﺭﻫﺎ ﺃﺣﺪ ﺍﻷﻛﺜﺮ ﺍﻧﺘﺸﺎﺭﴽ ﺣﱴ ﻭﻗﺘﻨﺎ ﻫﺬﺍ
،ﻭ ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﻇﻬﻮﺭ ﻣﻌﺎﳉﺎﺕ ٦٤ﺑﺖ ﺇﻻ ﺍﻥ ﺍﻟﺪﺭﺍﺳﺔ ﺣﻮﻝ ﻣﻌﺎﳉﺎﺕ ٣٢ﺑﺖ ﺗﻌﺘﱪ ﻫﻲ ﺍﻷﺳﺎﺱ ﻧﻈﺮﴽ
ﻻﻥ ﺍﳌﻌﺎﳉﺎﺕ ﺍﳊﺪﻳﺜﺔ ﻣﺎ ﻫﻲ ﺍﻻ ﺗﻄﻮﻳﺮ ﻭﺍﺿﺎﻓﺎﺕ ﻟﻠﻤﻔﺎﻫﻴﻢ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﻌﺎﳉﺎﺕ ﺍﻟﺴﺎﺑﻘﺔ.
٢٤
.٢.٢ﺍﳌﻌﺎﰿ
ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ) ، (Kernel Modeﻭﻳﺘﻢ ﲢﻮﻳﻞ ﺍﳊﻠﻘﺔ ﺍﱃ ﺣﻠﻘﺔ ﻣﻌﻴﻨﺔ ﺗﻠﻘﺎﺋﻴﺎ ﻋﻨﺪ ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﻋﻨﻮﺍﻥ ﰲ
ﺍﻟﺬﺍﻛﺮﺓ ﻣﻮﺻﻮﻑ ﰲ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺑﺄﻧﻪ ﻳﻌﻤﻞ ﺑﺘﻠﻚ ﺍﳊﻠﻘﺔ.
ﻣﺴﺠﻼﺕ ﺍﻟﺘﻨﻘﻴﺢ.DR0, DR1, DR2, DR3, DR4, DR5, DR6, DR7 : •
٢٥
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
ﻣﺴﺠﻼﺕ ﺍﻹﺧﺘﺒﺎﺭ.TR1, TR2, TR3, TR4, TR5, TR6, TR7 : •
• ﻣﺴﺠﻼﺕ ﺃﺧﺮﻯmm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, xmm0, xmm1, xmm2, :
.xmm3, xmm4, xmm5, xmm6, xmm7, GDTR, LDTR, IDTR, MSR, and TR
٢٦
.٢.٢ﺍﳌﻌﺎﰿ
ﺍﳌﺴﺠﻞ :EBXﻳﺴﺘﺨﺪﻡ ﰲ ﺍﻟﻮﺻﻮﻝ ﻟﻠﺬﺍﻛﺮﺓ ﺑﺸﻜﻞ ﻏﲑ ﻣﺒﺎﺷﺮ ﻭﺫﻟﻚ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻣﺴﺠﻞ ﺁﺧﺮ ﻳﻌﻤﻞ •
ﻛﻌﻨﻮﺍﻥ ﺭﺋﻴﺴﻲ .Base Address
ﺍﳌﺴﺠﻞ :ECXﻳﺴﺘﺨﺪﻡ ﰲ ﻋﻤﻠﻴﺎﺕ ﺍﻟﺘﻜﺮﺍﺭ ﻭﺍﻟﻌﺪ. •
ﺍﳌﺴﺠﻞ :DSﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ. •
ﺍﳌﺴﺠﻞ :SSﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﳌﻜﺪﺱ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ. •
ﺍﳌﺴﺠﻞ :ESﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻟﻠﱪﻧﺎﻣﺞ ﺍﳌﺮﺍﺩ ﺗﻨﻔﻴﺬﻩ. •
ﺃﻣﺎ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ) (PModeﻓﺈﻥ ﻫﺬﻩ ﺍﳌﺴﺠﻼﺕ ﻻ ﺗﺸﲑ ﺍﱃ ﻣﻘﺎﻃﻊ ﺍﻟﱪﺍﻣﺞ ﻭﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺇﳕﺎ ﺗﺸﲑ ﺍﱃ
ﻭﺍﺻﻔﺎﺕ ﻣﻌﻴﻨﺔ ﰲ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ،ﻫﺬﻩ ﺍﻟﻮﺍﺻﻔﺎﺕ ﲢﺪﺩ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ﻭﻧﻮﻉ ﺍﳌﻘﻄﻊ )ﳛﻮﻱ
ﺷﻔﺮﺍﺕ ﺃﻡ ﺑﻴﺎﻧﺎﺕ ( ﻭﲢﺪﺩ ﺻﻼﺣﻴﺔ ﺍﻟﺘﻨﻔﻴﺬ ﻭﺻﻼﺣﻴﺔ ﻭﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﻓﻴﻬﺎ -ﻛﻤﺎ ﺳﻨﺮﻯ ﺫﻟﻚ ﰲ ﺍﻟﻔﺼﻞ
ﺍﻟﺮﺍﺑﻊ ﺑﺈﺫﻥ ﺍﷲ.-
ﺍﳌﺴﺠﻞ :BPﳛﻮﻱ ﻋﻨﻮﺍﻥ ﺍﻹﺯﺍﺣﺔ ﺑﺪﺍﺧﻞ ﻣﻘﻄﻊ ﺍﳌﻜﺪﺱ ﻭﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻸﺷﺎﺭﺓ ﻋﻠﻰ ﺃﻱ ﻋﻨﻮﺍﻥ ﰲ •
ﺃﻱ ﻣﻘﻄﻊ ﺁﺧﺮ.
٢٧
x86 .٢ﻣﻌﻤﺎﺭﻳﺔ ﺣﻮﺍﺳﻴﺐ
• 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
٧ﺃﻋﻠﻰ ﻣﺴﺘﻮﻯ ﲪﺎﻳﺔ ﻫﻮ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ) (Ring0ﻭﻳﻠﻴﻬﺎ ﺍﳊﻠﻘﺔ ١ﰒ ٢ﻭ.٣
٢٨
ﺍﳌﻌﺎﰿ.٢.٢
٢٩
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.
٣٠
ﺍﻟﻘﺴﻢ .II
Boo ng ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﺃﺣﺪ ﺃﻫﻢ ﺍﻷﺳﺎﺳﻴﺎﺕ ﰲ ﺑﺮﳎﺔ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻫﻲ ﻛﺘﺎﺑﺔ ﳏﻤﻞﹲ ﻟﻪ ،ﻫﺬﺍ ﺍﳌﺤﻤﻞ ﻳﻌﻤﻞ ﻋﻠﻰ ﻧﺴﺦ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﻦ
ﺃﺣﺪ ﺍﻷﻗﺮﺍﺹ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﰒ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﻟﻨﻮﺍﺓ ،ﻭﻫﻜﺬﺍ ﺗﻨﺘﻬﻲ ﺩﻭﺭﺓ ﻋﻤﻞ ﺍﳌﺤﻤﻞ ﻭﻳﺒﺪﺃ ﻧﻈﺎﻡ
ﺍﻟﺘﺸﻐﻴﻞ ﻣﺘﻤﺜﻼ ﰲ ﺍﻟﻨﻮﺍﺓ ﺑﺎﻟﺒﺪء ﺑﺘﻨﻔﻴﺬ ﺍﻻﻭﺍﻣﺮ ﻭﺍﳌﻬﻤﺎﺕ ﻭﺗﻠﺒﻴﺔ ﺇﺣﺘﻴﺎﺟﺎﺕ ﺍﳌﺴﺘﺨﺪﻡ .ﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﺳﻨﺪﺭﺱ
ﻛﻴﻔﻴﺔ ﺑﺮﳎﺔ ﺍﳌﺤﻤﻞ ﻭﻣﺎﻫﻴﺘﻪ ﻭﺳﻴﺘﻢ ﺍﻻﻗﻼﻉ ﻣﻦ ﻗﺮﺹ ﻣﺮﻥ ﺑﻨﻈﺎﻡ ، FAT12ﻓﺎﻟﻐﺮﺽ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﻫﻮ ﺩﺭﺍﺳﺔ
ﺃﺳﺎﺳﻴﺎﺕ ﺍﳌﺤﻤﻞ ﻭﲢﻤﻴﻞ ﻭﺗﻨﻔﻴﺬ ﻧﻮﺍﺓ ﻣﺒﺴﻄﺔ .
.١.٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ
ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ) (Boot-Strappingﻫﻲ ﺃﻭﻝ ﺧﻄﻮﺓ ﻳﻘﻮﻡ ﺎ ﺍﳉﻬﺎﺯ ﻋﻨﺪ ﻭﺻﻠﻪ ﺑﺎﻟﻜﻬﺮﺑﺎء ﻟﺘﺤﻤﻴﻞ ﻧﻈﺎﻡ
ﺍﻟﺘﺸﻐﻴﻞ ،ﻭﺗﺒﺪﺃ ﻫﺬﻩ ﺍﻟﻌﻤﻠﻴﺔ ﻣﺒﺎﺷﺮﺓ ﻋﻨﺪ ﺍﻟﻀﻐﻂ ﻋﻠﻰ ﻣﻔﺘﺎﺡ ﺍﻟﺘﺸﻐﻴﻞ ﰲ ﺍﳊﺎﺳﺐ ،ﺣﻴﺚ ﺗﺮﺳﻞ ﺇﺷﺎﺭﺓ
ﻛﻬﺮﺑﺎﺋﻴﺔ ١ﺍﱃ ﺍﻟﻠﻮﺣﺔ ﺍﻻﻡ ) ( MotherBoardﻭﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺘﻮﺟﻴﻬﻬﺎ ﺍﱃ ﻭﺣﺪﺓ ﻣﻮﺯﺩ ﺍﻟﻄﺎﻗﺔ )Power Supply
.(Unitﺑﻌﺪ ﺫﻟﻚ ﻳﺄﰐ ﺩﻭﺭ ﻭﺣﺪﺓ PSUﻟﻜﻲ ﺗﻘﻮﻡ ﲟﻬﻤﺔ ﺗﺰﻭﻳﺪ ﺍﳊﺎﺳﺐ ﻭﻣﻠﺤﻘﺎﺗﻪ ﺑﺎﻟﻜﻤﻴﺔ ﺍﳌﻄﻠﻮﺑﺔ ﻣﻦ ﺍﻟﻄﺎﻗﺔ،
ﻭﺇﺭﺳﺎﻝ ﺍﺷﺎﺭﺓ Power Goodﺇﱃ ﺍﻟﻠﻮﺣﺔ ﺍﻻﻡ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﻧﻈﺎﻡ ﺍﻝ . BIOSﺗﺪﻝ ﻫﺬﻩ ﺍﻻﺷﺎﺭﺓ ﻋﻠﻰ ﺃﻧﻪ ﰎ
ﺗﺰﻭﻳﺪ ﺍﻟﻄﺎﻗﺔ ﺍﻟﻜﺎﻓﻴﺔ ،ﻭﻓﻮﺭﺍ ﺳﻴﺒﺪﺃ ﺑﺮﻧﺎﻣﺞ ﺍﻟﻔﺤﺺ ﺍﻟﺬﺍﰐ ) ( Power on Self Testﺍﻟﺬﻱ ﻳﻌﺮﻑ ﺍﺧﺘﺼﺎﺭﴽ
ﺏ POSTﺑﻔﺤﺺ ﺃﺟﻬﺰﺓ ﻭﳏﻠﻘﺎﺕ ﺍﳊﺎﺳﺐ )ﻣﺜﻞ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﺍﳌﺎﻭﺱ ﻭﺍﻟﻨﺎﻗﻞ ﺍﻟﺘﺴﻠﺴﻠﻲ ...ﺍﱁ(
ﻭﺍﻟﺘﺄﻛﺪ ﻣﻦ ﺃﺎ ﺳﻠﻴﻤﺔ .ﺑﻌﺪﻫﺎ ﻳﻘﻮﻡ ﺍﻝ POSTﺑﻨﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﱃ ﻧﻈﺎﻡ ﺍﻝ BIOSﺣﻴﺚ ﺳﻴﻘﻮﻡ ﺍﻝ POST
ﺑﺘﺤﻤﻴﻞ ﺍﻝ BIOSﺍﱃ ﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ 0xFFFF0ﻭ ﺳﻴﻘﻮﻡ ﺃﻳﻀﺎ ﺑﻮﺿﻊ ﺗﻌﻠﻴﻤﺔ ﻗﻔﺰ ) ( jumpﰲ ﺃﻭﻝ ﻋﻨﻮﺍﻥ
ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﺍﱃ ﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ،ﻛﺬﻟﻚ ﻣﻦ ﻣﻬﺎﻡ ﺍﻝ POSTﻫﻲ ﺗﺼﻔﲑ ﺍﳌﺴﺠﻠﲔ CS:IPﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻥ ﺃﻭﻝ
ﺗﻌﻠﻴﻤﻴﺔ ﺳﻴﻨﻔﺬﻫﺎ ﺍﳌﻌﺎﰿ ﻫﻲ ﺗﻌﻠﻴﻤﺔ ﺍﻟﻘﻔﺰ ﺍﱃ ﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﺍﻝ . BIOSﻳﺴﺘﻠﻢ ﺍﻝ BIOSﺍﻟﺘﺤﻜﻢ
ﻭﻳﺒﺪﺃ ﰲ ﺍﻧﺸﺎء ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ) ( Interrupt Vector Tableﻭﺗﻮﻓﲑ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﻘﺎﻃﻌﺎﺕ ،ﻭﻳﻘﻮﻡ ﺑﺎﳌﺰﻳﺪ
ﻣﻦ ﻋﻤﻠﻴﺎﺕ ﺍﻟﻔﺤﺺ ﻭﺍﻻﺧﺘﺒﺎﺭ ﻟﻠﺤﺎﺳﺐ ،ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺒﺪﺃ ﰲ ﻣﻬﻤﺔ ﺍﻟﺒﺤﺚ ﻋﻦ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﰲ ﺍﻻﺟﻬﺰﺓ
ﺍﳌﻮﺟﻮﺩﺓ ﺑﻨﺎءﺍ ﻋﻠﻰ ﺗﺮﺗﻴﺒﻬﺎ ﰲ ﺍﻋﺪﺍﺩﺍﺕ ﺍﻝ BIOSﰲ ﺑﺮﻧﺎﻣﺞ ، Setupﻭﰲ ﺣﺎﻟﺔ ﱂ ﳚﺪ ﺍﻝ BIOSﺟﻬﺎﺯﺍ ﻗﺎﺑﻼ
ﻟﻼﻗﻼﻉ ﰲ ﻛﻞ ﺍﻟﻘﺎﺋﻤﺔ ﻓﺎﻧﻪ ﻳﺼﺪﺭ ﺭﺳﺎﻟﺔ ﺧﻄﺄ ﺑﻌﺪﻡ ﺗﻮﻓﺮ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻭﻳﻮﻗﻒ ﺍﳊﺎﺳﺐ ﻋﻦ ﺍﻟﻌﻤﻞ ) ( Halt
،ﻭﰲ ﺣﺎﻟﺔ ﺗﻮﻓﺮ ﺟﻬﺎﺯﴽ ﻗﺎﺑﻼً ﻟﻺﻗﻼﻉ ﺳﻴﻘﻮﻡ ﺍﻝ BIOSﺑﺘﺤﻤﻴﻞ ﺍﻟﻘﻄﺎﻉ ﺍﻷﻭﻝ ﻣﻨﻪ ) ﳛﻮﻱ ﻫﺬﺍ ﺍﻟﻘﻄﺎﻉ ﻋﻠﻰ
ﺑﺮﻧﺎﻣﺞ ﺍﳌﺤﻤﻞ( ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻭﺑﺎﻟﺘﺤﺪﻳﺪ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ 0x07c00ﻭﺳﻴﻨﻘَﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺍﳌﺤﻤﻞ.
١ﻫﺬﻩ ﺍﻹﺷﺎﺭﺓ ﲢﻮﻱ ﻋﻠﻰ ﺑﺖ ) ( bitﺗﺪﻝ ﻗﻴﻤﺘﻪ ﺍﺫﺍ ﻛﺎﻧﺖ 1ﻋﻠﻰ ﺃﻧﻪ ﰎ ﺗﺸﻐﻴﻞ ﺍﳊﺎﺳﺐ.
٣٣
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﺧﻼﻝ ﻫﺬﻩ ﺍﳌﻬﻤﺔ )ﺍﻗﻼﻉ ﺍﻟﻨﻈﺎﻡ( ﻳﻮﻓﺮ ﻟﻨﺎ ﻧﻈﺎﻡ ﺍﻝ BIOSﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻋﻠﻰ ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﺍﻟﺬﻱ
ﻳﺘﻢ ﺍﻧﺸﺎﺋﻪ ﺑﺪءﴽ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ، 0x0ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻫﻲ ﺧﺪﻣﺎﺕ ﻳﻮﻓﺮﻫﺎ ﻟﻨﺎ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﻻﺩﺍء ﻭﻇﻴﻔﺔ ﻣﻌﻴﻨﺔ
ﻣﺜﻞ ﻣﻘﺎﻃﻌﺔ ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ .ﻭﺍﺣﺪﺓ ﻣﻦ ﺃﻫﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﻟﻠﺒﺤﺚ ﻋﻦ
ﺟﻬﺎﺯ ﺍﻻﻗﻼﻉ ﻫﻲ ﺍﳌﻘﺎﻃﻌﺔ int 0x19ﺣﻴﺚ ﺗﻜﻤﻦ ﻭﻇﻴﻔﺘﻬﺎ ﰲ ﺍﻟﺒﺤﺚ ﻋﻦ ﻫﺬﺍ ﺍﳉﻬﺎﺯ ﻭﻣﻦ ﰒ ﲢﻤﻴﻞ ﺍﻟﻘﻄﺎﻉ
ﺍﻷﻭﻝ ﻣﻨﻪ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ 0x07c00ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻪ .ﻃﺮﻳﻘﺔ ﺍﻟﺒﺤﺚ ﻭﺍﻟﺘﺤﻤﻴﻞ ﻟﻴﺴﺖ ﺑﺎﻻﻣﺮ ﺍﳌﻌﻘﺪ
ﺣﻴﺚ ﻋﻠﻰ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ ﺍﻟﺒﺤﺚ ﰲ ﺃﻭﻝ ﻗﻄﺎﻉ )ﻣﻦ ﺃﻱ ﺟﻬﺎﺯ ﻣﻮﺟﻮﺩ ﻋﻠﻰ ﻗﺎﺋﻤﺔ ﺍﻻﺟﻬﺰﺓ ﺍﻟﻘﺎﺑﻠﺔ ﻟﻼﻗﻼﻉ(
ﻋﻦ ﺍﻟﺘﻮﻗﻴﻊ 0xAA55ﻭﻫﻲ ﻋﺒﺎﺭﺓ ﻋﻦ ﺑﺎﻳﺘﲔ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﻋﻠﻰ ﺁﺧﺮ ﺍﻟﻘﻄﺎﻉ ﺍﻻﻭﻝ ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﺍﳉﻬﺎﺯ
ﻗﺎﺑﻞ ﻟﻼﻗﻼﻉ .ﻭﻣﻦ ﺍﳉﺪﻳﺮ ﺑﺎﻟﺬﻛﺮ ﺃﻥ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﻮﻓﺮﻫﺎ ﻟﻨﺎ ﻧﻈﺎﻡ ﺍﻟﺒﺎﻳﻮﺱ ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ ﻓﻘﻂ ﺍﺫﺍ ﻛﺎﻥ
ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ Real Modeﺃﻣﺎ ﺇﺫﺍ ﰎ ﺗﻐﻴﲑ ﳕﻂ ﺍﳌﻌﺎﰿ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ Protected Mode
-ﻛﻤﺎ ﺳﻨﺮﻯ ﺫﻟﻚ ﻻﺣﻘﺎ -ﻓﺎﻧﻪ ﻟﻦ ﳝﻜﻦ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺑﻞ ﺳﻴﺘﺴﺒﺐ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ ﰲ ﺣﺪﻭﺙ
ﺍﺳﺘﺜﻨﺎءﺍﺕ ) ( Excep onﺗﻮﻗﻒ ﻋﻤﻞ ﺍﳊﺎﺳﺐ.
٣٤
.٣.٣ﳐﻄﻂ ﺍﻟﺬﺍﻛﺮﺓ
ﻭﲢﻘﻴﻖ ﻫﺬﺍ ﺍﻟﺸﺮﻁ ﻟﻴﺲ ﺑﺎﻷﻣﺮ ﺍﳌﻌﻘﺪ ﺧﺼﻮﺻﺎ ﻣﻊ ﺗﻮﻓﺮ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻻﺩﻭﺍﺕ ﺍﻟﱵ ﺗﺴﺎﻋﺪ ﻋﻠﻰ ﻧﺴﺦ ﻣﻘﻄﻊ
ﻣﻦ ﻗﺮﺹ ﻣﺎ ﺍﱃ ﻣﻘﻄﻊ ﰲ ﻗﺮﺹ ﺁﺧﺮ ،ﺃﻣﺎ ﺍﻟﺸﻖ ﺍﻟﺜﺎﱐ ﻣﻦ ﺍﻟﺸﺮﻁ ﻓﻬﻮ ﻣﺘﻌﻠﻖ ﺑﺘﻤﻴﻴﺰ ﺍﻟﻘﻄﺎﻉ ﺍﻻﻭﻝ ﻛﻘﻄﺎﻉ
ﻗﺎﺑﻞ ﻟﻼﻗﻼﻉ ﻣﻦ ﻏﲑﻩ ،ﺣﻴﺚ ﺣﱴ ﻳﻜﻮﻥ ﺍﻟﻘﻄﺎﻉ ﻗﺎﺑﻼ ﻟﻼﻗﻼﻉ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﳛﻤﻞ ﺍﻟﺘﻮﻗﻴﻊ 0xAA55ﰲ
ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 510ﻭ . 511ﻭﺑﺪﻭﻥ ﻫﺬﺍ ﺍﻟﺘﻮﻗﻴﻊ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ )ﻭﲢﺪﻳﺪﺍ ﻣﻘﺎﻃﻌﺔ ﺭﻗﻢ (0x19ﻟﻦ ﺗﺘﻌﺮﻑ ﻋﻠﻰ
ﻫﺬﺍ ﺍﻟﻘﻄﺎﻉ ﻛﻘﻄﺎﻉ ﻗﺎﺑﻞٌ ﻟﻺﻗﻼﻉ .ﺃﻣﺎ ﺍﻟﺸﺮﻁ ﺍﻟﺜﺎﻟﺚ ﻓﻬﻮ ﺷﺮﻁ ﺍﺧﺘﻴﺎﺭﻱ ﻭﻟﻴﺲ ﺍﺟﺒﺎﺭﻱ ،ﻓﻤﻦ ﺍﳌﻤﻜﻦ ﺃﻥ
ﺗﻜﻮﻥ ﻭﻇﻴﻔﺔ ﺍﳌﺤﻤﻞ ﻫﻲ ﻋﺮﺽ ﺭﺳﺎﻟﺔ ﺗﺮﺣﻴﺐ ﻓﻘﻂ ! ﻭﻟﻜﻦ ﰲ ﺃﻏﻠﺐ ﺍﳊﺎﻻﺕ ﺍﻟﻮﺍﻗﻌﻴﺔ ﳚﺐ ﺃﻥ ﺗﺤﻤﱠﻞ
ﺍﻟﻨﻮﺍﺓ ﻭﺗُﻨﻔﱠﺬ ﻋﻦ ﻃﺮﻳﻖ ﻫﺬﺍ ﺍﳌﺤﻤﻞ .ﻭﻗﺪ ﺃﺳﻠﻔﻨﺎ ﻭﺫﻛﺮﻧﺎ ﺃﻥ ﲢﻤﻴﻞ ﻧﻮﺍﺓ 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 .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﻳﻠﻴﻬﺎ ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﰒ ﻣﺴﺎﺣﺔ ﺫﺍﻛﺮﺓ ﺧﺎﻟﻴﺔ ﲢﻮﻱ ﺍﻟﻌﻨﻮﺍﻥ 0x07c00ﻭﻫﻮ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺬﻱ ﻳﻨﻘﻞ ﺍﻟﺒﺎﺑﻮﺱ
ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻪ )ﻋﻨﻮﺍﻥ ﺑﺮﻧﺎﻣﺞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ( ،ﻭﻳﻠﻴﻬﺎ ﻣﻨﻄﻘﺔ ﺑﻴﺎﻧﺎﺕ ﺑﺎﻳﻮﺱ ﺍﳌﻮﺳﻌﺔ ﻭﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﻭﺍﻟﱵ ﲟﺠﺮﺩ
ﺍﻟﻜﺘﺎﺑﺔ ﻋﻠﻴﻬﺎ ﺗﻈﻬﺮ ﺍﻷﺣﺮﻑ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ ) (Memory Mappedﻭﻳﻠﻴﻬﺎ ﺍﻟﺒﺎﻳﻮﺱ ﻋﻠﻰ ﺫﺍﻛﺮﺓ ﺍﻟﻔﻴﺪﻳﻮ ﻭﻣﻨﺎﻃﻖ
ﳏﺠﻮﺯﺓ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻟﺒﻌﺾ ﺃﺟﻬﺰﺓ ﺍﻹﺩﺧﺎﻝ ﻭﺍﻹﺧﺮﺍﺝ ﻭﻣﻦ ﰒ ﺍﻟﺒﺎﻳﻮﺱ ﻭﺍﻟﺬﻱ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0xf0000ﻭﻫﻮ
ﻣﻮﺟﻮﺩ ﻋﻠﻰ ﺫﺍﻛﺮﺓ ﺍﻟﺮﻭﻡ ). (Memory Mapped
٣ﺭﺍﺟﻊ ﺍﳌﻠﺤﻖ ﺍ ﳌﻌﺮﻓﺔ ﻛﻴﻔﻴﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﺠﻤﻊ ﻟﺘﺮﲨﺔ ﺍﳌﺤﻤﻞ ﻭﻛﻴﻔﻴﺔ ﻧﺴﺨﻪ ﺍﱃ floppy disk or CDﻟﻴﺘﻢ ﺍﻟﻘﻼﻉ ﻣﻨﻪ ﺳﻮﺍءﴽ ﻛﺎﻥ
ﻋﻠﻰ ﺟﻬﺎﺯ ﻓﻌﻠﻲ ﺃﻭ ﻋﻠﻰ ﺟﻬﺎﺯ ﲣﻴﻠﻲ ). (Virtual Machine
٣٦
.٤.٣ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﻭﻋﻨﺪﻣﺎ ﻳﺒﺪﺃ ﺍﳉﻬﺎﺯ ﺑﺎﻟﻌﻤﻞ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ ﻳﻘﻮﻡ ﺑﻨﺴﺦ ﻫﺬﺍ ﺍﳌﺤﻤﻞ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 0x0000:0x7c00ﻭﻳﺒﺪﺃ
ﺑﺘﻨﻔﻴﺬﻩ ،ﻭﰲ ﻫﺬﺍ ﺍﳌﺜﺎﻝ ﻓﺎﻥ ﺍﳌﺤﻤﻞ ﻫﺬﺍ ﺍﻟﺬﻱ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ) (real modeﻻ ﻳﻘﻮﻡ ﺑﺸﻲء ﺫﻭ
ﻓﺎﺋﺪﺓ ﺣﻴﺚ ﻳﺒﺪﺃ ﺑﺘﻨﻔﻴﺬ ﺍﻻﻣﺮ cliﺍﻟﺬﻱ ﻳﻮﻗﻒ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ،ﻳﻠﻴﻬﺎ ﺍﻻﻣﺮ hltﺍﻟﺬﻱ ﻳﻮﻗﻒ ﻋﻤﻞ ﺍﳌﻌﺎﰿ
ﻭﺑﺎﻟﺘﺎﱄ ﻳﺘﻮﻗﻒ ﺍﻟﻨﻈﺎﻡ ﻋﻦ ﺍﻟﻌﻤﻞ ،ﻭﺑﺪﻭﻥ ﻫﺬﺍ ﺍﻷﻣﺮ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻴﺴﺘﻤﺮ ﰲ ﺗﻨﻔﻴﺬ ﺃﻭﺍﻣﺮ ﻻ ﻣﻌﲎ ﳍﺎ )(garbage
ﻭﺍﻟﱵ ﺳﺘﺆﺩﻱ ﺍﱃ ﺳﻘﻮﻁ ) (Crashﺍﻟﻨﻈﺎﻡ .ﻭﺑﺴﺒﺐ ﺃﻥ ﺣﺠﻢ ﺍﳌﺤﻤﻞ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ 512ﺑﺎﻳﺖ ﻭﺃﻥ ﺁﺧﺮ
ﺑﺎﻳﺘﲔ ﻓﻴﻪ ﳚﺐ ﺃﻥ ﺗﻜﻮﻧﺎ ﺍﻟﺘﻮﻗﻴﻊ ﺍﳋﺎﺹ ﺑﺎﳌﺤﻤﻞ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﺃﻭﻝ 510ﺑﺎﻳﺖ ﺫﺍﺕ ﻗﻴﻤﺔ ﻭﺍﺧﺮ ﺑﺎﻳﺘﲔ
ﳘﺎ ، 0xaa55ﻟﺬﻟﻚ ﰎ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﻮﺟﻪ timesﻟﻜﻲ ﻳﺘﻢ ﻣﻠﺊ ﺍﳌﺘﺒﻘﻲ ﻣﻦ ﺃﻭﻝ 510ﺑﺎﻳﺖ ﺑﺎﻟﻘﻴﻤﺔ ﺻﻔﺮ
)ﻭﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﺃﻱ ﻗﻴﻤﺔ ﺍﺧﺮﻯ( ﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﻛﺘﺎﺑﺔ ﺍﻟﺘﻮﻗﻴﻊ ﺍﳋﺎﺹ ﺑﺎﳌﺤﻤﻞ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺍﻟﺘﻌﺮﻑ ﻋﻠﻴﻪ
ﻣﻦ ﻗﺒﻞ ﺍﻟﺒﺎﻳﻮﺱ.
٣٧
Bootloader ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٣
٣٨
ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤.٣
٣٩ 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 0xaa
data segment ﻭﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕcode segment ﺍﻟﺸﻲء ﺍﳌﻼﺣﻆ ﰲ ﺍﳌﺜﺎﻝ ﺍﻟﺴﺎﺑﻖ ﻫﻮ ﺃﻥ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ
ﺑﺎﻳﺖ( ﻟﺬﻟﻚ ﳚﺐ ﺗﻌﺪﻳﻞ ﻗﻴﻢ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ512 ﻣﺘﻮﺍﺟﺪﺍﻥ ﰲ ﻧﻔﺲ ﺍﳌﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ )ﺩﺍﺧﻞ ﺍﻝ
ﻭ ﺑﺪﺍﻳﺔ ﻧﺬﻛﺮ ﺃﻥ ﺍﻟﺒﺎﻳﻮﺱ ﻋﻨﺪﻣﺎ ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺑﺮﻧﺎﻣﺞ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﻗﻤﻨﺎ.ﻟﻼﺷﺎﺭﺓ ﺍﱃ ﺍﳌﻜﺎﻥ ﺍﻟﺼﺤﻴﺢ
ﻟﺬﻟﻚ ﻻ ﺩﺍﻋﻲcs:ip ﻭﺍﻟﱵ ﻳﻨﺘﺞ ﻣﻨﻬﺎ ﺗﺼﺤﻴﺢ ﻗﻴﻢ ﺍﻝfar jump ﺑﻜﺘﺎﺑﺘﻪ ﻓﺎﻧﻪ ﰲ ﺣﻘﻴﻘﺔ ﺍﻷﻣﺮ ﻳﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ
٣٩
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﻟﻠﻘﻠﻖ ﺣﻮﻝ ﻫﺬﻳﻦ ﺍﳌﺴﺠﻠﲔ ،ﻟﻜﻦ ﳚﺐ ﺗﻌﺪﻳﻞ ﻗﻴﻢ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﺍﻻﺧﺮﻯ ﻣﺜﻞ .ds,es,ss,fs,gs
ﻭﻛﻤﺎ ﻧﻌﻠﻢ ﺃﻥ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﳌﺤﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻫﻮ 0x07c00ﳝﻜﻦ ﺍﻟﻮﺻﻮﻝ ﺍﻟﻴﻪ ﺑﺄﻛﺜﺮ ﻣﻦ 4000ﻃﺮﻳﻘﺔ
ﳐﺘﻠﻔﺔ ،ﻟﻜﻦ ﺳﻮﻑ ﻧﻘﺘﺼﺮ ﻋﻠﻰ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻨﻮﺍﻥ 0x07c0:0x0ﺃﻭ ﺍﻟﻌﻨﻮﺍﻥ 0x0:0x7c00ﻧﻈﺮﴽ ﻻﻥ
ﻫﺬﻩ ﻫﻲ ﺍﻟﻘﻴﻢ ﺍﻟﻔﻌﻠﻴﺔ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻣﻬﺎ ﺍﻟﺒﺎﻳﻮﺱ.
ﻭﰲ ﺣﺎﻟﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻻﻭﱃ ﻓﺎﻥ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﳚﺐ ﺃﻥ ﲢﻮﻱ ﺍﻟﻘﻴﻤﺔ ) 0x07c0ﻛﻤﺎ ﰲ ﺍﳌﺜﺎﻝ
ﺍﻋﻼﻩ( ﺃﻣﺎ ﺑﻘﻴﺔ ﺍﻟﻌﻨﻮﺍﻧﲔ )ﺳﻮﺍءﺍ ﻟﻠﻤﺘﻐﲑﺍﺕ ﻭﺍﻝ (labelﻓﺎﺎ ﳚﺐ ﺃﻥ ﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻘﻴﻤﺔ ،0x0ﻭﻛﻤﺎ ﻫﻮ ﻣﻌﺮﻭﻑ
ﺍﻥ ﺍﳌﺠﻤﻌﺎﺕ ﻋﻨﺪﻣﺎ ﺗﺒﺪﺃ ﰲ ﻋﻤﻠﻴﺔ ﺗﺮﲨﺔ ﺍﳌﻠﻒ ﺍﱃ ﻣﻠﻒ ﺛﻨﺎﺋﻲ ﻓﺎﺎ ﺗﺒﺪﺃ ﺑﺘﺮﻗﻴﻢ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺑﺪءﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0x0
ﻟﺬﻟﻚ ﻛﺎﻧﺖ ﻭﻇﻴﻔﺔ ﺍﳌﻮﺟﻪ orgﻫﻲ ﻋﻤﻞ ﺍﻋﺎﺩﺓ ﺗﻌﻴﲔ ) (reloca ngﻟﻠﻌﻨﺎﻭﻳﻦ ﺑﺎﻟﻘﻴﻤﺔ ﺍﻟﱵ ﰎ ﻛﺘﺎﺑﺘﻬﺎ ،ﻭﰲ
ﺍﳌﺜﺎﻝ ﺃﻋﻼﻩ ﻛﺎﻧﺖ ﺍﻟﻘﻴﻤﺔ ﻫﻲ ، 0x0ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﻣﻜﺎﻥ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﻓﺎﻥ ﻣﺴﺠﻼﺕ ﺍﳌﻘﺎﻃﻊ ﳚﺐ ﺃﻥ ﲢﻮﻱ ﺍﻟﻘﻴﻤﺔ 0x0ﺑﻴﻨﻤﺎ ﺍﳌﺴﺠﻼﺕ ﺍﻻﺧﺮﻯ ﳚﺐ ﺃﻥ ﺗﺒﺪﺃ ﻗﻴﻤﻬﺎ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ
، 0x7c00ﻭﻫﺬﺍ ﻻ ﳝﻜﻦ ﺑﺎﻟﻮﺿﻊ ﺍﻟﻄﺒﻴﻌﻲ ﻻﻥ ﺍﳌﺠﻤﻌﺎﺕ ﺳﺘﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0x0ﻟﺬﻟﻚ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ
ﺍﳌﻮﺟﻪ orgﻭﲢﺪﻳﺪ ﻗﻴﻤﺔ ﺍﻝ relocateﺑﺎﻟﻘﻴﻤﺔ . 0x7c00
٤ﳍﺬﺍ ﺍﻟﺴﺒﺐ ﻓﺎﻥ ﺃﻭﻝ ﺗﻌﻠﻴﻤﺔ ﰲ ﺍﳌﺤﻤﻞ ﺳﺘﻜﻮﻥ ﺗﻌﻠﻴﻤﺔ ﺍﻟﻘﻔﺰ ﺍﱃ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﻨﻔﻴﺬﻳﺔ ،ﻭﺑﺪﻭﻥ ﺍﻟﻘﻔﺰ ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻴﺒﺪﺃ ﺑﺘﻨﻔﻴﺬ ﻫﺬﻩ
ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﺎﻋﺘﺒﺎﺭ ﺍﺎ ﺗﻌﻠﻴﻤﺎﺕ ﻭﻫﺬﺍ ﻣﺎ ﻳﺆﺩﻱ ﰲ ﺍﻻﺧﺮ ﺍﱃ ﺳﻘﻮﻁ ﺍﻟﻨﻈﺎﻡ.
٤٠
ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤.٣
.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 ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٣
٤٢
ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤.٣
٥٦
٥٧ 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 ﻭﳚﺐ ﺃﻭﻻ ﺍﻋﺎﺩﺓ ﲡﻤﻴﻊ ﺍﳌﻠﻒ ﺍﻟﺜﻨﺎﺋﻲ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺃﻱ ﻣﻦ ﺑﺮﺍﻣﺞ ﺍﻝ، ﰲ ﻛﻞ ﺗﻜﺮﺍﺭ
.ﺗﻌﻠﻴﻤﺔ ﻗﻔﺰ ﺑﻌﺪ ﺍﺳﺘﺪﻋﺎء ﺩﺍﻟﺔ ﻃﺒﺎﻋﺔ ﺍﻟﺴﻠﺴﻠﺔ ﺍﱃ ﻣﺎ ﻗﺒﻠﻬﺎ
٤٥
Bootloader ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٣
٤٦
ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤.٣
٤٧
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﺍﻟﻨﺘﻴﺠﺔ:
ﺍﳌﺴﺠﻞ : ahﺍﳊﺎﻟﺔ. •
ﻣﺜﺎﻝ:
Example ٣.٧: Reset Floppy Drive
١ reset floppy:
٢
٣ mov ah,0x0 ; reset floppy routine number.
٤ mov dl,0x0 ; drive number
٥
٦ int 0x13 ; call BIOS
٧
٨ jc reset floppy ; try again if error occur.
٤٨
.٤.٣ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
hard ﺍﳌﺴﺠﻞ :clﺭﻗﻢ ﺍﳌﻘﻄﻊ ،ﻣﻦ ﺍﻟﺒﺖ ، 5 - 0ﺃﻣﺎ ﺍﺧﺮ ﺑﺘﲔ ﻳﺴﺘﺨﺪﻣﺎﻥ ﻣﻊ ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ •
.disk
ﺍﳌﺴﺠﻞ :dhﺭﻗﻢ ﺍﻟﺮﺃﺱ. •
ﺍﻟﻨﺘﻴﺠﺔ:
• ﺍﳌﺴﺠﻞ : ahﺍﳊﺎﻟﺔ.
• ﺍﳌﺴﺠﻞ :alﻋﺪﺩ ﺍﳌﻘﺎﻃﻊ ﺍﻟﱵ ﰎ ﻗﺮﺍﺋﺘﻬﺎ.
0x1 : CFﺍﺫﺍ ﺣﺪﺙ ﺧﻄﺄ 0x0 ،ﺍﺫﺍ ﲤﺖ ﺍﻟﻌﻤﻠﻴﺔ ﺑﻨﺠﺎﺡ. •
ﻣﺜﺎﻝ:
٤٩
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
١٢
١٣ ; init buffer.
١٤ mov ax,0x1000
١٥ mov es,ax
١٦ xor bx,bx
١٧
١٨ read:
١٩
٢٠ mov ah,0x2 ; routine number.
٢١ mov al,1 ?; how many sectors
٢٢ mov ch,1 ; cylinder or track number.
٢٣ mov cl,2 ; sector number "fisrt sector is 1 not 0",now we read
the second sector.
٢٤ mov dh,0 ; head number "starting with 0".
٢٥ mov dl,0 ; drive number ,floppy drive always zero.
٢٦
٢٧ int 0x13 ; call BIOS.
٢٨ jc read ; if error, try again.
٢٩
٣٠ jmp 0x1000:0x0 ; jump to execute the second sector.
ﻭﺟﻮﺩ ﻫﻴﻜﻠﺔ ﺑﻴﺎﻧﺎﺕ Data Structureﻣﻌﻴﻨﺔ ﻋﻠﻰ ﺍﻟﻘﺮﺹ،ﻳﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﺩﺭﺍﻳﻔﺮ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ. •
٥٠
FAT12 .٥.٣ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ
ﻭﺣﻴﺚ ﺃﻥ ﺑﺮﳎﺔ ﺑﺮﻧﺎﻣﺞ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ﺗﻌﺘﻤﺪ ﻛﻠﻴﺎُ ﻋﻠﻰ ﻫﻴﻜﻠﺔ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ،ﻓﺎﻧﻨﺎ ﺳﻨﺒﺪﺃ
ﺑﺎﳊﺪﻳﺚ ﻋﻨﻬﺎ ﺃﻭﻻ ﻭﺳﻮﻑ ﻧﺄﺧﺬ ﻧﻈﺎﻡ FAT12ﻋﻠﻰ ﻗﺮﺹ ﻣﺮﻥ ﻛﻤﺜﺎﻝ ،ﻧﻈﺮﴽ ﻟﺒﺴﺎﻃﺔ ﻫﺬﺍ ﺍﻟﻨﻈﺎﻡ ﻭﺧﻠﻮﻩ ﻣﻦ
ﺍﻟﺘﻌﻘﻴﺪﺍﺕ.
.32 MB ﺣﺠﻢ ﺍﻟﻘﺮﺹ ﳛﻔﻆ ﰲ 16ﺑﺖ ،ﻭﻟﺬﺍ ﻓﺎﻧﻪ ﻻ ﻳﺪﻋﻢ ﺍﻻﻗﺮﺍﺹ ﺍﻟﱵ ﺣﺠﻤﻬﺎ ﻳﺰﻳﺪ ﻋﻦ •
ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺃﻧﻨﺎ ﺳﻨﺴﺘﺨﺪﻡ ﻫﺬﺍ ﺍﻟﻨﻈﺎﻡ ﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ ﻧﻈﺮﴽ ﻟﺒﺴﺎﻃﺘﻪ ،ﻭﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻧﻪ ﻗﺪ ﺗﻼﺷﻰ
ﺍﺳﺘﺨﺪﺍﻣﻪ ﰲ ﻫﺬﺍ ﺍﻟﺰﻣﻦ ﺍﻻ ﺍﻧﻪ ﻳﻌﺘﱪ ﺃﺳﺎﺱ ﺟﻴﺪ ﻟﻸﻧﻈﻤﺔ ﺍﳌﺘﻘﺪﻣﺔ ﻟﺬﺍ ﻭﺟﺐ ﺩﺭﺍﺳﺘﻪ.
٦ﺳﻮﺍءﴽ ﻛﺎﻧﺖ ﺍﻟﺘﻬﺌﻴﺔ ﻣﻦ ﻗﺒﻞ ﺩﺭﺍﻳﻔﺮ ﻧﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﺍﻟﺬﻱ ﺳﻨﻘﻮﻡ ﺑﱪﳎﺘﻪ ﺃﻭ ﻛﺎﻧﺖ ﻣﻦ ﻗﺒﻞ ﻧﻈﺎﻡ ﺍﻟﺸﺘﻐﻴﻞ ﺍﳌﺴﺘﺨﺪﻡ ﺃﺛﻨﺎء ﻋﻤﻠﻴﺔ
ﺍﻟﺘﻄﻮﻳﺮ ،ﻓﻤﺜﻼ ﰲ ﻭﻳﻨﺪﻭﺯ ﳝﻜﻦ ﺇﻋﺎﺩﺓ ﺌﻴﺔ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺑﻨﻈﺎﻡ . FAT12
٥١
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﻭﺃﻭﻝ ﻣﻘﻄﻊ ﻫﻮ ﻣﻘﻄﻊ ﺍﻻﻗﻼﻉ ) (Boot Sectorﻭﳛﻮﻱ ﺷﻔﺮﺓ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ )ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ( ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ
ﺑﻴﺎﻧﺎﺕ ﻭﻣﻌﻠﻮﻣﺎﺕ ، BPB and OEM idﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻋﻨﻮﺍﻧﻪ ﺍﻟﻔﻴﺰﻳﺎﺋﻲ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﻫﻮ :ﺍﳌﻘﻄﻊ 1ﺍﳌﺴﺎﺭ 0
ﺍﻟﺮﺃﺱ 0ﻭﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ ﺍﻟﺬﻱ ﳚﺐ ﲤﺮﻳﺮ ﺍﱃ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ int 0x13ﺍﻟﱵ ﺗﻘﻮﻡ ﺑﺎﻟﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻘﺮﺹ
ﻛﺬﻟﻚ ﰲ ﺣﺎﻟﺔ ﻣﺎ ﺃﺭﺩﻧﺎ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﻣﺘﺤﻜﻢ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ .ﻭﻧﻈ ًﺮ ﻟﺼﻌﻮﺑﺔ ﻫﺬﻩ ﺍﻟﻌﻨﻮﻧﺔ ﻭﺍﻟﱵ ﺗﻌﺮﻑ
ﺏ Absolute Sectorﻓﺎﻥ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﺗﺘﻌﺎﻣﻞ ﻣﻊ ﻧﻈﺎﻡ ﻋﻨﻮﻧﺔ ﳐﺘﻠﻒ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﳏﺘﻮﻳﺎﺕ ﺍﻟﻘﺮﺹ ،ﻓﺒﺪﻻً
ﻣﻦ ﺫﻛﺮ ﻛﻞ ﻣﻦ ﺍﳌﻘﻄﻊ ﻭﺍﳌﺴﺎﺭ ﻭﺍﻟﺮﺃﺱ ﻟﻠﻮﺻﻮﻝ ﺍﱃ ﻣﻘﻄﻊ ﻣﺎ ﻓﺎﻥ ﻫﺬﻩ ﺍﻟﻌﻨﻮﻧﺔ ﺗﺴﺘﺨﺪﻡ ﻓﻘﻂ ﺭﻗﻢ ﻟﻠﻤﻘﻄﻊ .
ﻧﻈﺎﻡ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻟﺬﻱ ﺗﺴﺘﺨﺪﻣﻪ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ ﻳﺴﻤﻰ ﺑﺎﻟﻌﻨﻮﻧﺔ ﺍﳌﻨﻄﻘﻴﺔ ) (Logical Sector Addressingﻭﳜﺘﺼﺮ
ﺏ LBAﻫﻮ ﻧﻈﺎﻡ ﺑﺴﻴﻂ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ﺗﺮﻗﻴﻢ ﺍﳌﻘﺎﻃﻊ ﺑﺸﻜﻞ ﻣﺘﺴﻠﺴﻞ ﺑﺪﺋﴼ ﻣﻦ ﻣﻘﻄﻊ ﺍﻻﻗﻼﻉ )(Boot Sector
ﻭﺍﻟﺬﻱ ﻳﺄﺧﺬ ﺍﻟﻌﻨﻮﺍﻥ ، 0ﻭﺍﳌﻘﻄﻊ ﺍﻟﺜﺎﱐ 1ﻭﻫﻜﺬﺍ ﻫﻠﻢ ﺟﺮﺍ ﺣﱴ ﻧﺼﻞ ﺍﱃ ﺁﺧﺮ ﻣﻘﻄﻊ ﰲ ﺍﻟﻘﺮﺹ .ﻭﲟﺎ ﺃﻧﻪ
ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻨﻮﻧﺔ ﺍﳊﻘﻴﻘﺔ ﺑﺪﻻ ﻣﻦ ﺍﳌﻨﻄﻘﻴﺔ ﳊﻈﺔ ﺍﻟﻘﺮﺍءﺓ ﻣﻦ ﺍﻟﻘﺮﺹ )ﺗﺬﻛﺮ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ int 0x13
ﻭﺍﳌﺴﺠﻼﺕ ﺍﻟﱵ ﳚﺐ ﺍﺩﺧﺎﻝ ﻗﻴﻤﻬﺎ( ﻓﺎﻧﻪ ﳚﺐ ﺍﳚﺎﺩ ﻃﺮﻳﻘﺔ ﻟﻠﺘﺤﻮﻳﻞ ﻣﻦ ﺍﻟﻌﻨﻮﻧﺔ ﺍﳊﻘﻴﻘﺔ ﺍﱃ ﺍﳌﻨﻄﻘﻴﺔ -ﺳﻨﻨﺎﻗﺶ
ﺍﳌﻮﺿﻮﻉ ﻻﺣﻘﺎ .-ﻧﻨﺘﻘﻞ ﺍﱃ ﺍﳌﻘﻄﻊ ﺍﻟﺘﺎﱄ ﳌﻘﻄﻊ ﺍﻹﻗﻼﻉ ﻭﻫﻮ ﻣﻘﻄﻊ )ﺃﻭ ﻋﺪﺓ ﻣﻘﺎﻃﻊ( ﳝﻜﻦ ﺃﻥ ﳛﺠﺰﻫﺎ ﺍﳌﱪﻣﺞ
ﻻﺩﺍء ﺃﻱ ﻭﻇﻴﻔﺔ ﻳﺮﻳﺪﻫﺎ ﻭﺗﺴﻤﻰ ﺍﳌﻘﺎﻃﻊ ﺍﳌﺤﺠﻮﺯﺓ ﺍﻻﺿﺎﻓﻴﺔ ، Extra Reserved Sectorsﻭﺍﳌﻘﺼﻮﺩ ﲟﺤﺠﻮﺯﺓ
ﺃﻱ ﺍﻧﻪ ﻻ ﻳﻮﺟﺪ ﳍﺎ ﻭﺟﻮﺩ ﰲ ﺩﻟﻴﻞ ، FATﻭﻣﻘﻄﻊ ﺍﻹﻗﻼﻉ ﻫﻮ ﻣﻘﻄﻊ ﳏﺠﻮﺯ ﺩﺍﺋﻤﺎ ﻟﺬﻟﻚ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﺍﳌﺘﻐﲑ
reserved sectorsﰲ ﻣﻌﻠﻮﻣﺎﺕ BPBﻫﻲ ﻭﺍﺣﺪ ،ﻭﰲ ﺣﺎﻟﺔ ﻣﺎ ﺃﺭﺩﺕ ﺣﺠﺰ ﻣﻘﺎﻃﻊ ﺃﺧﺮﻯ ﻛﻞ ﻣﺎ ﻋﻠﻴﻚ
ﻫﻮ ﺯﻳﺎﺩﺓ ﻫﺬﻩ ﺍﻟﻘﻴﻤﺔ ﺑﻌﺪﺩ ﺍﳌﻘﺎﻃﻊ ﺍﳌﺮﻏﻮﺑﺔ ،ﻭﻟﻠﻮﺻﻮﻝ ﺍﱃ ﳏﺘﻮﻳﺎﺕ ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﺍﻻﺿﺎﰲ)ﺍﻥ ﻛﺎﻥ ﻟﻪ ﻭﺟﻮﺩ(
ﻓﺎﻥ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳊﻘﻴﻘﻲ ﻟﻪ ﻫﻮ ﺍﳌﻘﻄﻊ 2ﺍﳌﺴﺎﺭ 0ﺍﻟﺮﺃﺱ ، 0ﺃﻣﺎ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻨﻄﻘﻲ ﻟﻪ ﻫﻮ ﺍﳌﻘﻄﻊ .1ﻭﺑﺸﻜﻞ ﻋﺎﻡ
ﻓﺎﻧﻪ ﰲ ﺍﻟﻐﺎﻟﺐ ﻻ ﻳﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻊ ﺍﺿﺎﻓﻴﺔ ﺳﻮﻯ ﻣﻘﻄﻊ ﺍﻻﻗﻼﻉ .ﺍﳌﻘﻄﻊ ﺍﻟﺜﺎﻟﺚ ﻫﻮ ﺟﺪﻭﻝ ، FATﻭﻫﻮ
ﺟﺪﻭﻝ ﳛﻮﻱ ﺳﺠﻼﺕ ﺑﻄﻮﻝ 12ﺑﺖ ﻋﻦ ﻛﻞ ﻛﻠﺴﺘﺮ ) (Clusterﰲ ﺍﻟﻘﺮﺹ ،ﺑﻴﺎﻧﺎﺕ ﻫﺬﺍ ﺍﻟﺴﺠﻞ ﺗﻮﺿﺢ ﻣﺎ
ﺍﺫﺍ ﻛﺎﻥ ﺍﻟﻜﻠﺴﺘﺮ ﻗﻴﺪ ﺍﻻﺳﺘﺨﺪﺍﻡ ﺃﻡ ﻻ ،ﻭﻫﻞ ﻫﻮ ﺁﺧﺮ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ﺃﻡ ﻻ ﻭﺇﺫﺍ ﻛﺎﻥ ﻟﻴﺲ ﺑﺎﺧﺮ ﻓﺎﻧﻪ ﻳﻮﺿﺢ
ﻟﻨﺎ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻟﺘﺎﱄ ﻟﻠﻤﻠﻒ ،ﻭﻳﻮﺿﺢ ﺍﻟﺸﻜﻞ ﺍﻟﺘﺎﱄ ﺗﺮﻛﻴﺒﺔ ﻫﺬﺍ ﺍﳉﺪﻭﻝ
ﺍﺫﴽ ﻫﺬﺍ ﻭﻇﻴﻔﺔ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻫﻲ ﻣﻌﺮﻓﺔ ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﺍﳋﺎﻟﻴﺔ ﻣﻦ ﻏﲑﻫﺎ ﻛﺬﻟﻚ ﺍﻟﻮﻇﻴﻔﺔ ﺍﻻﺧﺮﻯ ﻫﻲ ﻣﻌﺮﻓﺔ ﲨﻴﻊ
ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﳌﻠﻒ ﻣﺎ ﻭﻳﺘﻢ ﺫﻟﻚ ﺑﺎﻟﻨﻈﺮ ﺍﱃ ﻗﻴﻤﺔ ﺍﻟﺴﺠﻞ )ﻗﻴﻤﺔ ﺍﻝ 12ﺑﺖ( ،ﻭﺍﻟﻘﻴﻢ ﻫﻲ :
ﺍﻟﻘﻴﻤﺔ :0x00ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﻟﻜﻠﺴﺘﺮ ﺧﺎﱄ. •
ﺍﻟﻘﻴﻢ ﻣﻦ 0x02ﺍﱃ : 0xfefﺗﺪﻝ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻟﺘﺎﱄ )ﲟﻌﲎ ﺁﺧﺮ ﺃﻥ ﺍﻟﻜﻠﺴﺘﺮ ﳏﺠﻮﺯ ﻭﺗﻮﺟﺪ •
ﻛﻠﺴﺘﺮﺍﺕ ﻣﺘﺒﻘﻴﺔ ﻟﻠﻤﻠﻒ(.
ﺍﻟﻘﻴﻢ ﻣﻦ 0xff0ﺍﱃ :0xff6ﻗﻴﻢ ﳏﺠﻮﺯﺓ. •
٥٢
FAT12 .٥.٣ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ
ﻭﳝﻜﻦ ﺍﻟﻨﻈﺮ ﺍﱃ ﺟﺪﻭﻝ FATﺑﺄﻧﻪ ﻣﺼﻔﻮﻓﺔ ﻣﻦ ﺍﻟﻘﻴﻢ ﺃﻋﻼﻩ ،ﻭﻋﻨﺪﻣﺎ ﻧﺮﻳﺪ ﲢﻤﻴﻞ ﻣﻠﻒ ﻓﺎﻧﻨﺎ ﺳﻨﺄﰐ ﺑﻌﻨﻮﺍﻥ ﺃﻭﻝ
ﻛﻠﺴﺘﺮ ﻟﻪ ﻣﻦ ﺟﺪﻭﻝ ) Root Directoryﺳﻨﺄﰐ ﻋﻠﻴﻬﺎ ﻻﺣﻘﺎ( ﻭﺑﻌﺪﻫﺎ ﻧﺴﺘﺨﺪﻡ ﻋﻨﻮﺍﻥ ﺍﻟﻜﻠﺴﺘﺮ ﻙ indexﺍﱃ
ﺟﺪﻭﻝ FATﻭﻧﻘﺮﺃ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻘﺎﺑﻠﻪ ﻟﻠﻜﻠﺴﺘﺮ ،ﻓﺎﺫﺍ ﻛﺎﻧﺖ ﺍﻟﻘﻴﻤﺔ ﺑﲔ 0x02ﺍﱃ 0xfefﻓﺎﺎ ﺗﺪﻝ ﻋﻠﻰ ﺍﻟﻜﻠﺴﺘﺮ
ﺍﻟﺘﺎﱄ ﻟﻠﻤﻠﻒ ،ﻭﻣﻦ ﰒ ﺳﻨﺴﺘﺨﺪﻡ ﻫﺬﻩ ﺍﻟﻘﻴﻤﺔ ﺃﻳﻀﺎ ﻙ indexﻭﻧﻘﺮﺃ ﺍﻟﻘﻴﻤﺔ ﺍﳉﺪﻳﺪﺓ ،ﻭﻧﺴﺘﻤﺮ ﻋﻠﻰ ﻫﺬﺍ ﺍﳊﺎﻝ
ﺍﱃ ﺃﻥ ﻧﻘﺮﺃ ﻗﻴﻤﺔ ﺗﺪﻝ ﻋﻠﻰ ﺎﻳﺔ ﺍﳌﻠﻒ .ﻫﺬﺍ ﺍﳉﺪﻭﻝ FATﻳﺒﺪﺃ ﻣﻦ ﺍﳌﻘﻄﻊ ﺍﳌﻨﻄﻘﻲ ٧ 1ﻭﻃﻮﻟﻪ 9ﻣﻘﺎﻃﻊ ﺃﻱ
ﺃﻥ ﺎﻳﺔ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﺗﻜﻮﻥ ﰲ ﺍﳌﻘﻄﻊ ﺗﻜﻮﻥ ﰲ ﺁﺧﺮ ﺍﳌﻘﻄﻊ ،10ﻭﳌﻌﺮﻓﺔ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳊﻘﻴﻘﻲ ﻟﻠﻤﻘﻄﻊ ﻓﺎﻧﻪ ﳝﻜﻦ
ﺍﺳﺘﺨﺪﺍﻡ ﺑﻌﺾ ﺍﳌﻌﺎﺩﻻﺕ ﻟﻠﺘﺤﻮﻳﻞ ،ﻭﺍﻟﻘﺴﻢ ﺍﻟﺘﺎﱄ ﺳﻴﻮﺿﺢ ﺫﻟﻚ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺷﺮﺡ ﻣﺒﺴﻂ ﻋﻦ ﻫﻴﻜﻠﺔ ﺍﻟﻘﺮﺹ
ﺍﳌﺮﻥ ﻭﻛﻴﻔﻴﺔ ﺣﻔﻈﻪ ﻟﻠﺒﻴﺎﻧﺎﺕ .ﻭﺑﻌﺪ ﺟﺪﻭﻝ FATﺗﻮﺟﺪ ﻧﺴﺨﺔ ﺃﺧﺮﻯ ﻣﻦ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻭﺗﺴﺘﺨﺪﻡ ﻛﻨﺴﺨﺔ
ﺍﺣﺘﻴﺎﻃﻴﺔ backupﻭﻫﻲ ﺑﻨﻔﺲ ﺣﺠﻢ ﻭﺧﺼﺎﺋﺺ ﺍﻟﻨﺴﺨﺔ ﺍﻻﻭﱃ ،ﻭﺑﻌﺪﻫﺎ ﻳﺄﰐ ﺩﻟﻴﻞ ﺍﳉﺬﺭ Root Directory
ﻭﻫﻮ ﻣﺼﻔﻮﻓﺔ ﻣﻦ 224ﺳﺠﻞ ﻛﻞ ﺳﺠﻞ ﺑﻄﻮﻝ 32ﺑﺎﻳﺖ ،ﻭﻇﻴﻔﻴﺔ ﻫﺬﺍ ﺍﻟﺪﻟﻴﻞ ﻫﻲ ﺣﻔﻆ ﺃﲰﺎء ﺍﳌﻠﻔﺎﺕ
ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﻌﻠﻮﻣﺎﺕ ﺍﻟﱵ ﲣﺺ ﻭﻗﺖ ﺍﻻﻧﺸﺎء ﻭﺍﻟﺘﻌﺪﻳﻞ ﻭﺣﺠﻢ ﺍﳌﻠﻒ
ﻭﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ،ﻋﻨﻮﺍﻥ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺃﻫﻢ ﻣﻌﻠﻮﻣﺔ ﻟﻜﻲ ﻧﺴﺘﻄﻴﻊ ﲢﻤﻴﻞ ﺍﳌﻠﻒ ﻛﺎﻣﻼ ،ﺣﻴﺚ ﻛﻤﺎ
ﺫﻛﺮﻧﺎ ﺃﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﺳﻴﻌﻤﻞ ﻙ indexﰲ ﺟﺪﻭﻝ FATﻭﺑﻌﺪﻫﺎ ﺳﻨﺤﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻧﺖ ﺗﻮﺟﺪ ﻛﻠﺴﺘﺮﺍﺕ ﺃﺧﺮﻯ
ﳚﺐ ﲢﻤﻴﻠﻬﺎ ﺃﻡ ﺃﻥ ﺍﳌﻠﻒ ﻳﺘﻜﻮﻥ ﻣﻦ ﻛﻠﺴﺘﺮ ﻭﺍﺣﺪ .ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﳏﺘﻮﻳﺎﺕ ﺍﻟﺴﺠﻞ ﺍﻟﻮﺍﺣﺪ ﰲ ﺩﻟﻴﻞ
ﺍﻝ root directoryﺑﺪﺍءﴽ ﻣﻦ ﺍﻟﺒﺎﻳﺖ ﺍﻻﻭﻝ ﺍﱃ ﺍﻻﺧﲑ:
ﺍﻟﺒﺎﻳﺘﺎﺕ :7-0ﺍﺳﻢ ﺍﳌﻠﻒ) ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳊﺠﻢ ﺃﻗﻞ ﻣﻦ 8ﺑﺎﻳﺖ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺣﺮﻑ ﺍﳌﺴﺎﻓﺔ ﻟﺘﻌﺒﺌﺔ •
ﺍﳌﺘﺒﻘﻲ(.
ﺍﻟﺒﺎﻳﺘﺎﺕ :10-8ﺍﻣﺘﺪﺍﺩ ﺍﳌﻠﻒ)ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﺴﺎﻓﺔ ﺃﻳﻀﺎ ﻟﺘﻌﺒﺌﺔ ﺍﳌﺘﺒﻘﻲ(. •
٥٣
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﺍﻟﺒﺎﻳﺘﺎﺕ :25-24ﺗﺎﺭﻳﺦ ﺁﺧﺮ ﺗﻌﺪﻳﻞ )ﺗﺘﺒﻊ ﻧﻔﺲ ﺗﺮﺗﻴﺐ ﺍﻟﺒﺎﻳﺘﺎﺕ .(17-16 •
ﻭﳚﺐ ﻣﻼﺣﻈﺔ ﺃﻥ ﺣﺠﻢ ﺍﻟﺴﺠﻼﺕ ﻫﻮ ﺛﺎﺑﺖ Fixed Lenght Recordﻓﻤﺜﻼ ﺍﺳﻢ ﺍﳌﻠﻒ ﳚﺐ ﺍﻥ ﻳﻜﻮﻥ ﺑﻄﻮﻝ
8ﺑﺎﻳﺖ ﻭﰲ ﺣﺎﻟﺔ ﺯﺍﺩ ﻋﻠﻰ ﺫﻟﻚ ﻓﺎﻥ ﻫﺬﺍ ﺳﻮﻑ ﳛﺪﺙ ﺿﺮﺭﴽ ﻋﻠﻰ ﻫﺬﺍ ﺍﻟﺪﻟﻴﻞ ،ﺃﻳﻀﺎ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﻻﺳﻢ
ﲝﺠﻢ ﺃﻗﻞ ﻣﻦ ﺍﳌﻄﻠﻮﺏ ﻓﺎﻧﻪ ﳚﺐ ﺗﻜﻠﻤﺔ ﺍﻟﻌﺪﺩ ﺍﻟﻨﺎﻗﺺ ﻣﻦ ﺍﳊﺮﻭﻑ ﲝﺮﻑ ﺍﳌﺴﺎﻓﺔ .Space
٥٤
FAT12 .٥.٣ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ
٥٥
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 ﻭﺳﻴﺘﻢ ﺗﺴﻤﻴﺔ ﺍﳌﻠﻒ ﺑﺎﻻﺳﻢ
ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ، ﺣﺮﻭﻑ3 ﺣﺮﻭﻑ ﻭﺍﻻﻣﺘﺪﺍﺩ ﻋﻦ8 ﻭﳝﻜﻦ ﺗﺴﻤﻴﺘﻪ ﺑﺄﻱ ﺍﺳﻢ ﺍﺧﺮ ﺑﺸﺮﻁ ﺃﻥ ﻻ ﻳﺰﻳﺪ ﺍﻻﺳﻢ ﻋﻦ
.Root Directory ﺣﱴ ﻻ ﻳﺘﻀﺮﺭ ﺟﺪﻭﻝSpaces ﺳﻴﻘﻮﻡ ﺑﺎﺿﺎﻓﺔ ﻣﺴﺎﻓﺎﺕFAT12 ﻃﻮﻝ ﺍﻻﺳﻢ ﺃﻗﻞ ﻓﺎﻥ ﺩﺭﺍﻳﻔﺮ
(FAT12 ﻭﳝﻜﻨﻨﺎ ﺃﻥ ﻧﻔﺮﻕ ﺑﲔ ﺍﲰﺎء ﺍﳌﻠﻔﺎﺕ ﺍﻟﺪﺍﺧﻠﻴﺔ )ﻭﻫﻲ ﺍﻟﱵ ﻳﺘﻢ ﺍﺿﺎﻓﺔ ﻣﺴﺎﻓﺎﺕ ﻋﻠﻴﻬﺎ ﻭﻳﺴﺘﺨﺪﻣﻬﺎ ﻧﻈﺎﻡ
.(ﻭﺍﻷﲰﺎء ﺍﳋﺎﺭﺟﻴﺔ )ﻭﻫﻲ ﺍﻟﱵ ﻳﻨﺸﺌﻬﺎ ﺍﳌﺴﺘﺨﺪﻡ
٥٦
FAT12 ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ.٥.٣
٥٧
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
٥٨
FAT12 .٥.٣ﻣﻘﺪﻣﺔ ﺍﱃ ﻧﻈﺎﻡ
ﺟﺪﻭﻝ FATﻳﻮﺿﺢ ﺣﺎﻟﺔ ﻛﻞ ﺍﻟﻜﻠﺴﺘﺮﺍﺕ ﺍﳌﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﻟﻘﺮﺹ ﺳﻮﺍءﺍ ﻛﺎﻧﺖ ﺧﺎﻟﻴﺔ ﺃﻡ ﻣﻌﻄﻮﺑﺔ ﺃﻡ ﺍﺎ
ﻣﺴﺘﺨﺪﻣﺔ ،ﻭﳚﺐ ﲢﻤﻴﻞ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻲ ﻧﺴﺘﻄﻴﻊ ﻋﻦ ﻃﺮﻳﻖ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﺍﻟﺬﻱ ﲢﺼﻠﻨﺎ ﻋﻠﻴﻪ
ﻣﻦ ﺟﺪﻭﻝ Root Directoryﺃﻥ ﳓﻤﻞ ﲨﻴﻊ ﻛﻠﺴﺘﺮﺍﺕ ﺍﳌﻠﻒ .ﻭﺑﻨﻔﺲ ﺍﻟﻄﺮﻳﻘﺔ ﺍﻟﱵ ﻗﻤﻨﺎ ﺎ ﻟﺘﺤﻤﻴﻞ ﺟﺪﻭﻝ
Root Directoryﺳﻴﺘﻢ ﺎ ﲢﻤﻴﻞ ﺟﺪﻭﻝ FATﺣﻴﺚ ﳚﺐ ﲢﺪﺩ ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻗﻄﺎﻉ ﻟﻠﺠﺪﻭﻝ ﻭ ﻋﺪﺩ ﺍﻟﻘﻄﺎﻋﺎﺕ
ﺍﻟﱵ ﻳﺸﻐﻠﻬﺎ ﺍﳉﺪﻭﻝ ،ﻭﻛﺬﻟﻚ ﺍﳌﺴﺎﺣﺔ ﺍﳋﺎﻟﻴﺔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻲ ﻳﺘﻢ ﺣﻔﻆ ﺍﳊﺪﻭﻝ ﺎ .ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ
ﺫﻟﻚ.
٥٩
Bootloader .٣ﺇﻗﻼﻉ ﺍﳊﺎﺳﺐ ﻭﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ
ﺣﻴﺚ ﻳﺘﻢ ﻃﺮﺡ ﺍﻟﻌﺪﺩ 2ﻣﻦ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻭﻫﺬﺍ ﺑﺴﺒﺐ ﺃﻥ ﺃﻭﻝ ﺭﻗﻢ ﻛﻠﺴﺘﺮ ﰲ ﻧﻈﺎﻡ FAT12ﻫﻮ - 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ﻭﺍﻧﻪ ﻳﺘﻜﻮﻥ ﻣﻦ ﺳﺠﻼﺕ ﺑﻄﻮﻝ 12ﺑﺖ ﻭﺗﻌﺎﺩﻝ ﺑﺎﻳﺖ ﻭﻧﺼﻒ ،ﺃﻱ ﺃﻧﻪ ﺍﺫﺍ
ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ 0ﻓﺎﻧﻨﺎ ﳚﺐ ﺃﻥ ﻧﻘﺮﺃ ﺍﻟﺴﺠﻞ ﺍﻻﻭﻝ ﻣﻦ ﺟﺪﻭﻝ FATﻭﺑﺴﺒﺐ ﺍﻧﻪ ﻻ ﳝﻜﻦ ﻗﺮﺍءﺓ 12
ﺑﺖ ﻓﺴﻮﻑ ﺗﺘﻢ ﻗﺮﺍءﺓ 16ﺑﺖ )ﺍﻟﺴﺠﻞ ﺍﻻﻭﻝ ﺑﺎﻻﺿﺎﻓﺔ ﺍﱃ ﻧﺼﻒ ﺍﻟﺴﺠﻞ ﺍﻟﺜﺎﱐ( ﻭﻋﻤﻞ maskﻻﺧﺮ 4ﺑﺖ
)ﻻﺯﺍﻟﺔ ﻣﺎ ﰎ ﻗﺮﺍﺋﺘﻪ ﻣﻦ ﺍﻟﺴﺠﻞ ﺍﻟﺜﺎﱐ( .ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ 1ﻓﻴﺠﺐ ﻗﺮﺍءﺓ ﺍﻟﺴﺠﻞ ﺍﻟﺜﺎﱐ ﻣﻦ
ﺟﺪﻭﻝ FATﻭﺍﻟﺬﻱ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﺒﺖ 23-12ﻭﺑﺴﺒﺐ ﺃﻧﻪ ﻻ ﳝﻜﻦ ﻗﺮﺍءﺓ 12ﺑﺖ ﺳﻨﻘﻮﻡ ﺑﻘﺮﺍءﺓ 16ﺑﺖ ﺃﻱ ﻣﻦ
ﺍﻟﺒﺖ 23-8ﻭﺍﺯﺍﻟﺔ ﺃﻭﻝ 4ﺑﺖ.
ﻭﺑﺎﺧﺘﺼﺎﺭ ،ﻟﻘﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻘﺎﺑﻠﺔ ﻟﺮﻗﻢ ﻛﻠﺴﺘﺮ ﻣﺎ ﻓﻴﺠﺐ ﺃﻭﻻ ﺗﻄﺒﻴﻖ ﺍﻟﻘﺎﻧﻮﻥ :
)cluster = cluster + (cluster/2
ﻭﻗﺮﺍءﺓ 16ﺑﺖ ،ﻭﰲ ﺣﺎﻟﺔ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺭﻗﻢ ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺭﻗﻢ ﺯﻭﺟﻲ ﻓﻴﺠﺐ ﻋﻤﻞ 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.
٧ ; to read cluster 0 we need to read fat[0].
٨ ; cluster 1 −> fat[1].
٩ ; cluster 2 −> fat[3],...etc.
١٠
١١ mov cx,ax ; cx = cluster number.
١٢ shr cx,1 ; divide cx by 2.
١٣ add cx,ax ; cx = ax + (ax/2).
١٤ mov di,cx
١٥ add di,0x0200
١٦ mov dx,word[di] ; read 16−bit form FAT.
١٧
١٨
١٩ ; Now, because FAT entry are 12−bit long, we should remove 4
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
٦٦
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
ﺑﺴﺒﺐ ﺍﻟﻘﻴﻮﺩ ﻋﻠﻰ ﺣﺠﻢ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻓﺎﻥ ﻫﺬﺍ ﻗﺪ ﺃﺩﻯ ﺍﱃ ﺗﻘﺴﻴﻢ ﺍﳌﻬﻤﺔ ﺍﱃ ﻣﺮﺣﻠﺘﲔ ﺣﻴﺚ ﺍﻗﺘﺼﺮﺕ ﻣﻬﻤﺔ
ﺍﳌﺮﺣﻠﺔ ﺍﻻﻭﱃ ﻋﻠﻰ ﲢﻤﻴﻞ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﺍﳌﺤﻤﻞ ،ﺃﻣﺎ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ stage 2ﻓﻼ ﻗﻴﻮﺩ ﻋﻠﻴﻬﺎ ﻭﻏﺎﻟﺒﺎ ﻣﺎ ﻳﺘﻢ
ﺗﻨﻔﻴﺬ ﺍﳌﻬﻤﺎﺕ ﺍﻟﺘﺎﻟﻴﺔ ﰲ ﻫﺬﻩ ﺍﳌﺮﺣﻠﺔ:
ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ.PMode •
٦٧
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
:Code Descriptorﺗﺼﻒ ﺧﺼﺎﺋﺺ ﺍﳌﻘﻄﻊ ﺃﻭ ﺍﻟﻘﺴﻢ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﻳﻨﻔﺬ ﻛﺸﻔﺮﺓ .Code •
:Data Descriptorﺗﺼﻒ ﺧﺼﺎﺋﺺ ﺍﳌﻘﻄﻊ ﺃﻭ ﺍﻟﻘﺴﻢ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﻻ ﻳﻨﻔﺬ ﻭﳛﻮﻱ ﺑﻴﺎﻧﺎﺕ .Data •
ﺍﻟﺒﺘﺎﺕ :39-16ﲢﻮﻱ ﺃﻭﻝ ﺛﻼﺙ ﺑﺎﻳﺘﺎﺕ ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ .Base Address •
ﺍﻟﺒﺖ :40ﺑﺖ ﺍﻟﻮﺻﻮﻝ ) Access Bitﻳﺴﺘﺨﺪﻡ ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ .(Virtual Memory •
٦٨
ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ.١.٤
. ﳏﺠﻮﺯﺓ:52 ﺍﻟﺒﺖ •
. ﳏﺠﻮﺯﺓ:53 ﺍﻟﺒﺖ •
،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.
٦٩
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
٢٠
٢١ ; Data Descriptor: start at 0x10.
٢٢
٢٣ dw 0xffff ; limit low.
٢٤ dw 0x0 ; base low.
٢٥ db 0x0 ; base middle.
٢٦ db 10010010b ; access byte.
٢٧ db 11001111b ; granularity byte.
٢٨ db 0x0 ; base high.
٢٩
٣٠ end of gdt:
ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻳﺒﺪﺃ ﺑﺎﻟﻮﺍﺻﻔﺔ ﺍﳋﺎﻟﻴﺔ Null Descriptorﻭﺣﺠﻤﻬﺎ 8ﺑﺎﻳﺖ ﻭﻣﺘﺤﻮﻳﺎﺎ ﺗﻜﻮﻥ ﺻﻔﺮﴽ ﰲ ﺍﻟﻌﺎﺩﺓ ،ﺃﻣﺎ
ﺍﻟﻮﺍﺻﻔﺔ ﺍﻟﺘﺎﻟﻴﺔ ﳍﺎ ﻓﻬﻲ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﺸﻔﺮﺓ Code Descriptorﻭﺗﻮﺿﺢ ﺍﳌﻘﻄﻊ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺬﻱ ﺳﻴﺘﺴﺨﺪﻡ
ﻛﺸﻔﺮﺓ ﻭﻣﺎ ﻫﻲ ﺑﺪﺍﻳﺘﻪ ﻭﺣﺠﻤﻪ ﻭﺻﻼﺣﻴﺎﺕ ﺍﺳﺘﺨﺪﺍﻣﻪ ﺣﻴﺚ ﳝﻜﻦ ﺃﻥ ﻧﺴﻤﺢ ﻓﻘﻂ ﻟﻠﱪﺍﻣﺞ ﺍﻟﱵ ﺗﻌﻤﻞ ﻋﻠﻰ
ﻣﺴﺘﻮﻯ ﺍﻟﻨﻮﺍﺓ Kernel Modeﺑﺎﻟﺪﺧﻮﻝ ﺍﱃ ﻫﺬﺍ ﺍﳌﻘﻄﻊ.ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺷﺮﺡ ﳌﺤﺘﻮﻳﺎﺕ ﻫﺬﻩ ﺍﻟﻮﺍﺻﻔﺔ ﻭﳝﻜﻨﻚ
ﺍﳌﻄﺎﺑﻘﺔ ﻣﻊ ﺍﳉﺪﻭﻝ ﺍﻟﺬﻱ ﻳﻮﺿﺢ ﺍﻟﺸﻜﻞ ﺍﻟﻌﺎﻡ ﻟﻜﻞ ﻭﺍﺻﻔﺔ.
ﺗﺒﺪﺃ ﻭﺍﺻﻔﺔ ﺍﻟﻜﻮﺩ Code Descriptorﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0x8ﻭﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻣﻬﻢ ﺟﺪﺍ ﺣﻴﺚ ﺳﻴﻜﻮﻥ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ
ﻫﻮ ﻗﻴﻤﺔ ﺍﳌﺴﺠﻞ ، CSﻭﺍﻟﺒﺘﺎﺕ ﻣﻦ 15-0ﲢﺪﺩ ﺣﺠﻢ ﺍﳌﻘﻄﻊ Segment Limitﻭﺍﻟﻘﻴﻤﺔ ﻫﻲ 0xffffﺗﺪﻝ
ﻋﻠﻰ ﺃﻥ ﺃﻛﱪ ﺣﺠﻢ ﳝﻜﻦ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ ﻫﻮ .0xffff
ﺍﻟﺒﺘﺎﺕ ﻣﻦ 39-16ﲤﺜﻞ ﺍﻟﺒﺘﺎﺕ 23-0ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ Base Addressﻭﺍﻟﻘﻴﻤﺔ ﺍﻟﱵ ﰎ ﺍﺧﺘﻴﺎﺭﻫﺎ ﻫﻲ
0x0ﻭﺑﺎﻟﺘﺎﱄ ﻧﻌﺮﻑ ﺃﻥ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﻫﻮ 0x0ﻭﻋﻨﻮﺍﻥ ﺍﻟﻨﻬﺎﻳﺔ . 0xffff
ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 6ﻭﻳﺴﻤﻰ Access Byteﳛﺪﺩ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺗﻮﺿﻴﺢ ﳌﻌﲎ ﻛﻞ ﺑﺖ ﻣﻮﺟﻮﺩﺓ
ﻓﻴﻪ:
• ﺍﻟﺒﺖ Access Bit :0ﻭﻳﺴﺘﺨﺪﻡ ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ ﻟﺬﻟﻚ ﺍﺧﺘﺮﻧﺎ ﺍﻟﻘﻴﻤﺔ .0
ﺍﻟﺒﺖ :1ﺑﺖ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ ،ﻭﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1ﻟﺬﺍ ﳝﻜﻦ ﻗﺮﺍءﺓ ﻭﺗﻨﻔﻴﺬ ﺃﻱ ﺑﺎﻳﺖ ﻣﻮﺟﻮﺩﺓ ﰲ •
ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﻣﻦ .0xffff-0x0
expansion direcﻻ ﻳﻬﻢ ﺣﺎﻟﻴﺎ ﻟﺬﺍ ﺍﻟﻘﻴﻤﺔ ﻫﻲ .0 on :2 ﺍﻟﺒﺖ •
ﺍﻟﺒﺖ :3ﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﻣﻘﻄﻊ ﺷﻔﺮﺓ .Code Segment •
ﺍﻟﺒﺖ :4ﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﻣﻘﻄﻊ ﻟﻠﺸﻔﺮﺓ ﺍﻭ ﻟﻠﺒﻴﺎﻧﺎﺕ ﻭﻟﻴﺲ ﻟﻠﻨﻈﺎﻡ. •
ﺍﻟﺒﺘﺎﺕ :6-5ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ ﻭﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 0ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻳﺴﺘﺨﺪﻡ ﻓﻘﻂ ﰲ ﺍﳊﻠﻘﺔ •
ﺻﻔﺮ Ring0ﺃﻭ ﻣﺎ ﻳﺴﻤﻰ .Kernel Mode
ﺍﻟﺒﺖ :7ﺗﺴﺘﺨﺪﻡ ﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻈﺎﻫﺮﻳﺔ ﻟﺬﺍ ﰎ ﺍﳘﺎﳍﺎ. •
٧٠
.١.٤ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ
ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ 7ﻭﻳﺴﻤﻰ granularityﳛﺪﺩ ﺃﻳﻀﺎ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ ،ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺗﻮﺿﻴﺢ ﳌﻌﲎ ﻛﻞ ﺑﺖ ﻣﻮﺟﻮﺩﺓ
ﻓﻴﻪ:
ﺍﻟﺒﺘﺎﺕ :3-0ﲤﺜﻞ ﺍﻟﺒﺘﺎﺕ ﻣﻦ 19-16ﻣﻦ ﺎﻳﺔ ﺣﺠﻢ ﺍﳌﻘﻄﻊ Segment Limitﻭﺍﻟﻘﻴﻤﺔ ﻫﻲ ، 0xf •
ﻭﺬﺍ ﻳﻜﻮﻥ ﺃﻗﺼﻰ ﻋﻨﻮﺍﻥ ﻟﻠﻤﻘﻄﻊ ﻫﻮ 0xfffffﺃﻱ 1ﻣﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ،ﻭﻻﺣﻘﴼ ﻋﻨﺪﻣﺎ ﻳﺘﻢ ﺗﻔﻌﻴﻞ
ﺑﻮﺍﺑﺔ A20ﺳﻨﺘﻤﻜﻦ ﻣﻦ ﺍﻟﻮﺻﻮﻝ ﺣﱴ 4ﺟﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ.
ﺍﻟﺒﺘﺎﺕ :5-4ﳏﺠﻮﺯﺓ ﻟﻠﻨﻈﺎﻡ ﻟﺬﺍ ﰎ ﺍﳘﺎﳍﺎ. •
ﺍﻟﺒﺖ :6ﰎ ﺍﺧﺘﻴﺎﺭ ﺍﻟﻘﻴﻤﺔ 1ﺩﻻﻟﺔ ﻋﻠﻰ ﻫﺬﺍ ﺍﳌﻘﻄﻊ ﻫﻮ 32ﺑﺖ. •
ﺍﻟﺒﺎﻳﺖ ﺍﻻﺧﲑ ﰲ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ )ﺍﻟﺒﺎﻳﺖ ﺭﻗﻢ (8ﳝﺜﻞ ﺍﻟﺒﺘﺎﺕ ﻣﻦ 32-24ﻣﻦ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ
ﻭﺍﻟﻘﻴﻤﺔ ﻫﻲ 0x0ﻭﺑﺎﻟﺘﺎﱄ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﺍﻟﻜﻠﻲ ﻫﻮ 0x0ﺃﻱ ﻣﻦ ﺃﻭﻝ ﺑﺎﻳﺖ ﰲ ﺍﻟﺬﺍﻛﺮﺓ.
ﺇﺫﴽ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ Code Descriptorﺣﺪﺩﺕ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻣﻘﻄﻊ ﺍﻟﻜﻮﺩ ﻭﺎﻳﺘﻪ ﻭﻛﺬﻟﻚ ﺻﻼﺣﻴﺔ ﺍﻟﺘﻨﻔﻴﺬ
ﻭﺣﺪﺩﺕ ﺑﺄﻥ ﺍﳌﻘﻄﻊ ﻫﻮ ﻣﻘﻄﻊ ﻛﻮﺩ .Code Segment
ﺍﻟﻮﺍﺻﻔﺔ ﺍﻟﺘﺎﻟﻴﺔ ﻫﻲ ﻭﺍﺻﻔﺔ ﻣﻘﻄﻊ ﺍﻟﺒﻴﺎﻧﺎﺕ Data Descriptorﻭﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ﺭﻗﻢ 0x10ﻭﻫﻲ ﻣﺸﺎﺔ ﲤﺎﻣﺎ
ﻟﻮﺍﺻﻔﺔ ﺍﻟﻜﻮﺩ ﺑﺎﺳﺘﺜﻨﺎء ﺍﻟﺒﺖ ﺭﻗﻢ 43ﺣﻴﺚ ﳛﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ ﻛﻮﺩ ﺃﻡ ﺑﻴﺎﻧﺎﺕ.
ﻭﺑﻌﺪ ﺇﻧﺸﺎء ﻫﺬﺍ ﺍﳉﺪﻭﻝ ) (GDTﰲ ﺍﻟﺬﺍﻛﺮﺓ ،ﳚﺐ ﺃﻥ ﻳﺤﻤِﻞ ﺍﳌﺴﺠﻞ gdtrﻋﻠﻰ ﺣﺠﻢ ﻫﺬﺍ ﺍﳉﺪﻭﻝ ﻧﺎﻗﺼﺎ
ﻭﺍﺣﺪ ﻭﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳉﺪﻭﻝ ،ﻭﻳﺘﻢ ﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﺇﻧﺸﺎء ﻣﺆﺷﺮﺍ ﺍﱃ ﺟﺪﻭﻝ GDTﻭﻣﻦ ﰒ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻻﻣﺮ
) lgdtﻭﻫﻮ ﺃﻣﺮ ﻳﻌﻤﻞ ﻓﻘﻂ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ، (Ring0ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﺫﻟﻚ.
Example ٤.٢: Load GDT into GDTR
١
٢ bits 16 ; 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:
٢٤
٢٥ dw end of gdt − begin of gdt − 1 ; size −1
٢٦ dd begin of gdt ; base of gdt
٧٢
ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ.١.٤
٧٣
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
٧٤
A20 .٢.٤ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ
ﻭﲞﺼﻮﺹ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﻣﺘﺤﻜﻢ (8042ﻓﻐﺎﻟﺒﺎ ﻣﺎ ﺗﺄﰐ ﻋﻠﻰ ﺷﻜﻞ ﺷﺮﳛﺔ Integrated Circuitﺃﻭ
ﺗﻜﻮﻥ ﻣﻀﻤﻨﺔ ﺩﺍﺧﻞ ﺍﻟﻠﻮﺣﺔ ﺍﻷﻡ ) (Motherboardﻭﺗﻜﻮﻥ ﰲ ﺍﻝ .South Bridgeﻭﻳﺮﺗﺒﻂ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﻣﻊ
ﻣﺘﺤﻜﻢ ﺁﺧﺮ ﺑﺪﺍﺧﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ،ﻭﻋﻨﺪ ﺍﻟﻀﻐﻂ ﻋﻠﻰ ﺯﺭ ﻣﺎ ﻓﺎﻧﻪ ﻳﺘﻢ ﺗﻮﻟﻴﺪ Make Codeﻭﻳُﺮﺳﻞ ﺍﱃ
ﺍﳌﺘﺤﻜﻢ ﺍﳌﻮﺟﻮﺩ ﺑﺪﺍﺧﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﺍﻟﺬﻱ ﺑﺪﺭﻭﻩ ﻳﻘﻮﻡ ﺑﺎﺭﺳﺎﻟﻪ ﺍﱃ ﻣﺘﺤﻜﻢ 8042ﻋﻦ ﻃﺮﻳﻖ ﻣﻨﻔﺬ ﺍﳊﺎﺳﺐ
). (Hardware Portﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ ﻣﺘﺤﻜﻢ 8042ﺣﻴﺚ ﻳﻘﻮﻡ ﺑﺘﺤﻮﻳﻞ Make codeﺍﱃ Scan Codeﻭﳛﻔﻈﻬﺎ
ﰲ ﻣﺴﺠﻼﺗﻪ ﺍﻟﺪﺍﺧﻠﻴﺔ Bufferﻫﺬﺍ ﺍﳌﺴﺠﻞ ﳛﻤﻞ ﺍﻟﺮﻗﻢ 0x60ﰲ ﺃﺟﻬﺰﺓ ،IBM and Compa ble PCﻭﻫﺬﺍ
ﻳﻌﲏ ﺃﻧﻪ ﰲ ﺣﺎﻟﺔ ﻗﺮﺍءﺓ ﻫﺬﺍ ﺍﳌﺴﺠﻞ )ﻋﻦ ﻃﺮﻳﻖ ﺍﻷﻣﺮ (inﻓﺎﻧﻪ ﳝﻜﻦ ﻗﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ ﺍﳌﺪﺧﻠﺔ.
ﻭﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﻣﻦ ﺳﻴﺘﻢ ﻣﻨﺎﻗﺸﺔ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﺑﺎﻟﺘﻔﺼﻴﻞ ،ﻭﺳﻨﻜﺘﻔﻲ ﻫﻨﺎ ﻓﻘﻂ ﺑﺘﻮﺿﻴﺢ ﺍﻷﺟﺰﺍء ﺍﳌﺘﻌﻠﻘﺔ
ﺑﺘﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ .A20
.on ﺍﻟﺒﺘﺎﺕ : HDD ac vity LED :7-6ﺍﻟﻘﻴﻤﺔ ،off :0ﺍﻟﻘﻴﻤﺔ :1 •
٧٥
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
ﻭﳚﺐ ﻣﻼﺣﻈﺔ ﺃﻥ ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ ﻻ ﺗﻌﻤﻞ ﰲ ﻛﻞ ﺍﻻﺟﻬﺰﺓ ﻭﺭﲟﺎ ﻳﻜﻮﻥ ﻫﻨﺎﻙ ﺍﺭﻗﺎﻡ ﳐﺘﻠﻔﺔ ﻟﻠﻤﻨﺎﻓﺬ ،ﻭﻳﻌﺘﻤﺪ ﰲ
ﺍﻵﺧﺮ ﻋﻠﻰ ﻣﺼﻨﻌﻲ ﺍﻟﻠﻮﺣﺎﺕ ﺍﻻﻡ ﻭﳚﺐ ﻗﺮﺍءﺓ ﻛﺘﻴﺒﺎﺎ ﳌﻌﺮﻓﺔ ﺍﻟﻌﻨﺎﻭﻳﻦ.
ﺑﻮﺍﺳﻄﺔ ﺍﻟﺒﺎﻳﻮﺱ
0x2400 ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ int 0x15ﺍﻟﺪﺍﻟﺔ 0x2401ﻟﺘﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ ، A20ﻭﺍﻟﺪﺍﻟﺔ
ﻟﺘﻌﻄﻴﻠﻬﺎ.ﻣﻊ ﺍﻟﺘﺬﻛﲑ ﺑﺄﻥ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﺍﳌﻌﺎﰿ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﺳﺘﺪﻋﺎء ﻫﺬﻩ ﺍﳌﻘﺎﻃﻌﺔ،
ﻭﺍﻟﻜﻮﺩ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻃﺮﻳﻘﺔ ﺍﻟﺘﻔﻌﻴﻞ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺍﻟﺒﺎﻳﻮﺱ.
Example ٤.٥: Enable A20 by BIOS int 0x15
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ١
٢ ; enable a20 bios:
; ٣ Enable A20 with BIOS int 0x15 routine 0x2401
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٤
٥
٦ enable a20 bios:
٧
٨ pusha ; save all registers
٩
١٠ mov ax,0x2401 ; Enable A20 routine.
١١ int 0x15
١٢
١٣ popa ; restore registers
١٤ ret
٧٦
A20 .٢.٤ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ
ﺍﳌﺘﺤﻜﻢ ) .(Statusﺣﻴﺚ ﻳﺘﻢ ﺍﺭﺳﺎﻝ ﺍﻷﻭﺍﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﻋﻦ ﻃﺮﻳﻖ ﺍﳌﻨﻔﺬ 0x64ﻭﺍﺫﺍ ﻛﺎﻥ ﻫﻨﺎﻙ ﻭﺳﺎﺋﻂ
ﳍﺬﺍ ﺍﻷﻣﺮ ﻓﺘﺮﺳﻞ ﺍﱃ ﺍﻝ ) bufferﺍﳌﻨﻔﺬ (0x60ﻭﻛﺬﻟﻚ ﺗﻘﺮﺃ ﺍﻟﻨﺘﺎﺋﺞ ﻣﻦ ﺍﳌﻨﻔﺬ .0x60
ﻭﺣﻴﺚ ﺍﻥ ﺗﻨﻔﻴﺬ ﺃﻭﺍﻣﺮ ﺍﻟﱪﻧﺎﻣﺞ )ﻋﻦ ﻃﺮﻳﻖ ﺍﳌﻌﺎﰿ( ﺃﺳﺮﻉ ﺑﻜﺜﲑ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻷﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ ﺍﱃ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ
ﺍﳌﻔﺎﺗﻴﺢ )ﻭﺑﺸﻜﻞ ﻋﺎﻡ ﺍﱃ ﺃﻱ ﻣﺘﺤﻜﻢ ﻟﻌﺘﺎﺩ ﻣﺎ( ﻓﺎﻧﻪ ﳚﺐ ﺍﻥ ﻧﻮﻓﺮ ﻃﺮﻗﴼ ﻻﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﻗﺒﻞ ﺍﻟﻌﻮﺩﺓ ﺍﱃ
ﺍﻟﱪﻧﺎﻣﺞ ﻻﺳﺘﻜﻤﺎﻝ ﺍﻟﺘﻨﻔﻴﺬ .
ﻭﳝﻜﻦ ﻋﻦ ﻃﺮﻳﻖ ﻗﺮﺍءﺓ ﺣﺎﻟﺔ ﺍﳌﺘﺤﻜﻢ )ﻋﻦ ﻃﺮﻳﻖ ﻗﺮﺍءﺓ ﺍﳌﻨﻔﺬ (0x64ﺃﻥ ﻧﻌﺮﻑ ﻣﺎ ﺍﺫﺍ ﰎ ﺗﻨﻔﻴﺬ ﺍﻻﻭﺍﻣﺮ ﺍﳌﺮﺳﻠﺔ
ﺍﻡ ﻻ ،ﻭﻛﺬﻟﻚ ﻫﻞ ﻫﻨﺎﻙ ﻧﺘﻴﺠﺔ ﻟﻜﻲ ﻳﺘﻢ ﻗﺮﺍﺋﺘﻬﺎ ﰲ ﺍﻟﱪﻧﺎﻣﺞ ﺍﻡ ﻻ.
ﻭﻣﺎ ﻳﻬﻤﻨﺎ ﻣﻦ ﺍﻟﺒﺘﺎﺕ ﻋﻨﺪ ﻗﺮﺍءﺓ ﺣﺎﻟﺔ ﺍﳌﺘﺤﻜﻢ ﺣﺎﻟﻴﺎ ﻫﻮ ﺃﻭﻝ ﺑﺘﲔ ﻓﻘﻂ ،ﻭﻭﻇﻴﻔﺘﻬﻤﺎ ﻫﻲ:
ﺍﻟﺒﺖ :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:
٧
٨ in al,0x64 ; read status
٩ test al,0x1 ?; is output buffer is empty
١٠ je wait output ; yes, hang.
١١
١٢ ret ; no,there is a result.
١٣
١٤
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ١٥
١٦ ; wait input: wait input buffer to be empty.
٧٧
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
ﻭﻹﺭﺳﺎﻝ ﺍﻭﺍﻣﺮ ﺍﱄ ﺍﳌﺘﺤﻜﻢ ﻓﺎﻥ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﺍﳌﻨﻔﺬ 0x64ﻭﺗﻮﺟﺪ ﺍﻟﻜﺜﲑ ﻣﻦ ﺍﻷﻭﺍﻣﺮ ،ﻭﻧﻈﺮﺍ ﻻﻥ ﻫﺬﺍ ﺍﳉﺰء
ﻏﲑ ﳐﺼﺺ ﻟﱪﳎﺔ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻓﺎﻧﻨﺎ ﺳﻨﻨﺎﻗﺶ ﻓﻘﻂ ﺍﻻﻭﺍﻣﺮ ﺍﻟﱵ ﻤﻨﺎ ﺣﺎﻟﻴﺎ ،ﻭﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺩﺱ
ﺳﻨﻌﻮﺩ ﺍﱃ ﺍﳌﻮﺿﻮﻉ ﺑﺎﻟﺘﻔﺼﻴﻞ ﺍﻥ ﺷﺎء ﺍﷲ.
ﻭﻗﺎﺋﻤﺔ ﺍﻻﻭﺍﻣﺮ ﺣﺎﻟﻴﺎ:
• ﺍﻷﻣﺮ :0xadﺗﻌﻄﻴﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.
ﺍﻷﻣﺮ :0xaeﺗﻔﻌﻴﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ. •
ﻭﻋﻦ ﻃﺮﻳﻖ ﺍﻷﻣﺮ 0xddﻓﺎﻧﻪ ﳝﻜﻦ ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ A20ﺑﺴﻬﻮﻟﺔ ﻛﻤﺎ ﰲ ﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ،ﻟﻜﻦ ﺃﻳﻀﺎ ﻫﺬﻩ ﺍﻟﻄﺮﻳﻘﺔ
ﻻ ﺗﻌﻤﻞ ﻋﻠﻰ ﻛﻞ ﺍﻻﺟﻬﺰﺓ ﺣﻴﺚ ﻫﻨﺎﻙ ﺑﻌﺾ ﺍﳌﺘﺤﻜﻤﺎﺕ ﻻ ﺗﺪﻋﻢ ﻫﺬﺍ ﺍﻷﻣﺮ.
Example ٤.٧: Enable A20 by Send 0xdd
١
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٢
٣ ; enable a20 keyboard controller:
; ٤ Enable A20 with command 0xdd
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٥
٦
٧ enable a20 keyboard controller:
٨
٩ ;cli
٧٨
A20 .٢.٤ﺗﻔﻌﻴﻞ ﺍﻟﺒﻮﺍﺑﺔ
ﻭﺗﻮﺟﺪ ﻃﺮﻳﻘﺔ ﺃﺧﺮﻯ ﺃﻛﺜﺮ ﳏﻤﻮﻟﻴﺔ ﻭﻫﻲ ﻋﻦ ﻃﺮﻳﻖ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ Output Portﰲ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ
ﻭﳝﻜﻦ ﻗﺮﺍءﺓ ﻫﺬﺍ ﺍﳌﻨﻔﺬ ﻭﺍﻟﻜﺘﺎﺑﺔ ﺍﻟﻴﻪ ﻋﻦ ﻃﺮﻳﻖ ﺍﺭﺳﺎﻝ ﺍﻻﻭﺍﻣﺮ 0xd0ﻭ 0xd1ﻋﻠﻰ ﺍﻟﺘﻮﺍﱄ.
ﻭﻋﻨﺪ ﻗﺮﺍءﺓ ﻫﺬﺍ ﺍﳌﻨﻔﺬ )ﺑﺎﺭﺳﺎﻝ ﺍﻻﻣﺮ d0ﺍﱃ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ( ﻓﺎﻥ ﺍﻟﻘﻴﻢ ﺗﻌﲏ:
ﺍﻟﺒﺖ :System Reset :0 •
– ﺍﻟﻘﻴﻤﺔ .Reset Computer :0
– ﺍﻟﻘﻴﻤﺔ .Normal Opera on :1
ﺍﻟﺒﺖ :1ﺑﻮﺍﺑﺔ :A20 •
– ﺍﻟﻘﻴﻤﺔ :0ﺗﻌﻄﻴﻞ.
– ﺍﻟﻘﻴﻤﺔ :1ﺗﻔﻌﻴﻞ.
ﺍﻟﺒﺘﺎﺕ :3-2ﻏﲑ ﻣﻌﺮﻑ. •
٧٩
ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ- ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤
٨٠
VGA .٣.٤ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ
ﺣﻴﺚ ﰲ ﺍﻟﺒﺪﺍﻳﺔ ﰎ ﺗﻌﻄﻴﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﻋﻦ ﻃﺮﻳﻖ ﺍﺭﺳﺎﻝ ﺍﻻﻣﺮ (0xadﻭﺍﺳﺘﺪﻋﺎء ﺍﻟﺪﺍﻟﺔ wait inputﻟﻠﺘﺄﻛﺪ
ﻣﻦ ﺃﻥ ﺍﻻﻣﺮ ﻗﺪ ﰎ ﺗﻨﻔﻴﺬﻩ ﻭﻣﻦ ﰒ ﰎ ﺍﺭﺳﺎﻝ ﺃﻣﺮ ﻗﺮﺍءﺓ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ ﳌﺘﺤﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﺍﻻﻣﺮ (0xda
ﻭﺍﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﺣﱴ ﻳﻨﺘﻬﻲ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻻﻣﺮ ،ﻭﻗﺪ ﰎ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﺪﺍﻟﺔ wait outputﻻﻧﺘﻈﺎﺭ ﻗﻴﻤﺔ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ
،ﻭﺑﻌﺪﻫﺎ ﰎ ﻗﺮﺍءﺓ ﻫﺬﻩ ﺍﻟﻘﻴﻤﺔ ﻭﺣﻔﻈﻬﺎ ﰲ ﺍﳌﻜﺪﺱ )، (Stackﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﺍﺭﺳﺎﻝ ﺃﻣﺮ ﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ﻣﻨﻔﺬ ﺍﳋﺮﻭﺝ
ﳌﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ )ﺍﻻﻣﺮ (0xd1ﻭﺍﻧﺘﻈﺎﺭ ﺍﳌﺘﺤﻜﻢ ﺣﻰ ﻳﻨﺘﻬﻲ ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻻﻣﺮ ﻭﻣﻦ ﻗﻤﻨﺎ ﺑﺎﺭﺳﺎﻝ ﻗﻴﻤﺔ
ﺍﳌﻨﻔﺬ ﺍﳋﺮﻭﺝ ﺍﳉﺪﻳﺪﺓ ﺑﻌﺪ ﺃﻥ ﰎ ﺗﻔﻌﻴﻞ ﺍﻟﺒﺖ ﺭﻗﻢ 1ﻭﻫﻮ ﺍﻟﺒﺖ ﺍﻟﺬﻱ ﻳﻔﻌﻞ ﺑﻮﺍﺑﺔ ، A20ﻭﰲ ﺍﻻﺧﲑ ﰎ ﺗﻔﻌﻴﻞ
ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﳎﺪﺩﺍ.
٨١
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
A ribute Graphics Controller , Sequencer unit , CRT Controller , Video DAC ,Video Bufferﻭ
.٣ Controller
ﺍﻝ Video Bufferﻫﻮ ﻣﻘﻄﻊ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ segment of memoryﻳﻌﻤﻞ ﻛﺬﺍﻛﺮﺓ ﻟﻠﺸﺎﺷﺔ Memory Mapped
،ﻭﻋﻨﺪ ﺑﺪﺍﻳﺔ ﺍﻟﺘﺸﻐﻴﻞ ﻓﺎﻥ ﺍﻟﺒﺎﻳﻮﺱ ﳜﺼﺺ ﻣﺴﺎﺣﺔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﺑﺪءﺍ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ 0xa0000ﻛﺬﺍﻛﺮﺓ ﻟﻠﺸﺎﺷﺔ
ﻭﰲ ﺣﺎﻟﺔ ﰎ ﺍﻟﻜﺘﺎﺑﺔ ﺍﱃ ﻫﺬﻩ ﺍﻟﺬﺍﻛﺮﺓ ﻓﺎﻥ ﻫﺬﺍ ﺳﻮﻑ ﻳﻐﲑ ﰲ ﺍﻟﺸﺎﺷﺔ ،ﻫﺬﺍ ﺍﻟﺮﺑﻂ ﻳﺴﻤﻰ ،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ﰲ ﻋﺎﻡ ، 1981ﻭ MDAﻻ ﺗﺪﻋﻢ ﺍﻟﻨﻤﻂ ﺍﻟﺮﺳﻮﻣﻲ ﻭﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ ﺎ
)ﻳﺴﻤﻰ (Mode 7ﻳﺪﻋﻢ 80ﻋﻤﻮﺩ ﻭ 24ﺻﻒ ) .(25*80ﻭﰲ ﻧﻔﺲ ﺍﻟﻌﺎﻡ ﻗﺎﻣﺖ IBMﺑﺘﻄﻮﻳﺮ ﻣﻘﻴﺎﺱ
) Color Graphics Adapterﻭﺍﺧﺘﺼﺎﺭﺍ (CGAﺍﻟﺬﻱ ﻛﺎﻥ ﺃﻭﻝ ﻣﺘﺤﻜﻢ ﻳﺪﻋﻢ ﺍﻻﻟﻮﺍﻥ ﺣﻴﺚ ﳝﻜﻦ ﻋﺮﺽ 16
ﻟﻮﻥ ﳐﺘﻠﻒ.ﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﺗﻄﻮﻳﺮ .Enhanced Graphics Adapter
ﻭﳚﺪﺭ ﺑﻨﺎ ﺍﻟﺘﺬﻛﲑ ﺑﺎﻥ ﻣﺘﺤﻜﻤﺎﺕ VGAﻣﺘﻮﺍﻓﻘﺔ ﻣﻊ ﺍﳌﻘﺎﻳﻴﺲ ﺍﻟﺴﺎﺑﻘﺔ Backward Compa bleﻓﻌﻨﺪﻣﺎ ﻳﺒﺪﺃ
ﺍﳊﺎﺳﺐ ﰲ ﺍﻟﻌﻤﻞ ﻓﺎﻥ ﺍﻟﻨﻤﻂ ﺳﻴﻜﻮﻥ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ ) Mode 7ﺍﻟﺬﻱ ﻇﻬﺮ ﰲ ، (MDAﻭﻫﺬﺍ ﻳﻌﲏ ﺍﻧﻨﺎ ﺳﻨﺘﻌﺎﻣﻞ
ﻣﻊ 80ﻋﻤﻮﺩ ﻭ 25ﺻﻒ.
ﻭﻋﻨﺪ ﺍﻟﻜﺘﺎﺑﺔ ﰲ ﻫﺬﻩ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻓﺎﻥ ﻫﺬﺍ ﺳﻮﻑ ﻳﺆﺛﺮ ﰲ ﺍﻟﺸﺎﺷﺔ ﻭﺍﻇﻬﺎﺭ ﺍﻟﻘﻴﻢ ﺍﻟﱵ ﰎ ﻛﺘﺎﺑﺘﻬﺎ ،ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ
ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﻛﺘﺎﺑﺔ ﺣﺮﻑ Aﺑﻠﻮﻥ ﺃﺑﻴﺾ ﻭﺧﻠﻔﻴﺔ ﺳﻮﺩﺍء.
٣ﺷﺮﺡ ﻫﺬﻩ ﺍﳌﻜﻮﻧﺎﺕ ﺳﻴﻜﻮﻥ ﻻﺣﻘﺎ ﺑﺎﺫﻥ ﺍﷲ ،ﻭﺳﻴﺘﻢ ﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﺑﻌﺾ ﺍﻻﺷﻴﺎء ﲝﺴﺐ ﺍﳊﺎﺟﺔ ﺣﺎﻟﻴﺎ.
٨٢
VGA .٣.٤ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ
ﻭﺑﺴﺒﺐ ﺃﻥ ﻫﻨﺎﻙ 80ﺣﺮﻑ ﰲ ﻛﻞ ﻋﻤﻮﺩ ﻓﺎﻧﻪ ﳚﺐ ﺿﺮﺏ ﻗﻴﻤﺔ yﺏ . 80ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ
ﻃﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻨﺪ ). (4,4
address = x + y ∗ 80
address = 4 + 4 ∗ 80 = 324
ﻭﺑﺎﺭﺳﺎﻝ ﺍﳊﺮﻑ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 0xb8144ﻓﺎﻥ ﺍﳊﺮﻑ ﺳﻮﻑ ﻳﻈﻬﺮ ﻋﻠﻰ ﺍﻟﺸﺎﺷﺔ ﰲ ﺍﻟﺼﻒ ﺍﳋﺎﻣﺲ ﻭﺍﻟﻌﻤﻮﺩ
ﺍﳋﺎﻣﺲ )ﺍﻟﺘﺮﻗﻴﻢ ﻳﺒﺪﺃ ﻣﻦ ﺻﻔﺮ ﻭﺃﻭﻝ ﺻﻒ ﻭﻋﻤﻮﺩ ﺭﻗﻤﻬﺎ ﺻﻔﺮ(.
ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺍﻥ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ Mode 7ﻫﻮ ﺍﻟﺬﻱ ﻳﺒﺪﺃ ﺍﳊﺎﺳﺐ ﺑﻪ ،ﰲ ﻫﺬﺍ ﺍﻟﻨﻤﻂ ﻳﺘﻌﺎﻣﻞ ﻣﺘﺤﻜﻢ ﺍﻟﻌﺮﺽ
٨٣
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
ﻣﻊ ﺑﺎﻳﺘﲔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻞ ﺣﺮﻑ ﻳﺮﺍﺩ ﻃﺒﺎﻋﺘﻪ ،ﲟﻌﲎ ﺍﺫﺍ ﻣﺎ ﺃﺭﺩﻧﺎ ﻃﺒﺎﻋﺔ ﺍﳊﺮﻑ Aﻓﺎﻧﻪ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ
ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 0xb8000ﻭﺧﺼﺎﺋﺺ ﺍﳊﺮﻑ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺘﺎﱄ ﻟﻪ 0xb8001ﻭﻫﺬﺍ ﻳﻌﲏ ﺍﻧﻪ ﳚﺐ ﺗﻌﺪﻳﻞ ﻗﺎﻧﻮﻥ
ﺍﻟﺘﺤﻮﻳﻞ ﺍﻟﺴﺎﺑﻖ ﻭﺍﻋﺘﺒﺎﺭ ﺃﻥ ﻛﻞ ﺣﺮﻑ ﻳﺄﺧﺬ ﺑﺎﻳﺘﲔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻟﻴﺲ ﺑﺎﻳﺖ ﻭﺍﺣﺪ.
ﺍﻟﺒﺎﻳﺖ ﺍﻟﺜﺎﱐ ﻟﻠﺤﺮﻑ ﳛﺪﺩ ﻟﻮﻥ ﺍﳊﺮﻑ ﻭﻛﺜﺎﻓﺔ ﺍﻟﻠﻮﻥ )ﻏﺎﻣﻖ ﻭﻓﺎﺗﺢ( ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻟﺒﺘﺎﺕ ﻓﻴﻪ:
ﺍﻟﺒﺘﺎﺕ :2-0ﻟﻮﻥ ﺍﳊﺮﻑ: •
– ﺍﻟﺒﺖ :0ﺃﲪﺮ.
– ﺍﻟﺒﺖ :1ﺃﺧﻀﺮ.
– ﺍﻟﺒﺖ :2ﺃﺯﺭﻕ.
ﺍﻟﺒﺖ :3ﻛﺜﺎﻓﺔ ﻟﻮﻥ ﺍﳊﺮﻑ ) 0ﻏﺎﻣﻖ 1 ،ﻓﺎﺗﺢ(. •
ﻭﻫﻜﺬﺍ ﺗﻮﺟﺪ 4ﺑﺖ ﻟﺘﺤﺪﻳﺪ ﺍﻟﻠﻮﻥ ،ﻭﺍﳉﺪﻭﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﻫﺬﻩ ﺍﻷﻟﻮﺍﻥ:
• 0: Black.
• 1: Blue.
• 2: Green.
• 3: Cyan.
• 4: Red.
• 5: Magneta.
• 6: Brown.
٨٤
VGA ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ.٣.٤
• 15: White.
ﻛﻤﺎ ﳚﺐ، ﻓﺎﻧﻪ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ ﻭﺧﺼﺎﺋﺼﻪ ﺍﱃ ﺫﺍﻛﺮﺓ ﺍﻟﻌﺮﺽMode 7 ﺍﺫﴽ ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑ ﻋﻠﻰ ﺍﻟﻨﻤﻂ
( ﻳﻈﻬﺮ ﻭﳜﺘﻔﻲ ﻟﻠﺪﻻﻟﺔ ﻋﻠﻰ ﺍﳌﻮﻗﻊ ﺍﳊﺎﱄunderline )ﻫﻮ ﺧﻂCursor ﻣﺮﺍﻋﺎﺓ ﺑﻌﺾ ﺍﻻﻣﻮﺭ ﻣﻦ ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ
ﻭ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺼﻒ ﺍﻟﺘﺎﱄ ﰲ ﺣﺎﻟﺔ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺍﺧﺮ ﺣﺮﻑ ﰲ ﺍﻟﻌﻤﻮﺩ ﺃﻭ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳊﺮﻑ ﺍﳌﺮﺍﺩ ﻃﺒﺎﻋﺘﻪ
ﻭﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﻟﻄﺒﺎﻋﺔ ﺣﺮﻑputch32 ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻟﺪﺍﻟﺔ. 0xa ﻫﻮ ﺣﺮﻑ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺳﻄﺮ ﺟﺪﻳﺪ
.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 ?
٢٤ ;−−−−−−−−−−−−−−−−−−−−−−−−−−−
٢٥
٨٥
ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ- ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤
٨٦
VGA .٣.٤ﺃﺳﺎﺳﻴﺎﺕ ﺍﻝ
٦٤ ;−−−−−−−−−−−−−−−−−−−−−
٦٥
٦٦ ]inc byte[x pos
٦٧ cmp byte[x pos],COLUMNS
٦٨ je new row
٦٩
٧٠ jmp putch32 end
٧١
٧٢
٧٣ new row:
٧٤
٧٥ mov byte[x pos],0 ; clear the x pos.
٧٦ ]inc byte[y pos ; increment the y pos.
٧٧
٧٨ putch32 end:
٧٩
٨٠ popa ; Restore Registers.
٨١
٨٢ ret
ﻭﺗﺒﺪﺃ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﺑﻔﺤﺺ ﺍﳊﺮﻑ ﺍﳌﺮﺍﺩ ﻃﺒﺎﻋﺘﻪ )ﻣﻮﺟﻮﺩ ﰲ ﺍﳌﺴﺠﻞ (blﻣﻊ ﺣﺮﻑ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺴﻄﺮ ﺍﳉﺪﻳﺪ
0xaﻭﰲ ﺣﺎﻟﺔ ﺍﻟﺘﺴﺎﻭﻱ ﻳﺘﻢ ﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﱃ ﺁﺧﺮ ﺟﺴﻢ ﺍﻟﺪﺍﻟﺔ ﻭﺍﻟﺬﻱ ﻳﻘﻮﻡ ﺑﺘﺼﻔﲑ ﻗﻴﻤﺔ xﻭﺯﻳﺎﺩﺓ ﻗﻴﻤﺔ y
ﺩﻻﻟﺔ ﻋﻠﻰ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺴﻄﺮ ﺍﳉﺪﻳﺪ .ﺃﻣﺎ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﺍﳊﺮﻑ ﻫﻮ ﺃﻱ ﺣﺮﻑ ﺁﺧﺮ ﻓﺎﻧﻪ ﳚﺐ ﺣﺴﺎﺏ ﺍﻟﻌﻨﻮﺍﻥ
ﺍﻟﺬﻱ ﳚﺐ ﺍﺭﺳﺎﻝ ﺍﳊﺮﻑ ﺍﻟﻴﻪ ﺣﱴ ﳝﻜﻦ ﻃﺒﺎﻋﺘﻪ ،ﻭﻛﻤﺎ ﺫﻛﺮﻧﺎ ﺃﻥ ﺍﻟﻨﻤﻂ ﺍﻟﻨﺼﻲ Mode 7ﻳﺴﺘﺨﺪﻡ ﺑﺎﻳﺘﲔ
ﻟﻜﻞ ﺣﺮﻑ ﻟﺬﺍ ﺳﻴﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﺍﻟﻌﻼﻗﺔ ﺍﻟﺘﺎﻟﻴﺔ ﻟﻠﺘﺤﻮﻳﻞ ﻣﺎ ﺑﲔ ) (x,yﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ ﺍﳌﻄﻠﻮﺏ.
videomemory = 0xb0000
videomemory+ = x ∗ 2 + y ∗ 80 ∗ 2
ﻭﻛﻤﺎ ﻳﻈﻬﺮ ﰲ ﺍﻟﻜﻮﺩ ﺍﻟﺴﺎﺑﻖ ﻓﻘﺪ ﰎ ﺣﺴﺎﺏ ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﻭﺣﻔﻈﻪ ﰲ ﺍﳌﺴﺠﻞ eaxﻭﺑﻌﺪ ﺫﻟﻚ ﰎ ﻃﺒﺎﻋﺔ
ﺍﳊﺮﻑ ﺍﳌﻄﻠﻮﺏ ﺑﺎﳋﺼﺎﺋﺺ ﺍﻟﱵ ﰎ ﲢﺪﻳﺪﻫﺎ ﻣﺴﺒﻘﺎ ﻛﺜﺎﺑﺖ .ﻭﺁﺧﺮ ﺧﻄﻮﺓ ﰲ ﺍﻟﺪﺍﻟﺔ ﻫﻲ ﺯﻳﺎﺩﺓ ﻗﻴﻢ ) (x,yﻟﻠﺪﺍﻟﺔ
ﺍﱃ ﺍﳌﻜﺎﻥ ﺍﻟﺘﺎﱄ ،ﻭﻫﺬﺍ ﻳﺘﻢ ﺑﺰﻳﺎﺩﺓ xﻓﻘﻂ ﻭﰲ ﺣﺎﻟﺔ ﺗﺴﺎﻭﺕ ﺍﻟﻘﻴﻤﺔ ﻣﻊ ﻗﻴﻤﺔ ﺁﺧﺮ ﻋﻤﻮﺩ ﰲ ﺍﻟﺼﻒ ﻓﺎﻧﻪ ﻳﺘﻢ
ﺯﻳﺎﺩﺓ ﻗﻴﻤﺔ yﻭﺗﺼﻔﲑ xﺩﻻﻟﺔ ﻋﻠﻰ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﺼﻒ ﺍﻟﺘﺎﱄ.
٨٧
ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ- ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤
١
٢
٣ ; ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
٤ ; 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
ﰲ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﺣﺮﻑ ﺣﺮﻑ ﻣﻦ ﺍﻟﺴﻠﺴﺔ ﺍﻟﻨﺼﻴﺔ ﻭﻃﺒﺎﻋﺘﻪ ﺍﱃ ﺃﻥ ﻧﺼﻞ ﺍﱃ ﺎﻳﺔ ﺍﻟﺴﻠﺴﻠﺔ )ﺍﻟﻘﻴﻤﺔ
، (0x0ﻭﺑﻌﺪ ﺫﻟﻚ ﺳﻴﺘﻢ ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ ﻭﺫﻟﻚ ﻋﻦ ﻃﺮﻳﻖ ﻣﺘﺤﻜﻢ CRT Controllerﻭﻧﻈﺮﴽ ﻻﻥ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻪ
ﺑﻄﺊ ﻗﻠﻴﻼ ﻓﺎﻥ ﲢﺪﻳﺚ ﺍﳌﺆﺷﺮ ﺳﻴﻜﻮﻥ ﺑﻌﺪ ﻃﺒﺎﻋﺔ ﺍﻟﺴﻠﺴﻠﺔ ﻭﻟﻴﺲ ﺑﻌﺪ ﻃﺒﺎﻋﺔ ﻛﻞ ﺣﺮﻑ .
٨٩
.٤ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ -ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ
ﻭﻋﻨﺪ ﺍﺭﺳﺎﻝ ﺃﻱ ﻣﻦ ﺍﻟﻘﻴﻢ ﺍﻟﺴﺎﺑﻘﺔ ﺍﱃ ﻣﺴﺠﻞ Index Reigsterﻓﺎﻥ ﻫﺬﺍ ﺳﻴﺤﺪﺩ ﻧﻮﻉ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﻟﱵ ﺳﺘﺮﺳﻞ
ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ .Data Registerﻭﻣﻦ ﺍﳉﺪﻭﻝ ﺍﻟﺴﺎﺑﻖ ﺳﻨﺠﺪ ﺃﻥ ﺍﻟﻘﻴﻤﺔ 0xfﺳﺘﺤﺪﺩ ﻗﻴﻤﺔ xﻟﻠﻤﺆﺷﺮ ،
ﻭﺍﻟﻘﻴﻤﺔ 0xeﺳﺘﺤﺪﺩ ﻗﻴﻤﺔ yﻟﻠﻤﺆﺷﺮ.ﻭﺑﻌﺪ ﺫﻟﻚ ﳚﺐ ﺍﺭﺳﺎﻝ ﻗﻴﻢ x,yﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻋﻠﻰ ﺍﻟﺘﻮﺍﱄ ﻣﻊ
ﻣﻼﺣﻈﺔ ﺃﻥ ﻣﺘﺤﻜﻢ CRTﻳﺘﻌﺎﻣﻞ ﻣﻊ ﺑﺎﻳﺖ ﻭﺍﺣﺪ ﻟﻜﻞ ﺣﺮﻑ ﻭﻫﺬﺍ ﻳﻌﲏ ﺃﻧﻨﺎ ﺳﻨﺴﺘﺨﺪﻡ ﺍﻟﻘﺎﻧﻮﻥ ﺍﻟﺘﺎﱄ ﻟﻠﺘﺤﻮﻳﻞ
ﻣﻦ ﻗﻴﻢ ) (x,yﺍﱃ ﻋﻨﺎﻭﻳﻦ.
videomemory = x + y ∗ 80
ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻋﻤﻞ ﺍﻟﺪﺍﻟﺔ move cursorﻭﺍﻟﱵ ﺗﻌﻤﻞ ﻋﻠﻰ ﲢﺮﻳﻚ ﺍﳌﺆﺷﺮ.
Example ٤.١٢: Move Hardware Cursor
١
; ٢ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
٣ ; move cursor: Move the Hardware Cursor.
; ٤ input:
; ٥ bl: x pos.
; ٦ bh: y pos.
; ٧ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
٨
٩ bits 32
١٠
٩٠
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
٩٢
.٤.٤ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ
.٤.٤ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ
ﺍﱃ ﻫﻨﺎ ﺗﻨﺘﻬﻲ ﻣﻬﻤﺔ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ Second Stage Bootloaderﻭﻳﺘﺒﻘﻰ ﻓﻘﻂ ﺍﻟﺒﺤﺚ ﻋﻦ
ﺍﻟﻨﻮﺍﺓ ﻭﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ .٤ﻭﰲ ﻫﺬﺍ ﺍﳉﺰء ﺳﻴﺘﻢ ﻛﺘﺎﺑﺔ ﻧﻮﺍﺓ ﲡﺮﻳﺒﻴﺔ ﺪﻑ ﺍﻟﺘﺄﻛﺪ ﻣﻦ ﻋﻤﻠﻴﺔ ﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﱃ
ﺍﻟﻨﻮﺍﺓ ﻭﻛﺬﻟﻚ ﺪﻑ ﺇﻋﺎﺩﺓ ﻛﺘﺎﺑﺔ ﺷﻔﺮﺓ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺑﺸﻜﻞ ﺃﻓﻀﻞ.
ﻭﺳﻴﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﻟﻜﺘﺎﺑﺔ ﻫﺬﻩ ﺍﻟﻨﻮﺍﺓ ﺍﻟﺘﺠﺮﻳﺒﻴﺔ ﺣﻴﺚ ﺃﻥ ﺍﳌﻠﻒ ﺍﻟﻨﺎﺗﺞ ﺳﻴﻜﻮﻥ Pure Binaryﻭﻻ
ﳛﺘﺎﺝ ﺍﱃ ﳏﻤﻞ ﺧﺎﺹ ،ﻭﺍﺑﺘﺪﺍءﴽ ﻣﻦ ﺍﻟﻔﺼﻞ ﺍﻟﻘﺎﺩﻡ ﺳﻨﺘﺮﻙ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺟﺎﻧﺒﺎ ﻭﻧﺒﺪﺃ ﺍﻟﻌﻤﻞ ﺑﻠﻐﺔ ﺍﻟﺴﻲ ﻭﺍﻟﺴﻲ++
.
ﻭﲟﺎ ﺃﻧﻨﺎ ﻧﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ PModeﻓﻼ ﳝﻜﻨﻨﺎ ﺃﻥ ﻧﺴﺘﺨﺪﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ int 0x13ﻟﺘﺤﻤﻴﻞ
ﻗﻄﺎﻋﺎﺕ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ،ﻭﳚﺐ ﺃﻥ ﻧﻘﻮﻡ ﺑﻜﺘﺎﺑﺔ ﺩﺭﺍﻳﻔﺮ ﳌﺤﺮﻙ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺃﻭ ﻧﻘﻮﻡ ﺑﺘﺤﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺍﱃ
ﺍﻟﺬﺍﻛﺮﺓ ﻗﺒﻞ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﻫﺬﺍ ﻣﺎ ﺳﻨﻔﻌﻠﻪ ﺍﻻﻥ ،ﻭﺳﻨﺘﺮﻙ ﺟﺰﺋﻴﺔ ﺑﺮﳎﺔ ﳏﺮﻙ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻻﺣﻘﺎ.
ﻭﺣﻴﺚ ﺃﻥ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻳﺴﻤﺢ ﺑﺎﺳﺘﺨﺪﺍﻡ ﺫﺍﻛﺮﺓ ﺣﱴ 4ﺟﻴﺠﺎ ،ﻓﺎﻥ ﺍﻟﻨﻮﺍﺓ ﺳﻨﻘﻮﻡ ﺑﺘﺤﻤﻴﻠﻬﺎ ﻋﻠﻰ ﺍﻟﻌﻨﻮﺍﻥ
0x100000ﺃﻱ ﻋﻨﺪ 1ﻣﻴﺠﺎ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ .ﻟﻜﻦ ﻋﻠﻴﻨﺎ ﺍﻟﺘﺬﻛﺮ ﺑﺄﻥ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻻ ﻳﺪﻋﻢ ﺍﻟﻮﺻﻮﻝ ﺍﱃ
ﺍﻟﻌﻨﻮﺍﻥ 0x100000ﻟﺬﻟﻚ ﺳﻨﻘﻮﻡ ﺑﺘﺤﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺃﻭﻻ ﰲ ﺃﻱ ﻋﻨﻮﺍﻥ ﺧﺎﱄ ﻭﻟﻴﻜﻦ 0x3000ﻭﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ
ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺳﻨﻘﻮﻡ ﺑﻨﺴﺨﻬﺎ ﺍﱃ ﺍﻟﻌﻨﻮﺍﻥ 0x100000ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﻭﺍﻟﺘﺤﻜﻢ ﺍﻟﻴﻬﺎ.
ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻧﻮﺍﺓ ﺗﺮﺣﻴﺒﻴﺔ.
٩٣
ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ- ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤
٩٤
.٤.٤ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ
٥٣ hlt
ﻭﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺳﺘﻜﻮﻥ ﻫﻲ ﺍﳌﺴﺆﻭﻟﺔ ﻋﻦ ﺍﻟﺒﺤﺚ ﻋﻦ ﺍﻟﻨﻮﺍﺓ ﻭﲢﻤﻴﻠﻬﺎ ﻭﻧﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ،
ﻭﺳﻴﺘﻢ ﲢﻤﻴﻠﻬﺎ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻗﺒﻞ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻭﺫﻟﻚ ﺣﱴ ﻧﺘﻜﻤﻦ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺔ ﺍﻟﺒﺎﻳﻮﺱ
int 0x13ﻭﻋﻨﺪ ﺍﻻﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﺳﻴﺘﻢ ﻧﺴﺦ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﻋﻨﻮﺍﻥ 1ﻣﻴﺠﺎ ﻭﻧﻘﻞ ﺍﻟﺘﺤﻜﻢ ﺍﱃ ﺍﻟﻨﻮﺍﺓ.
ﻭﻟﺘﺤﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﳚﺐ ﺃﻭﻻ ﲢﻤﻴﻞ Root Directoryﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﻟﺒﺤﺚ ﻋﻦ ﻣﻠﻒ ﺍﻟﻨﻮﺍﺓ ﻭﰲ ﺣﺎﻟﺔ
ﻛﺎﻥ ﺍﳌﻠﻒ ﻣﻮﺟﻮﺩﺍ ﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﻋﻨﻮﺍﻥ ﺃﻭﻝ ﻛﻠﺴﺘﺮ ﻟﻪ ،ﻫﺬﺍ ﺍﻟﻌﻨﻮﺍﻥ ﺳﻴﻌﻤﻞ ﻙ indexﰲ ﺟﺪﻭﻝ ) FATﻭﺍﻟﺬﻱ
ﳚﺐ ﲢﻤﻴﻠﻪ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻳﻀﺎ( ﻭﺳﻴﺘﻢ ﻗﺮﺍءﺓ ﺍﻟﻘﻴﻤﺔ ﺍﳌﻘﺎﺑﻠﺔ ﳍﺬﺍ ﺍﻝ indexﻭﺍﻟﱵ ﺳﺘﺨﱪﻧﺎ ﻫﻞ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﻫﺬﺍ
ﺍﻟﻜﻠﺴﺘﺮ ﻫﻮ ﺁﺧﺮ ﻛﻠﺴﺘﺮ ﻟﻠﻤﻠﻒ ﺃﻡ ﻻ .٥
ﻭﺍﻟﺸﻔﺮﺓ ﺍﻟﺘﺎﻟﻴﺔ ﺗﻮﺿﺢ ﻣﻠﻒ ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ ﻣﻦ ﺍﳌﺤﻤﻞ ، stage2.asmﻭﰎ ﺗﻘﺴﻴﻢ ﺍﻟﻜﻮﺩ ﺑﺸﻜﻞ ﺃﻛﺜﺮ ﺗﻨﻈﻴﻤﺎ
ﺣﻴﺚ ﰎ ﻧﻘﻞ ﺃﻱ ﺩﺍﻟﺔ ﺗﺘﻌﻠﻖ ﺑﺎﻟﻘﺮﺹ ﺍﳌﺮﻥ ﺍﱃ ﺍﳌﻠﻒ ) floppy.incﻣﻠﻒ .incﻫﻮ ﻣﻠﻒ ﻟﻠﺘﻀﻤﲔ ﰲ ﻣﻠﻒ ﺁﺧﺮ(
،ﻭﺍﻟﺪﻭﺍﻝ ﺍﳌﺘﻌﻠﻘﺔ ﺑﻨﻈﺎﻡ ﺍﳌﻠﻔﺎﺕ ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﻠﻒ fat12.incﻭﺩﻭﺍﻝ ﺍﻻﺧﺮﺍﺝ ﻣﻮﺟﻮﺩﺓ ﰲ stdio.incﻭﺩﻭﺍﻝ
ﺗﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ A20ﻣﻮﺟﻮﺩﺓ ﻋﻠﻰ ﺍﳌﻠﻒ a20.incﻭﺩﺍﻟﺔ ﺗﻌﻴﲔ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ﻭﻛﺬﻟﻚ ﺗﻔﺎﺻﻴﻞ ﺍﳉﺪﻭﻝ
ﻣﻮﺟﻮﺩﺓ ﰲ ﺍﳌﻠﻒ ، gdt.incﺍﺧﲑﺍ ﰎ ﺍﻧﺸﺎء ﻣﻠﻒ common.incﳊﻔﻆ ﺑﻌﺾ ﺍﻟﺜﻮﺍﺑﺖ ﺍﳌﺴﺘﺨﺪﻣﺔ ﺩﺍﺋﻤﺎ .٦
Example ٤.١٥: Loading and Execu ng Kernel: Full Example
١
٢
٣ bits 16 ; 16−bit real mode.
٤ org 0x500
٥
٦ start: jmp stage2
٧
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ٨
٩ ; 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
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ; ١٩
٢٠
٩٥
ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ- ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤
٩٦
ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ.٤.٤
٦١ ;−−−−−−−−−−−−−−−−−
٦٢ 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.
٩٧
ﺍﳌﺮﺣﻠﺔ ﺍﻟﺜﺎﻧﻴﺔ- ﺑﺮﳎﺔ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ.٤
٩٨
ﲢﻤﻴﻞ ﺍﻟﻨﻮﺍﺓ.٤.٤
١٤٣
١٤٤
١٤٥
١٤٦ ;−−−−−−−−−−−−−−−−−−−−−−−−
١٤٧ ; 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ﺣﻴﺚ ﺗﺪﻳﺮ ﻫﺬﻩ ﺍﻟﻨﻮﺍﺓ ﻋﺘﺎﺩ ﻭﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ
ﻭﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ ﻋﺎﻟﻴﺔ ﺗﺴﻤﺢ ﻟﱪﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﻣﻦ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻫﺬﻩ ﺍﳌﻮﺍﺭﺩ ﺑﺸﻜﻞ ﺟﻴﺪ.ﻭﺗﻌﺘﱪ ﺑﺮﳎﺔ
ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﻦ ﺃﺻﻌﺐ ﺍﳌﻬﻤﺎﺕ ﺍﻟﱪﳎﻴﺔ ﻋﻠﻰ ﺍﻻﻃﻼﻕ ،ﺣﻴﺚ ﺗﺆﺛﺮ ﻫﻴﻜﻠﺘﻪ ﻭﺗﺼﻤﻴﻤﻪ ﻋﻠﻰ ﻛﺎﻓﺔ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ
ﻭﻫﺬﺍ ﻣﺎ ﳝﻴﺰ ﺑﻌﺾ ﺍﻻﻧﻈﻤﺔ ﻭﳚﻌﻠﻬﺎ ﻗﺎﺑﻠﺔ ﻟﻠﻌﻤﻞ ﰲ ﺃﺟﻬﺰﺓ ﻣﻌﻴﻨﺔ .ﻭﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﺳﻨﻠﻘﻲ ﻧﻈﺮﺓ ﻋﻠﻰ ﺍﻟﻨﻮﺍﺓ
ﻭﺑﺮﳎﺘﻬﺎ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺴﻲ ﻭ ﺍﻟﺴﻲ ++ﻭﻛﺬﻟﻚ ﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﻃﺮﻕ ﺗﺼﻤﻴﻢ ﺍﻟﻨﻮﺍﺓ ﻭﻣﻴﺰﺍﺕ ﻭﻋﻴﻮﺏ
ﻛﻞٌ ﻋﻠﻰ ﺣﺪﺓ.
ﺗﻌﺮﻑ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺑﺄﺎ ﺍﳉﺰء ﺍﻷﺳﺎﺳﻲ ﰲ ﺍﻟﻨﻈﺎﻡ ﻭﺍﻟﺬﻱ ﺗﻌﺘﻤﺪ ﻋﻠﻴﻪ ﺑﻘﻴﺔ ﻣﻜﻮﻧﺎﺕ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ.
ﻭﻳﻜﻤﻦ ﺩﻭﺭ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﰲ ﺍﻟﺘﻌﺎﻣﻞ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ﻭﺇﺩﺍﺭﺗﻪ ﲝﻴﺚ ﺗﻜﻮﻥ ﻃﺒﻘﺔ ﺑﺮﳎﻴﺔ ﺗﺒﻌﺪ ﺑﺮﺍﻣﺞ
ﺍﳌﺴﺘﺨﺪﻡ ﻣﻦ ﺗﻔﺎﺻﻴﻞ ﻭﺗﻌﻘﻴﺪﺍﺕ ﺍﻟﻌﺘﺎﺩ ،ﻭﻻ ﺗﻘﺘﺼﺮ ﻋﻠﻰ ﺫﻟﻚ ﺑﻞ ﺗﻮﻓﺮ ﻭﺍﺟﻬﺔ ﺑﺮﳎﻴﺔ ﻣﺒﺴﻄﺔ )ﳝﻜﻦ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ
ﻣﻦ ﻟﻐﺔ ﺍﻟﱪﳎﺔ ﺍﳌﺪﻋﻮﻣﺔ ﻋﻠﻰ ﺍﻟﻨﻈﺎﻡ( ﲝﻴﺚ ﲤﻜﻦ ﺑﺮﺍﻣﺞ ﺍﳌﺴﺘﺨﺪﻡ ﺍﻻﺳﺘﻔﺎﺩﺓ ﻣﻦ ﻣﻮﺍﺭﺩ ﺍﳊﺎﺳﺐ .ﻭﰲ ﺍﳊﻘﻴﻘﺔ
ﻻ ﻳﻮﺟﺪ ﻗﺎﻧﻮﻥ ﻳﻨﺺ ﻋﻠﻰ ﺇﻟﺰﺍﻣﻴﺔ ﻭﺟﻮﺩ ﻧﻮﺍﺓ ﻟﻠﻨﻈﺎﻡ ،ﺣﻴﺚ ﳝﻜﻦ ﻟﱪﻧﺎﻣﺞ ﻣﺎ )ﻳﻌﻤﻞ ﰲ ﺍﳊﻠﻘﺔ ﺻﻔﺮ( ﺍﻟﺘﻌﺎﻣﻞ
ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺍﻟﻌﺘﺎﺩ ﻭﻣﻊ ﻛﻞ ﺍﳉﺪﺍﻭﻝ ﰲ ﺍﳊﺎﺳﺐ ﻭﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﺑﺎﻳﺖ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻦ ﻫﺬﺍ ﻣﺎ ﺳﻴﺠﻌﻞ ﻋﻤﻠﻴﺔ
ﻛﺘﺎﺑﺔ ﺍﻟﱪﺍﻣﺞ ﻋﻤﻠﻴﺔ ﺷﺒﻪ ﻣﺴﺘﺤﻴﻠﺔ ! ﺣﻴﺚ ﳚﺐ ﻋﻠﻰ ﻛﻞ ﻣﱪﻣﺞ ﻳﺮﻳﺪ ﻛﺘﺎﺑﺔ ﺗﻄﺒﻴﻖ ﺑﺴﻴﻂ ﺃﻥ ﳚﻴﺪ ﺑﺮﳎﺔ
ﺍﻟﻌﺘﺎﺩ ﻭﺃﺳﺎﺳﻴﺎﺕ ﺍﻻﻗﻼﻉ ﺣﱴ ﻳﻌﻤﻞ ﺑﺮﻧﺎﳎﻪ ،ﺍﺿﺎﻓﺔ ﻋﻠﻰ ﺫﻟﻚ ﻻ ﳝﻜﻦ ﺗﺸﻐﻴﻞ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﰲ ﻧﻔﺲ
ﺍﻟﻮﻗﺖ ﻧﻈﺮﺍ ﻟﻌﺪﻡ ﻭﺟﻮﺩ ﺑﻨﻴﺔ ﲢﺘﻴﺔ ﺗﻮﻓﺮ ﻣﺜﻞ ﻫﺬﻩ ﺍﳋﺼﺎﺋﺺ ،ﻭﻻﻧﻨﺴﻰ ﺍﻋﺪﺍﺩ ﻭﻴﺌﺔ ﺟﺪﺍﻭﻝ ﺍﻟﻨﻈﺎﻡ ﻭﻛﺘﺎﺑﺔ
ﻭﻇﺎﺋﻒ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﺍﻷﺧﻄﺎء ،ﻭﺩﻭﺍﻝ ﺣﺠﺰ ﻭﲢﺮﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻏﲑﻫﺎ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﺍﻟﻀﺮﻭﺭﻳﺔ ﻷﻱ
ﺑﺮﻧﺎﻣﺞ.ﻛﻞ ﻫﺬﺍ ﳚﻌﻞ ﻋﻤﻠﻴﺔ ﺗﻄﻮﻳﺮ ﺑﺮﻧﺎﻣﺞ ﻟﻠﻌﻤﻞ ﻋﻠﻰ ﺣﺎﺳﺐ ﻣﺎ ﺑﺪﻭﻥ ﻧﻮﺍﺓ ﻟﻪ ﺃﻣﺮﴽ ﻏﲑ ﻣﺮﻏﻮﺑﺎ ،ﺧﺎﺻﺔ ﺇﺫﺍ
ﺫﻛﺮﻧﺎ ﺃﻥ ﺍﻟﱪﻧﺎﻣﺞ ﳚﺐ ﲢﺪﻳﺜﻪ ﳎﺪﺩﴽ ﻋﻨﺪ ﻧﻘﻠﻪ ﺍﱃ ﻣﻨﺼﺔ ﺃﺧﺮﻯ ﺫﺍﺕ ﻋﺘﺎﺩ ﳐﺘﻠﻒ .ﺍﺫﴽ ﳝﻜﻦ ﺃﻥ ﻧﻘﻮﻝ ﺃﻥ ﻧﻮﺍﺓ
ﺍﻟﻨﻈﺎﻡ ﻫﻲ ﺍﳉﺰء ﺍﻻﻫﻢ ﰲ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻛﻜﻞ ،ﺣﻴﺚ ﺗﺪﻳﺮ ﺍﻟﻨﻮﺍﺓ ﻋﺘﺎﺩ ﺍﳊﺎﺳﺐ ﻣﻦ ﺍﳌﻌﺎﰿ ﻭﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ
ﻭﺍﻷﻗﺮﺍﺹ ﺍﻟﺼﻠﺒﺔ ﻭﺍﳌﺮﻧﺔ ﻭﻏﲑﻫﺎ ﻣﻦ ﺍﻷﺟﻬﺰﺓ ﺍﳌﺤﻴﻄﺔ ﺑﺎﳊﺎﺳﺐ.
ﻭﺣﱴ ﻧﻔﻬﻢ ﻋﻼﻗﺔ ﺍﻟﻨﻮﺍﺓ ﻣﻊ ﺑﻘﻴﺔ ﺃﺟﺰﺍء ﺍﻟﻨﻈﺎﻡ ،ﻓﺎﻧﻪ ﳝﻜﻦ ﺗﻘﺴﻴﻢ ﺍﳊﺎﺳﺐ ﺍﱃ ﻋﺪﺓ ﻣﺴﺘﻮﻳﺎﺕ ﻣﻦ ﺍﻟﺘﺠﺮﻳﺪ
ﲝﻴﺚ ﻛﻞ ﻣﺴﺘﻮﻯ ﳜﺪﻡ ﺍﳌﺴﺘﻮﻯ ﺍﻟﺬﻱ ﻳﻠﻴﻪ .
١٠٣
.٥ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ
.١.١.٥ﻣﺴﺘﻮﻳﺎﺕ ﺍﻟﺘﺠﺮﻳﺪ
ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﱪﳎﻴﺎﺕ ﻳﺘﻢ ﺑﻨﺎﺋﻬﺎ ﻋﻠﻰ ﺷﻜﻞ ﻣﺴﺘﻮﻳﺎﺕ ،ﻭﻇﻴﻔﺔ ﻛﻞ ﻣﺴﺘﻮﻯ ﻫﻮ ﺗﻮﻓﲑ ﻭﺍﺟﻬﺔ ﻟﻠﻤﺴﺘﻮﻯ ﺍﻟﺬﻱ
ﻳﻠﻴﻪ ﲝﻴﺚ ﲣﻔﻲ ﻫﺬﻩ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﻟﺘﻌﻘﻴﺪﺍﺕ ﻭﺍﻟﺘﻔﺎﺻﻴﻞ ﻭﻛﺬﻟﻚ ﺭﲟﺎ ﳛﻤﻲ ﻣﺴﺘﻮﻯ ﻣﺎ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ
ﻣﻦ ﺍﳌﺴﺘﻮﻯ ﺍﻟﺬﻱ ﻳﻠﻴﻪ ،ﻭﻏﺎﻟﺒﺎ ﻣﺎ ﻳﺘﺒﻊ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﳍﺬﺍ ﺍﻟﻨﻮﻉ ﻣﻦ ﺍﻟﱪﳎﻴﺎﺕ ﺣﻴﺚ ﳝﻜﻦ ﺗﻘﺴﻴﻢ ﺍﻟﻨﻈﺎﻡ ﻛﻜﻞ
ﺍﱃ ﻋﺪﺓ ﻣﺴﺘﻮﻳﺎﺕ.
١٠٤
.٢.٥ﻭﻇﺎﺋﻒ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ
.١.٢.٥ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ
ﺃﻫﻢ ﻭﻇﻴﻔﺔ ﻟﻨﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻫﻲ ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﺃﻥ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﳚﺐ ﺍﻥ ﻳﺘﻢ ﲢﻤﻠﻴﻪ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻗﺒﻞ
ﺃﻥ ﻳﺘﻢ ﺗﻨﻔﻴﺬﻩ ،ﻟﺬﻟﻚ ﻣﻦ ﻣﻬﺎﻡ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻫﻲ ﻣﻌﺮﻓﺔ ﺍﻷﻣﺎﻛﻦ ﺍﻟﺸﺎﻏﺮﺓ ،ﻭﺍﻟﺘﻌﺎﻣﻞ ﻣﻊ ﻣﺸﺎﻛﻞ ﺍﻟﺘﺠﺰﺋﺔ
) (Fragmenta onﺣﻴﺚ ﻣﻦ ﺍﳌﻤﻜﻦ ﺃﻥ ﲢﻮﻱ ﺍﻟﺬﺍﻛﺮﺓ ﻋﻠﻰ ﺍﻟﻜﺜﲑ ﻣﻦ ﺍﳌﺴﺎﺣﺎﺕ ﺍﻟﺼﻐﲑﺓ ﻭﺍﻟﱵ ﻻ ﺗﻜﻔﻲ
ﻟﺘﺤﻤﻴﻞ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﺃﻭ ﺣﱴ ﺣﺠﺰ ﻣﺴﺎﺣﺔ ﻟﱪﻧﺎﻣﺞ ﻣﺎ .ﺃﺣﺪ ﺍﳌﺸﺎﻛﻞ ﺍﻟﱵ ﻋﻠﻰ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ ﻫﻲ
ﻣﻌﺮﻓﺔ ﻣﻜﺎﻥ ﲢﻤﻴﻞ ﺍﻟﱪﻧﺎﻣﺞ ،ﺣﻴﺚ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﺍﻟﱪﻧﺎﻣﺞ ﻣﺴﺘﻘﻼ ﻋﻦ ﺍﻟﻌﻨﻮﺍﻳﻦ )(Posi on Independent
ﻟﻜﻲ ﻳﺘﻢ ﲢﻤﻠﻴﻪ ﻭﺇﻻ ﻓﻠﻦ ﻧﻌﺮﻑ ﻣﺎ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻟﺒﺪﺍﻳﺔ ) (Base Addressﳍﺬﺍ ﺍﻟﱪﻧﺎﻣﺞ .ﻓﻠﻮ ﻓﺮﺿﻨﺎ ﺍﻥ ﻟﺪﻳﻨﺎ
ﺑﺮﻧﺎﻣﺞ binaryﻭﻧﺮﻳﺪ ﲢﻤﻴﻠﻪ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﻓﻬﻨﺎ ﻟﻦ ﻧﺘﻤﻜﻦ ﻣﻦ ﻣﻌﺮﻓﺔ ﻣﺎ ﻫﻮ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺬﻱ ﳚﺐ ﺃﻥ ﻳﻜﻮﻥ ﻋﻠﻴﻪ
ﺍﻟﱪﻧﺎﻣﺞ ،ﻟﺬﻟﻚ ﻋﺎﺩﺓ ﻓﺎﻥ ﺍﻟﻨﺎﺗﺞ ﻣﻦ ﻋﻤﻠﻴﺔ ﺗﺮﲨﺔ ﻭﺭﺑﻂ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﻫﻮ ﺍﺎ ﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ،0x0ﻭﻫﻜﺬﺍ
ﺳﻨﺘﻤﻜﻦ ﺩﻭﻣﺎ ﻣﻦ ﲢﻤﻴﻞ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﰲ ﺑﺪﺍﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ .ﺬﺍ ﺍﻟﺸﻜﻞ ﻟﻦ ﻧﺘﻤﻜﻦ ﻣﻦ ﺗﻨﻔﻴﺬ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ
ﻭﺍﺣﺪ ،ﺣﻴﺚ ﺳﻴﻜﻮﻥ ﻫﻨﺎﻙ ﺑﺮﻧﺎﳎﺎ ﻭﺍﺣﺪﺍ ﻓﻘﻂ ﻳﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ ، 0x0ﻭﺍﳊﻞ ﳍﺬﻩ ﺍﳌﺸﺎﻛﻞ ﻫﻮ ﺑﺎﺳﺘﺨﺪﺍﻡ
ﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﻮﻧﺔ ﺍﻟﺘﺨﻴﻠﻴﺔ ) (Virtual Address Spaceﺣﻴﺚ ﻳﺘﻢ ﲣﺼﻴﺺ ﻣﺴﺎﺣﺔ ﲣﻴﻠﻴﺔ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻞ ﺑﺮﻧﺎﻣﺞ
ﲝﻴﺚ ﺗﺒﺪﺃ ﺍﻟﻌﻨﻮﻧﺔ ﲣﻴﻠﻴﺎ ﻣﻦ 0x0ﻭﺬﺍ ﰎ ﺣﻞ ﻣﺸﻜﻠﺔ ﲢﻤﻴﻞ ﺃﻛﺜﺮ ﻣﻦ ﺑﺮﻧﺎﻣﺞ ﻭﺣﻞ ﻣﺸﻜﻠﺔ .reloca on
ﻭﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﻮﺍﻥ ﺍﻟﺘﺨﻴﻠﻴﺔ ) (VASﻫﻲ ﻣﺴﺎﺣﺔ ﻣﻦ ﺍﻟﻌﻨﺎﻭﻳﻦ ﻟﻜﻞ ﺑﺮﻧﺎﻣﺞ ﲝﻴﺚ ﺗﻴﺪﺃ ﻣﻦ ﺍﻝ 0x0ﻭﻣﻔﻬﻮﻡ ﻫﺬﻩ
ﺍﳌﺴﺎﺣﺔ ﻫﻮ ﺃﻥ ﻛﻞ ﺑﺮﻧﺎﻣﺞ ﺳﻴﺘﻌﺎﻣﻞ ﻣﻊ ﻣﺴﺎﺣﺔ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﳋﺎﺻﺔ ﺑﻪ ﻭﻫﺬﺍ ﻣﺎ ﻳﺆﺩﻱ ﺍﱃ ﲪﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ،ﺣﻴﺚ
ﻟﻦ ﻳﺴﺘﻄﻴﻊ ﺃﻱ ﺑﺮﻧﺎﻣﺞ ﺍﻟﻮﺻﻮﻝ ﺍﱃ ﺃﻱ ﻋﻨﻮﺍﻥ ﺁﺧﺮ ﲞﻼﻑ ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﳌﻮﺟﻮﺩﺓ ﰲ .VASﻭﻧﻈﺮﴽ ﻟﻌﺪﻡ ﺍﺭﺗﺒﺎﻁ
ﺍﻝ VASﻣﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﻓﺎﻧﻪ ﳝﻜﻦ ﺍﻥ ﻳﺸﲑ ﻋﻨﻮﺍﻥ ﲣﻴﻠﻲ ﺍﱃ ﺫﺍﻛﺮﺓ ﺍﺧﺮﻯ ﲞﻼﻑ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ )ﻣﺜﻼ
ﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ( .ﻭﻫﺬﺍ ﳛﻞ ﻣﺸﻜﻠﺔ ﺍﻧﺘﻬﺎء ﺍﳌﺴﺎﺣﺎﺕ ﺍﳋﺎﻟﻴﺔ ﰲ ﺍﻟﺬﺍﻛﺮﺓ .ﻭﳚﺪﺭ ﺑﻨﺎ ﺫﻛﺮ ﺃﻥ ﺍﻟﺘﺤﻮﻳﻞ ﺑﲔ
ﺍﻟﻌﻨﺎﻭﻳﻦ ﺍﻟﺘﺨﻴﻠﻴﻪ ﺍﱃ ﺍﳊﻘﻴﻘﻴﺔ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺍﻟﻌﺘﺎﺩ ﺑﻮﺍﺳﻄﺔ ﻭﺣﺪﺓ ﺍﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺑﺪﺍﺧﻞ ﺍﳌﻌﺎﰿ )Memory
١٠٥
.٥ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ
.(Management Unitﻭﻛﺬﻟﻚ ﻣﻬﻤﺔ ﲪﺎﻳﺔ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺍﻟﺘﺤﻜﻢ ﰲ ﺍﻟﺬﺍﻛﺮﺓ Cacheﻭﻏﲑﻫﺎ ﻣﻦ ﺍﳋﺼﺎﺋﺺ ﻭﺍﻟﱵ
ﺳﻴﺘﻢ ﺍﻹﻃﻼﻉ ﻋﻠﻴﻬﺎ ﰲ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺑﻊ -ﲟﺸﻴﺌﺔ ﺍﷲ.-
٢ﺃﻏﻠﺐ ﺃﻧﻮﻳﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺍﳊﺎﻟﻴﺔ ﺗﺴﺘﺨﺪﻡ ﻃﺒﻘﺔ ،HALﻫﻞ ﺗﺴﺎﺋﻠﺖ ﻳﻮﻣﺎ ﻛﻴﻒ ﻳﻌﻤﻞ ﻧﻈﺎﻡ ﺟﻨﻮ/ﻟﻴﻨﻮﻛﺲ ﻋﻠﻰ ﺃﺟﻬﺰﺓ ﺳﻄﺢ
ﺍﳌﻜﺘﺐ ﻭﺍﻷﺟﻬﺰﺓ ﺍﳌﻀﻤﻨﺔ!
٣ﻛﻠﻤﺔ Monoﺗﻌﲏ ﻭﺍﺣﺪ ،ﺃﻣﺎ ﻛﻠﻤﺔ Lithicﻓﺘﻌﲏ ﺣﺠﺮﻱ ،ﻭﺍﳌﻘﺼﻮﺩ ﺑﺄﻥ ﺍﻟﻨﻮﺍﺓ ﺗﻜﻮﻥ ﻋﻠﻰ ﺷﻜﻞ ﻛﺘﻠﺔ ﺣﺠﺮﻳﺔ ﻟﻴﺴﺖ ﻣﺮﻧﺔ
ﻭﺗﻄﻮﻳﺮﻫﺎ ﻭﺻﻴﺎﻧﺘﻬﺎ ﻣﻌﻘﺪ.
١٠٦
.٤.٥ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ
١٠٧
.٥ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ
١٠٨
ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ.٤.٥
١٠٩
ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ.٥
( ﻭﺍﻟﱵ ﺳﻴﺒﺪﺃ ﺗﻨﻔﻴﺬ ﺍﻟﻨﻮﺍﺓ ﻣﻨﻬﺎ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
١١٠
.٤.٥ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ
٧
٨ add ebx,16 ; ebx point to AddressOfEntryPoint
٩
١٠ ]mov ebp,dword[ebx ; epb = AddressOfEntryPoint
١١
١٢ add ebx,12 ; ebx point to ImageBase
١٣
١٤ ]add ebp,dword[ebx ; epb = kernel entry
١٥
١٦ cli
١٧
١٨ call ebp
١١١
.٥ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ
ﺍﻳﻀﺎ ﳚﺐ ﺗﻌﺮﻳﻒ ﺩﺍﻟﺔ ﻟﻠﺘﻌﺎﻣﻞ ﻣﻊ ﺍﻟﺪﻭﺍﻝ ﺍﻟﻈﺎﻫﺮﻳﺔ ﺍﻟﻨﻘﻴﺔ ) ،٥ (Pure virtual func onﺣﻴﺚ ﺳﻴﻘﻮﻡ ﺍﳌﺘﺮﺟﻢ
ﺑﺎﺳﺘﺪﻋﺎء ﺍﻟﺪﺍﻟﺔ )( ٦ purecallﺃﻳﻨﻤﺎ ﻭﺟﺪ ﻋﻤﻠﻴﺔ ﺍﺳﺘﺪﻋﺎء ﻟﺪﺍﻟﺔ ، Pure virtualﻟﺬﻟﻚ ﺃﻥ ﺃﺭﺩﻧﺎ ﺩﻋﻢ
ﺍﻟﺪﻭﺍﻝ Pure virtualﳚﺐ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ ، purecallﻭﺣﺎﻟﻴﺎ ﺳﻴﻜﻮﻥ ﺍﻟﺘﻌﺮﻳﻒ ﻛﺎﻻﰐ.
ﻟﺪﻋﻢ ﺍﻟﻔﺎﺻﻠﺔ ﺍﻟﻌﺎﺋﻤﺔ ) (Floa ng Pointﰲ ﺳﻲ ++ﻓﺎﻧﻪ ﳚﺐ ﺗﻌﻴﲔ ﺍﻟﻘﻴﻤﺔ 1ﻟﻠﻤﺘﻐﲑ ، fltusedﻭﻛﺬﻟﻚ
ﳚﺐ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ )( ftol2 sseﻭﺍﻟﱵ ﲢﻮﻝ ﻣﻦ ﺍﻟﻨﻮﻉ floatﺍﱃ ﺍﻟﻨﻮﻉ longﻛﺎﻟﺘﺎﱄ.
٥ﻋﻨﺪ ﺗﻌﺮﻳﻒ ﺩﺍﻟﺔ ﺑﺄﺎ Pure virtualﺩﺍﺧﻞ ﺃﻱ ﻓﺌﺔ ﻓﺈﻥ ﻫﺬﺍ ﻳﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﻟﻔﺌﺔ ﳎﺮﺩﺓ ) (Abstractﻭﳚﺐ ﺇﻋﺎﺩﺓ ﺗﻌﺮﻳﻒ ﺍﻟﺪﺍﻟﺔ
) (Overrideﰲ ﺍﻟﻔﺌﺎﺕ ﺍﳌﺸﺘﻘﺔ ﻣﻦ ﺍﻟﻔﺌﺔ ﺍﻟﱵ ﲢﻮﻱ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ،ﻭﺍﻻ ﺳﺘﻜﻮﻥ ﺍﻟﻔﺌﺔ ﺍﳌﺸﺘﻘﺔ .
٦ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﻳﻘﻮﻡ ﻣﺘﺮﺟﻢ ﺍﻟﻔﻴﺠﻮﺍﻝ ﺳﻲ ++ﺑﺎﺳﺘﺪﻋﺎﺋﻬﺎ.ﻭﻗﺪ ﲣﺘﻠﻒ ﻣﻦ ﻣﺘﺮﺟﻢ ﻵﺧﺮ.
١١٢
.٤.٥ﺑﺮﳎﺔ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ
.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)) ();
٤٤ }
٤٥ }
١١٦
.٥.٥ﻧﻈﺮﺓ ﻋﻠﻰ ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ
٢٤
٢٥ // Execute global constructors
٢٦ ;)(init ctor
٢٧
٢٨ // Call kernel entry point
٢٩ ;)(main
٣٠
٣١ // Cleanup all dynamic dtors
٣٢ ;)(exit
٣٣
٣٤ #ifdef i386
٣٥ asm cli
٣٦ #endif
٣٧
٣٨ ;);;(for
٣٩ }
١١٧
ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ.٥
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) ﺑﺪﻭﻥ ﺇﺷﺎﺭﺓ32-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
١١٩
ﻣﻘﺪﻣﺔ ﺣﻮﻝ ﻧﻮﺍﺓ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ.٥
ﻭﻫﻲ ﺍﻟﺘﺴﻤﻴﺔ ﺍﻟﱵ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ﻷﺎ ﺗﻮﻗﻒ ﻋﻤﻞ ﺍﻟﻨﻈﺎﻡ ﰲ ﺣﺎﻟﺔ ﱂ ﺗﺘﻮﻓﺮ ﺩﺍﻟﺔ ﳌﻌﺎﳉﺘﻬﺎ.
١٢٣
Interrupts ﺍﳌﻘﺎﻃﻌﺎﺕ.٦
ﺑﺎﻳﺖ ﻭﻫﻲ ﻧﺎﲡﺔ ﻣﻦ1024 ﻣﻘﺎﻃﻌﺔ )ﻭﲝﺴﺒﺔ ﺑﺴﻴﻄﺔ ﻳﻜﻮﻥ ﺣﺠﻢ ﺍﳉﺪﻭﻝ ﻫﻮ256 ﻭﻳﺘﻜﻮﻥ ﺍﳉﺪﻭﻝ ﻣﻦ
ﺑﻌﺾ ﻣﻨﻬﺎ ﳏﺠﻮﺯ ﻭﺍﻟﺒﻌﺾ ﺍﻻﺧﺮ ﻳﺴﺘﺨﺪﻣﻪ ﺍﳌﻌﺎﰿ ﻭﺍﻟﺒﻘﻴﺔ،( ﺿﺮﺏ ﻋﺪﺩ ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺣﺠﻢ ﻛﻞ ﺳﺠﻞ
ﻭﺑﺴﺒﺐ ﺃﻥ ﺍﳉﺪﻭﻝ ﻳﺘﻜﻮﻥ ﻓﻘﻂ ﻣﻦ ﻋﻨﺎﻭﻳﻦ ﻟﺪﻭﺍﻝ.ﻣﺘﺮﻭﻛﺔ ﳌﱪﻣﺞ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﻟﺪﻋﻢ ﺍﳌﺰﻳﺪ ﻣﻦ ﺍﳌﻘﻄﺎﻋﺎﺕ
ﺎ ﺩﺍﺧﻞ ﻫﺬﺍﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻓﺎﻥ ﻫﺬﺍ ﳝﻜﻨﻨﺎ ﻣﻦ ﻭﺿﻊ ﺍﻟﺪﺍﻟﺔ ﰲ ﺃﻱ ﻣﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ ﻭﻣﻦ ﰒ ﻭﺿﻊ ﻋﻨﻮﺍ
. ﻭﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﳌﻮﺟﻮﺩﺓ ﻓﻴﻪIVT ﻳﻮﺿﺢ١.٦ ﻭﺍﳉﺪﻭﻝ،(ﺍﻟﺴﺠﻞ )ﻳﺘﻢ ﻫﺬﺍ ﻋﻦ ﻃﺮﻳﻖ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ
١٢٤
So ware Interrupts ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ.١.٦
• Bits 16-31:
– Interrupt / Trap Gate: Segment Selector (Useually 0x10)
– Task Gate: TSS Selector
• 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
١٢٥
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﻭﺍﳌﺜﺎﻝ ﺍﻟﺘﺎﱄ ﻳﻮﺿﺢ ﺍﻧﺸﺎء ﻭﺍﺻﻔﺔ ﻭﺍﺣﺪﺓ ﺑﻠﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﺣﱴ ﻳﺴﻬﻞ ﺗﺘﺒﻊ ﺍﻟﻘﻴﻢ ،ﻭﺳﻴﺘﻢ ﻛﺘﺎﺑﺔ ﻣﺜﺎﻝ ﻛﺎﻣﻞ
ﻻﺣﻘﺎ ﺑﻠﻐﺔ ﺍﻟﺴﻲ.
Example ٦.١: Example of interrupt descriptor
١
٢ idt descriptor:
٣ baseLow dw 0x0
٤ selector dw 0x8
٥ reserved db 0x0
٦ flags db 0x8e ; 010001110
٧ baseHi dw 0x0
ﺍﳌﺘﻐﲑ ﺍﻷﻭﻝ baseLowﻫﻮ ﺃﻭﻝ 16ﺑﺖ ﻣﻦ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ IRﻭﻳﻜﻤﻞ ﺍﳉﺰء ﺍﻻﺧﺮ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ
ﺍﳌﺘﻐﲑ baseHiﻭﰲ ﻫﺬﺍ ﺍﳌﺜﺎﻝ ﺍﻟﻌﻨﻮﺍﻥ ﻫﻮ 0x0ﲟﻌﲎ ﺃﻥ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﺳﺘﻜﻮﻥ ﰲ ﺍﻟﻌﻨﻮﺍﻥ .0x0ﻭﲟﺎ ﺃﻥ
ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ )ﲣﺪﱘ( ﺍﳌﻘﺎﻃﻌﺔ ﲢﻮﻱ ﺷﻔﺮﺓ ﺑﺮﳎﻴﺔ ﻟﻠﺘﻨﻔﻴﺬ ﻭﻟﻴﺴﺖ ﺑﻴﺎﻧﺎﺕ ) (Dataﻓﺎﻥ ﻗﻴﻤﺔ ﺍﳌﺘﻐﲑ selector
ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ 0x8ﻟﻺﺷﺎﺭﺓ ﺍﱃ ﻧﺎﺧﺐ ﺍﻟﺸﻔﺮﺓ ) (Code Selectorﰲ ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ ) .(GDTﺃﻣﺎ
ﺍﳌﺘﻐﲑ flagsﻓﺎﻥ ﻗﻴﻤﺘﻪ ﻫﻲ 010001110bﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﺍﻟﻮﺍﺻﻔﺔ ﻫﻲ 32-bitﻭﺃﻥ ﻣﺴﺘﻮﻯ ﺍﳊﻤﺎﻳﺔ
ﻫﻮ ﺍﳊﻠﻘﺔ ﺻﻔﺮ ).(Ring0
ﻭﺑﻌﺪ ﺃﻥ ﻳﺘﻢ ﺍﻧﺸﺎء ﺃﻏﻠﺐ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺑﺸﻜﻞ ﻣﺘﺴﻠﺴﻞ )ﰲ ﺃﻱ ﻣﻜﺎﻥ ﻋﻠﻰ ﺍﻟﺬﺍﻛﺮﺓ( ،ﳚﺐ ﺃﻥ ﻧﻨﺸﺊ ﺟﺪﻭﻝ
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ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﻘﻮﻡ ﲝﺴﺎﺏ ﻣﻜﺎﻥ ﺍﻟﻮﺍﺻﻔﺔ ﺑﺎﳌﻌﺎﺩﻟﺔ
int num * 8ﻭﺫﻟﻚ ﺑﺴﺒﺐ ﺃﻥ ﺣﺠﻢ ﻛﻞ ﻭﺍﺻﻔﺔ ﰲ ﺟﺪﻭﻝ 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.
• 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.
ﻭﻋﻨﺪﻣﺎ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻓﺎﻧﻪ ﳚﺐ ﺃﻥ ﺗﻨﻔﺬ ﺍﻷﻣﺮ iretﺃﻭ iretdﺣﱴ ﻳﺘﻢ ﺍﺭﺟﺎﻉ
ﺍﻟﻘﻴﻢ ﺍﻟﱵ ﰎ ﺩﻓﻌﻬﺎ ﺍﱃ ﺍﳌﻜﺪﺱ )ﻗﻴﻢ ﺍﻷﻋﻼﻡ .(FLAGSﻭﺑﺎﻟﺘﺎﱄ ﻳﻜﹾﻤﻞ ﺍﳌﻌﺎﰿ ﻋﻤﻠﻪ.
.٣.١.٦ﺃﺧﻄﺎء ﺍﳌﻌﺎﰿ
ﺧﻼﻝ ﺗﻨﻔﻴﺬ ﺍﳌﻌﺎﰿ ﻟﻸﻭﺍﻣﺮ ﻓﺎﻧﻪ ﺭﲟﺎ ﳛﺪﺙ ﺧﻄﺄ ﻣﺎ ﳑﺎ ﳚﻌﻞ ﺍﳌﻌﺎﰿ ﻳﻘﻮﻡ ﺑﺘﻮﻟﻴﺪ ﺍﺳﺘﺜﻨﺎء ﻳﻌﺮﻑ ﺑﺎﺳﺘﺜﻨﺎء ﺍﳌﻌﺎﰿ
،ﻭﻳﻮﺟﺪ ﻟﻪ ﻋﺪﺓ ﺃﻧﻮﺍﻉ:
ﺍﳋﻄﺄ :Faultﻋﻨﺪﻣﺎ ﺗﻌﻤﻞ ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﻫﺬﺍ ﺍﻟﻨﻮﻉ ﻣﻦ ﺍﻻﺳﺘﺜﻨﺎء ﻓﺮﲟﺎ ﻳﺘﻢ ﺍﺻﻼﺡ ﻫﺬﺍ ﺍﳋﻄﺄ ،ﻭﻋﻨﻮﺍﻥ •
ﺍﻟﻌﻮﺩﺓ ﺍﻟﺬﻱ ﻳﺘﻢ ﺩﻓﻌﻪ ﺍﱃ ﺍﳌﻜﺪﺱ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﺗﺴﺒﺐ ﰲ ﻫﺬﺍ ﺍﳋﻄﺄ.
ﺍﳋﻄﺄ :Trapﻋﻨﻮﺍﻥ ﺍﻟﻌﻮﺩﺓ ﻫﻮ ﻋﻨﻮﺍﻥ ﺍﻟﺘﻌﻠﻴﻤﺔ ﺍﻟﱵ ﺗﻠﻲ ﺍﻷﻣﺮ ﺍﻟﺬﻱ ﺗﺴﺒﺐ ﰲ ﺍﳋﻄﺄ. •
١٢٧
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﺍﳋﻄﺄ :Abortﻻ ﻳﻮﺟﺪ ﻋﻨﻮﺍﻥ ﻟﻠﻌﻮﺩﺓ ،ﻭﻟﻦ ﻳﻜﻤﻞ ﺍﻟﱪﻧﺎﻣﺞ ﻋﻤﻠﻪ ﺑﻌﺪ ﺍﻧﺘﻬﺎء ﺩﺍﻟﺔ ﻣﻌﺎﳉﺔ ﺍﳋﻄﺄ. •
١٢٨
So ware Interrupts .١.٦ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱪﳎﻴﺔ
ﻟﺬﻟﻚ ﳚﺐ ﺍﻳﻘﺎﻑ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﳊﲔ ﺍﻧﺸﺎء ﺟﺪﻭﻝ ﺍﳌﻘﻄﺎﻋﺎﺕ ﻭﻛﺘﺎﺑﺔ ﺩﻭﺍﻝ ﻣﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ .ﻛﺬﻟﻚ
ﺗﻮﺟﺪ ﻣﺸﻜﻠﺔ ﺃﺧﺮﻯ ﻟﺒﻌﺾ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﺣﻴﺚ ﺍﺎ ﺗﺴﺘﺨﺪﻡ ﻧﻔﺲ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ
ﺍﳌﻌﺎﰿ ﻟﻺﺳﺘﺜﻨﺎءﺍﺕ ﻭﺣﻠﻬﺎ ﻫﻮ ﺑﺈﻋﺎﺩﺓ ﺑﺮﳎﺔ ﺍﻟﺸﺮﳛﺔ ﺍﳌﺴﺆﻭﻟﺔ ﻋﻦ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻻﺷﺎﺭﺍﺕ ﻣﻦ ﺍﻟﻌﺘﺎﺩ ﻭﲢﻮﻳﻠﻬﺎ ﺍﱃ
ﻣﻘﺎﻃﻌﺎﺕ ﻭﺍﺭﺳﺎﳍﺎ ﺍﱃ ﺍﳌﻌﺎﰿ ،ﻫﺬﻩ ﺍﻟﺸﺮﳛﺔ ﺗﺴﻤﻰ Programmable Interrupt Controllerﻭﲣﺘﺼﺮ ﺏ PIC
ﻭﳚﺐ ﺇﻋﺎﺩﺓ ﺑﺮﳎﺘﻬﺎ ﻭﺗﻐﻴﲑ ﺍﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻟﻸﺟﻬﺰﺓ ﺍﻟﱵ ﺗﺴﺘﺨﺪﻡ ﺃﺭﻗﺎﻣﴼ ﻣﺘﺸﺎﺔ.
ﻭﻓﻴﻤﺎ ﻳﻠﻲ ﺳﻴﺘﻢ ﺇﻧﺸﺎء ﺟﺪﻭﻝ ﺍﳌﻘﺎﻃﻌﺎﺕ ) (IDTﺑﺎﺳﺘﺨﺪﺍﻡ ﻟﻐﺔ ﺍﻟﺴﻲ ﻭﺗﻮﻓﲑ ﺍﻝ 256ﺩﺍﻟﺔ ﳌﻌﺎﳉﺔ ﺍﳌﻘﻄﺎﻋﺎﺕ
ﻭﺣﺎﻟﻴﺎ ﺳﻴﻘﺘﺼﺮ ﻋﻤﻞ ﺍﻟﺪﻭﺍﻝ ﻋﻠﻰ ﻃﺒﺎﻋﺔ ﺭﺳﺎﻟﺔ ،ﻭﻗﺒﻞ ﺫﻟﻚ ﺳﻨﻘﻮﻡ ﺑﺎﻧﺸﺎء ﺟﺪﻭﻝ ﺍﻟﻮﺍﺻﻔﺎﺕ ﺍﻟﻌﺎﻡ )(GDT
ﳎﺪﺩﺍ )ﺃﻱ ﺳﻴﺘﻢ ﺍﻟﻐﺎء ﺍﳉﺪﻭﻝ ﺍﻟﺬﻱ ﻗﻤﻨﺎ ﺑﺎﻧﺸﺎﺋﻪ ﰲ ﻣﺮﺣﻠﺔ ﺍﻻﻗﻼﻉ( ﻭﺑﻌﺪ ﺫﻟﻚ ﺳﻨﺒﺪﺃ ﰲ ﺑﺮﳎﺔ ﻣﺘﺤﻜﻢ PIC
ﻭﺍﻋﺎﺩﺓ ﺗﺮﻗﻴﻢ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻷﺟﻬﺰﺓ ﻭﻛﺬﻟﻚ ﺑﺮﳎﺔ ﺳﺎﻋﺔ ﺍﻟﻨﻈﺎﻡ ﻻﺭﺳﺎﻝ ﻣﻘﺎﻃﻌﺔ ﺑﻮﻗﺖ ﳏﺪﺩ.
٢ﻣﻦ ﻣﻨﻈﻮﺭ ﺁﺧﺮ ﻫﺬﻩ ﺍﳉﺪﺍﻭﻝ ) (GDT,LDT and IDTﻫﻲ ﺟﺪﺍﻭﻝ ﻟﻠﻤﻌﺎﰿ ﻟﺬﻟﻚ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﰲ ﻃﺒﻘﺔ .HAL
١٢٩
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﻭﺣﺎﻟﻴﴼ ﻭﺍﺟﻬﺔ ﻃﺒﻘﺔ 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 .٢.٦ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ
ﺍﻟﺴﺒﺐ ﺍﻟﺮﺋﻴﺴﻲ ﰲ ﺗﻌﻄﻴﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻌﺘﺎﺩﻳﺔ ﻋﻨﺪ ﺍﻹﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ) (PModeﻫﻮ ﺑﺴﺒﺐ ﻋﺪﻡ
ﺗﻮﻓﺮ ﺩﻭﺍﻝ ﳌﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﰲ ﺗﻠﻚ ﺍﻟﻠﺤﻈﺔ ،ﻭﺣﱴ ﻟﻮ ﻗﻤﻨﺎ ﺑﺘﻮﻓﲑ ﺍﻝ ٢٥٦ﺩﺍﻟﺔ ﳌﻌﺎﳉﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻓﺎﻥ
ﻫﻨﺎﻟﻚ ﻣﺸﻜﻠﺔ ﺍﺳﺘﺨﺪﺍﻡ ﻧﻔﺲ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻷﻛﺜﺮ ﻣﻦ ﻏﺮﺽ ،ﻓﻤﺜﻼ ﻣﺆﻗﺘﺔ ﺍﻟﻨﻈﺎﻡ PITﺍﻟﱵ ﺗﺮﺳﻞ ﻣﻘﺎﻃﻌﺎﺕ
ﺑﺸﻜﻞ ﺩﺍﺋﻢ ﺗﺴﺘﺨﺪﻡ ﺍﳌﻘﺎﻃﻌﺔ ﺭﻗﻢ ٨ﻭﺍﻟﱵ ﻫﻲ ﺃﻳﻀﺎ ﺃﺣﺪ ﺍﺳﺘﺜﻨﺎءﺍﺕ ﺍﳌﻌﺎﰿ ،ﻟﺬﻟﻚ ﰲ ﻛﻠﺘﺎ ﺍﳊﺎﻻﺕ ﺳﻴﺘﻢ
ﺍﺳﺘﺪﻋﺎء ﺩﺍﻟﺔ ﲣﺪﱘ ﻭﺍﺣﺪﺓ ﻭﻫﻮ ﺷﻲء ﻣﺮﻓﻮﺽ ﲤﺎﻣﴼ .ﻟﺬﻟﻚ ﺍﳊﻞ ﺍﻟﻮﺣﻴﺪ ﻫﻮ ﺑﺈﻋﺎﺩﺓ ﺑﺮﳎﺔ ﺍﳌﺘﺤﻜﻢ ﺍﳌﺴﺆﻭﻝ
ﻋﻦ ﺍﺳﺘﻘﺒﺎﻝ ﺍﻹﺷﺎﺭﺍﺕ ﻣﻦ ﻣﺘﺤﻜﻤﺎﺕ ﺍﻟﻌﺘﺎﺩ ﻭﺗﻌﻴﲔ ﺃﺭﻗﺎﻡ ﳐﺘﻠﻔﺔ ﲞﻼﻑ ﺗﻠﻚ ﺍﻷﺭﻗﺎﻡ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ
ﻟﻸﺧﻄﺎء ﻭﺍﻻﺳﺘﺜﻨﺎءﺍﺕ ،ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ )ﺍﻧﻈﺮ ﺍﻟﺸﻜﻞ (١.٦ﻭﻇﻴﻔﺘﻪ ﻫﻲ ﺍﺳﺘﻘﺒﺎﻝ ﺇﺷﺎﺭﺍﺕ ﻣﻦ ﻣﺘﺤﻜﻤﺎﺕ
ﺍﻟﻌﺘﺎﺩ ﻭﻣﻦ ﰒ ﻳﻘﻮﻡ ﺑﺘﺤﻮﻳﻠﻬﺎ ﺍﱃ ﺃﺭﻗﺎﻡ ﻣﻘﺎﻃﻌﺎﺕ ﺗﺮﺳﻞ ﺑﻌﺪ ﺫﻟﻚ ﺍﱃ ﺍﳌﻌﺎﰿ ﺍﻟﺬﻱ ﻳﻘﻮﻡ ﺑﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ،
ﻭﻳﻌﺮﻑ ﻫﺬﺍ ﺍﳌﺘﺤﻜﻢ ﲟﺘﺤﻜﻢ PICﺍﺧﺘﺼﺎﺭﴽ ﻝ Programmable Interrupt Controllerﻭﻳﻌﺮﻑ ﺃﻳﻀﺎ ﺑﺎﻹﺳﻢ
، 8259Aﻭﰲ ﻫﺬﺍ ﺍﻟﺒﺤﺚ ﺳﻨﺴﺘﺨﺪﻡ ﺍﳌﺴﻤﻰ ﻣﺘﺤﻜﻢ .PIC
١٣٣
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﺍﳊﺎﺳﺐ ﻭﺇﻋﻄﺎء ﺭﻗﻢ ﻣﻘﺎﻃﻌﺔ ﻟﻜﻞ ﻣﺘﺤﻜﻢ ﻭﺑﺴﺒﺐ ﺗﻜﺮﺍﺭ ﻫﺬﻩ ﺍﻷﺭﻗﺎﻡ ﻓﺎﻧﻪ ﳚﺐ ﺗﻐﻴﲑﻫﺎ ﻷﺭﻗﺎﻡ ﺃﺧﺮﻯ ﻭﻫﺬﺍ
ﻳﺘﻢ ﺑﺴﻬﻮﻟﺔ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻭﺫﻟﻚ ﺑﺎﺳﺘﺨﺪﺍﻡ ﻣﻘﺎﻃﻌﺎﺕ ﺍﻟﺒﺎﻳﻮﺱ ﺃﻣﺎ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﻴﺠﺐ ﺃﻥ ﻧﻘﻮﻡ
ﺑﺎﻟﺘﺨﺎﻃﺐ ﺍﳌﺒﺎﺷﺮ ﻣﻊ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺬﻱ ﻟﺪﻳﻪ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻭﻣﻦ ﰒ ﺗﻐﻴﲑﻫﺎ .ﻭﺍﳉﺪﻭﻝ ٣.٦ﻳﻮﺿﺢ ﺃﺭﻗﺎﻡ
ﺍﳌﻘﺎﻃﻌﺎﺕ ﳌﺘﺤﻜﻤﺎﺕ ﺍﳊﺎﺳﺐ.
١٣٤
Programmable Interrupt Controller .٢.٦ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ
ﻣﺴﺠﻞ ﻃﻠﺒﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ ) :(Interrupt Request Registerﳛﻔﻆ ﻫﺬﺍ ﺍﳌﺴﺠﻞ ﺍﻷﺟﻬﺰﺓ ﺍﻟﱵ ﻃﻠﺒﺖ •
ﺗﻨﻔﻴﺬ ﻣﻘﺎﻃﻌﺘﻬﺎ ﻭﻫﻲ ﺑﺎﻧﺘﻈﺎﺭ ﻭﺻﻮﻝ ﺇﺷﻌﺎﺭ ) (Acnowledgesﻣﻦ ﺍﳌﻌﺎﰿ ،ﻭﺍﳉﺪﻭﻝ ٤.٦ﻳﻮﺿﺢ ﺑﺘﺎﺕ
ﻫﺬﺍ ﺍﳌﺴﺠﻞ.
١٣٥
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﻗﻴﻤﺔ ﺃﻱ ﺑﺖ ﻫﻲ ١ﻓﻬﺬﺍ ﻳﻌﲏ ﺃﻥ ﻣﺘﺤﻜﻢ ﺍﻟﻌﺘﺎﺩ ﺑﺎﻧﺘﻈﺎﺭ ﺍﻹﺷﻌﺎﺭ ﻣﻦ ﺍﳌﻌﺎﰿ.
ﻣﺴﺠﻞ ﺍﳋﺪﻣﺔ )) :(In Service Register (ISRﻳﺪﻝ ﻋﻠﻰ ﺍﳌﺴﺠﻞ ﻋﻠﻰ ﺃﻥ ﻃﻠﺐ ﺍﳌﻘﺎﻃﻌﺔ ﻗﺪ ﳒﺢ ﻭﺃﻥ •
ﺍﻹﺷﻌﺎﺭ ﻗﺪ ﻭﺻﻞ ﻟﻜﻦ ﱂ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ.
ﻣﺴﺠﻞ )) :(Interrupt Mask Register (IMRﳛﺪﺩ ﻫﺬﺍ ﺍﳌﺴﺠﻞ ﻣﺎ ﻫﻲ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﳚﺐ ﲡﺎﻫﻠﻬﺎ •
ﻭﻋﺪﻡ ﺍﺭﺳﺎﻝ ﺇﺷﻌﺎﺭ ﳍﺎ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺍﻟﺘﺮﻛﻴﺰ ﻋﻠﻰ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻷﻫﻢ.
ﻭﺍﳉﺪﻭﻝ ٥.٦ﻳﻮﺿﺢ ﻋﻨﺎﻭﻳﻦ ﻣﻨﺎﻓﺬ ﺍﳌﺴﺠﻼﺕ ﰲ ﺣﻮﺍﺳﻴﺐ .x86
١٣٦
Programmable Interrupt Controller .٢.٦ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ
ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺬﻱ ﳚﺐ ﺇﺭﺳﺎﻟﻪ ﺃﻭﻻ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ ﻭﻳﺄﺧﺬ ٧ﺑﺘﺎﺕ ﻭﻳﻮﺿﺢ ﺍﳉﺪﻭﻝ ٦.٦ﻫﺬﻩ
ﺍﻟﺒﺘﺎﺕ ﻭﻭﻇﻴﻔﺔ ﻛﻞ ﺑﺖ.
ﺣﻴﺚ ﺃﻥ ﺍﻟﺒﺖ ﺍﻷﻭﻝ ﳛﺪﺩ ﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﳚﺐ ﺇﺭﺳﺎﻝ ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ ICW4ﺃﻡ ﻻ ﻭﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻗﻴﻤﺔ ﺍﻟﺒﺖ ﻫﻲ ١
ﻓﺈﻧﻪ ﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ICW4ﺃﻣﺎ ﺍﻟﺒﺖ ﺍﻟﺜﺎﱐ ﻓﻐﺎﻟﺒﴼ ﻳﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ﺻﻔﺮ ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻥ ﻫﻨﺎﻙ ﺃﻛﺜﺮ ﻣﻦ ﻣﺘﺤﻜﻢ
PICﰲ ﺍﻟﻨﻈﺎﻡ ،ﻭﺍﻟﺒﺖ ﺍﻟﺜﺎﻟﺚ ﻏﲑ ﻣﺴﺘﺨﺪﻡ ﺃﻣﺎ ﺍﻟﺮﺍﺑﻊ ﻓﻴﺤﺪﺩ ﳕﻂ ﻋﻤﻞ ﺍﳌﻘﺎﻃﻌﺔ ﻫﻞ ﻫﻲ Level Triggered
Modeﺃﻡ ، Edge Triggered Modeﺃﻣﺎ ﺍﻟﺒﺖ ﺍﳋﺎﻣﺲ ﻓﻴﺠﺐ ﺃﻥ ﻳﺄﺧﺬ ﺍﻟﻘﻴﻤﺔ ١ﺩﻻﻟﺔ ﻋﻠﻰ ﺃﻧﻨﺎ ﺳﻨﻘﻮﻡ ﺑﺘﻬﻴﺌﺔ
ﻣﺘﺤﻜﻢ PICﻭﺑﻘﻴﺔ ﺍﻟﺒﺘﺎﺕ ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ ﰲ ﺣﻮﺍﺳﻴﺐ .x86ﻭﺍﻟﺸﻔﺮﺓ ٦.٥ﺗﻮﺿﺢ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﻷﻭﻝ ﺍﱃ
ﻣﺘﺤﻜﻢ PICﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ.
Example ٦.٥: Ini aliza on Control Words 1
١ ; Setup to initialize the primary PIC. Send ICW 1
٢ mov al, 0x11 ; 00010001
٣ out 0x20, al
٤
٥ ; Send ICW 1 to second PIC command register
٦ out 0xA0, al
ﺍﻷﻣﺮ ﺍﻟﺜﺎﱐ ICW2ﻳﺴﺘﺨﺪﻡ ﻹﻋﺎﺩﺓ ﺗﻐﻴﲑ ﻋﻨﻮﺍﻳﻦ ﺟﺪﻭﻝ IVTﺍﻟﺮﺋﻴﺴﻴﺔ ﻟﻠﻄﻠﺒﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ IRQﻭﺑﺎﻟﺘﺎﱄ ﻋﻦ
ﻃﺮﻳﻖ ﻫﺬﺍ ﺍﻷﻣﺮ ﳝﻜﻦ ﺃﻥ ﻧﻐﲑ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﻟﻞ IRQﺍﱃ ﺃﺭﻗﺎﻡ ﺃﺧﺮﻯ .ﻭﳚﺐ ﺃﻥ ﻳﺮﺳﻞ ﻫﺬﺍ ﺍﻷﻣﺮ ﻣﺒﺎﺷﺮﺓ
ﺑﻌﺪ ﺍﻷﻣﺮ ﺍﻷﻭﻝ ﻛﺬﻟﻚ ﳚﺐ ﺃﻥ ﻳﺘﻢ ﺍﺧﺘﻴﺎﺭ ﺃﺭﻗﺎﻣﺎ ﻏﲑ ﻣﺴﺘﺨﺪﻣﺔ ﻣﻦ ﻗﺒﻞ ﺍﳌﻌﺎﰿ ﺣﱴ ﻻ ﻧﻘﻊ ﰲ ﻧﻔﺲ ﺍﳌﺸﻜﻠﺔ
ﺍﻟﺴﺎﺑﻘﺔ ) ﻭﻫﻲ ﺃﻛﺜﺮ ﻣﻦ IRQﻳﺴﺘﺨﺪﻡ ﻧﻔﺲ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﺑﺎﻟﺘﺎﱄ ﻟﺪﻳﻬﻢ ﺩﺍﻟﺔ ﲣﺪﱘ ﻭﺍﺣﺪﺓ( .ﻭﺍﳌﺜﺎﻝ ٦.٦
ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺗﻐﻴﲑ ﺃﺭﻗﺎﻡ IRQﳌﺘﺤﻜﻢ PICﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ ﲝﻴﺚ ﻳﺘﻢ ﺍﺳﺘﺨﺪﺍﻡ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ٣٩-٣٢
ﻟﻠﻤﺘﺤﻜﻢ ﺍﻷﻭﻝ ﻭﺍﻷﺭﻗﺎﻡ ﻣﻦ ٤٧-٤٠ﻟﻠﻤﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻭﻫﻲ ﺃﺭﻗﺎﻣﴼ ﺧﺎﻟﻴﺔ ﻻ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ ﻭﺗﻘﻊ ﻣﺒﺎﺷﺮﺓ
ﺑﻌﺪ ﺁﺧﺮ ﻣﻘﺎﻃﻌﺔ ﻟﻠﻤﻌﺎﰿ ﺍﻟﺬﻱ ﻳﺴﺘﺨﺪﻡ ٣٢ﻣﻘﺎﻃﻌﺔ ﺑﺪءﴽ ﻣﻦ ﺍﻟﺼﻔﺮ ﻭﺍﻧﺘﻬﺎءﴽ ﺑﺎﳌﻘﺎﻃﻌﺔ .٣١
١٣٧
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﺍﻷﻣﺮ ﺍﻟﺜﺎﻟﺚ ICW3ﻳﺴﺘﺨﺪﻡ ﰲ ﺣﺎﻟﺔ ﻛﺎﻥ ﻫﻨﺎﻙ ﺃﻛﺜﺮ ﻣﻦ ﻣﺘﺤﻜﻢ PICﺣﻴﺚ ﳚﺐ ﺃﻥ ﳓﺪﺩ ﺭﻗﻢ ﻃﻠﺐ
ﺍﳌﻘﺎﻃﻌﺔ IRQﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻟﻠﺘﺨﺎﻃﺐ ﻣﻊ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ .ﻭﰲ ﺣﻮﺍﺳﻴﺐ x86ﻏﺎﻟﺒﴼ ﻣﺎ
ﻳﺴﺘﺨﺪﻡ IRQ2ﻟﺬﺍ ﳚﺐ ﺇﺭﺳﺎﻝ ﻫﺬﺍ ﺍﻷﻣﺮ ﺍﱃ ﺍﳌﺘﺤﻜﻢ ،ﻟﻜﻦ ﻛﻞ ﻣﺘﺤﻜﻢ ﻳﺘﻮﻗﻊ ﺍﻷﻣﺮ ﺑﺼﻴﻐﺔ ﻣﻌﻴﻨﺔ ﻳﻮﺿﺤﻬﺎ
ﺍﳉﺪﻭﻻﻥ ٧.٦ﻭ . ٨.٦
ﻭﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﲝﺴﺐ ﺍﻟﺼﻴﻐﺔ ﺍﻟﱵ ﻳﻘﺒﻠﻬﺎ ﻣﺴﺠﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻟﻠﻤﺘﺤﻜﻢ ،ﻓﻤﺘﺤﻜﻢ PICﺍﻟﺮﺋﻴﺴﻲ ﻳﺴﺘﻘﺒﻞ
ﺭﻗﻢ IRQﻋﻠﻰ ﺷﻜﻞ ٧ﺑﺖ ﲝﻴﺚ ﻳﺘﻢ ﺗﻔﻌﻴﻞ ﺭﻗﻢ ﺍﻟﺒﺖ ﺍﳌﻘﺎﺑﻞ ﻟﺮﻗﻢ IRQﻭﰲ ﻣﺜﺎﻟﺜﺎ ﻳﺮﺗﺒﻂ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺮﺋﻴﺴﻲ
ﻣﻊ ﺍﻟﺜﺎﻧﻮﻱ ﻋﱪ IRQ2ﻟﺬﻟﻚ ﳚﺐ ﺗﻔﻌﻴﻞ ﻗﻴﻤﺔ ﺍﻟﺒﺖ ) ٢ﺃﻱ ﳚﺐ ﺇﺭﺳﺎﻝ ﺍﻟﻘﻴﻤﺔ 0000100bﻭﻫﻲ ﺗﻌﺎﺩﻝ (0x4
ﺑﻴﻨﻤﺎ ﺍﳌﺘﺤﻜﻢ ﺍﻟﺜﺎﻧﻮﻱ ﻳﻘﺒﻞ ﺭﻗﻢ IRQﻋﻦ ﻃﺮﻳﻖ ﺇﺭﺳﺎﻝ ﻗﻴﻤﺘﻪ ﻋﻠﻰ ﺍﻟﺸﻜﻞ ﺍﻟﺜﻨﺎﺋﻲ ﻭﻫﻲ ) ٢ﻭﺗﻌﺎﺩﻝ ﺑﺎﻟﺘﺮﻣﻴﺰ
ﺍﻟﺜﻨﺎﺋﻲ (010ﻭﺑﻘﻴﺔ ﺍﻟﺒﺘﺎﺕ ﳏﺠﻮﺯﺓ )ﺍﻧﻈﺮ ﺟﺪﻭﻝ ، (٨.٦ﻭﺍﳌﺜﺎﻝ ٦.٧ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﻟﺜﺎﻟﺚ ﺍﱃ
ﺍﳌﺘﺤﻜﻤﲔ.
Example ٦.٧: Ini aliza on Control Words 3
١٣٨
Programmable Interrupt Controller .٢.٦ﻣﺘﺤﻜﻢ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﻘﺎﺑﻞ ﻟﻠﱪﳎﺔ
ﻫﻮ ﺁﺧﺮ ﺃﻣﺮ ﲢﻜﻢ ﳚﺐ ﺇﺭﺳﺎﻟﻪ ﺍﱃ ﺍﳌﺘﺤﻜﻤﲔ ﻭﻳﺄﺧﺬ ﺍﻟﺘﺮﻛﻴﺒﺔ ﺍﻟﱵ ﻳﻮﺿﺤﻬﺎ ﺟﺪﻭﻝ ﺍﻷﻣﺮ ﺍﻟﺮﺍﺑﻊ
ICW4
.٩.٦
ﻭﰲ ﺍﻟﻐﺎﻟﺐ ﻻ ﻳﻮﺟﺪ ﺣﻮﺟﺔ ﻟﺘﻔﻌﻴﻞ ﻛﻞ ﻫﺬﻩ ﺍﳋﺼﺎﺋﺺ ،ﻓﻘﻂ ﺃﻭﻝ ﺑﺖ ﳚﺐ ﺗﻔﻌﻴﻠﻪ ﺣﻴﺚ ﻳﺴﺘﺨﺪﻡ ﻣﻊ
ﺣﻮﺍﺳﻴﺐ . x86ﻭﺍﳌﺜﺎﻝ ٦.٨ﻳﻮﺿﺢ ﻛﻴﻔﺔ ﺇﺭﺳﺎﻝ ﺍﻷﻣﺮ ﺍﻟﺮﺍﺑﻊ ﺍﱃ ﺍﳌﺘﺤﻜﻢ PICﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ.
Example ٦.٨: Ini aliza on Control Words 4
١ mov al, 1 ; bit 0 enables 80x86 mode
٢
٣ ; send ICW 4 to both primary and secondary PICs
٤ out 0x21, al
٥ out 0xA1, al
ﻭﺑﻌﺪ ﺇﺭﺳﺎﻝ ﻫﺬﻩ ﺍﻷﻭﺍﻣﺮ ﺍﻷﺭﺑﻊ ﺗﻜﺘﻤﻞ ﻋﻤﻠﻴﺔ ﻴﺌﺔ ﻣﺘﺤﻜﻢ PICﺍﻟﺮﺋﻴﺴﻲ ﻭﺍﻟﺜﺎﻧﻮﻱ ،ﻭﰲ ﺣﺎﻟﺔ ﺣﺪﻭﺙ ﺃﻱ
ﻣﻘﺎﻃﻌﺔ ﻣﻦ ﻣﺘﺤﻜﻢ ﻟﻌﺘﺎﺩ ﻣﺎ ،ﻓﺈﻥ ﺃﺭﻗﺎﻡ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺍﻟﱵ ﺳﺘﺮﺳﻞ ﺍﱃ ﺍﳌﻌﺎﰿ ﻫﻲ ﺍﻷﺭﻗﺎﻡ ﺍﻟﱵ ﻗﻤﻨﺎ ﺑﺘﻌﻴﻴﻨﻬﺎ ﰲ
ﺍﻷﻣﺮ ﺍﻟﺜﺎﱐ )ﻭﺗﺒﺪﺃ ﻣﻦ ٣٢ﺍﱃ (٤٧ﻭﻫﻲ ﲣﺘﻠﻒ ﺑﺎﻟﻄﺒﻊ ﻋﻦ ﺍﻷﺭﻗﺎﻡ ﺍﻟﱵ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﳌﻌﺎﰿ .ﻭﲞﺼﻮﺹ ﺃﻭﺍﻣﺮ
ﺍﻟﺘﺤﻜﻢ ﺍﻟﺜﻼﺙ OCWﻓﻠﻦ ﳓﺘﺎﺝ ﺍﻟﻴﻬﺎ ﲨﻴﻌﴼ ﻭﺳﻴﺘﻢ ﺍﳊﺪﻳﺚ ﻋﻦ ﺍﻷﻣﺮ ﺍﻟﺜﺎﱐ OCW2ﻧﻈﺮﴽ ﻷﻧﻪ ﳚﺐ ﺃﻥ ﻳﺮﺳﻞ
ﺩﺍﺋﻤﴼ ﺑﻌﺪ ﺃﻥ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻭﺫﻟﻚ ﺣﱴ ﻳﺘﻢ ﺍﻟﺴﻤﺎﺡ ﻟﺒﻘﻴﺔ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺃﻥ ﺗﺄﺧﺬ ﺩﻭﺭﴽ
ﳌﻌﺎﳉﺘﻬﺎ .ﻭﺍﳉﺪﻭﻝ ١٠.٦ﻳﻮﺿﺢ ﺍﻟﺒﺘﺎﺕ ﺍﻟﱵ ﳚﺐ ﺇﺭﺳﺎﳍﺎ ﺍﱃ ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ .ﻭﻳﻬﻤﻨﺎ ﺍﻟﺒﺘﺎﺕ ٧-٥ﺣﻴﺚ
ﺃﻥ ﻗﻴﻤﻬﻢ ﲢﺪﺩ ﺑﻌﺾ ﺍﳋﺼﺎﺋﺺ ﺍﻟﱵ ﻳﻮﺿﺤﻬﺎ ﺍﳉﺪﻭﻝ .١١.٦ﻭﺍﳌﺜﺎﻝ ٦.٩ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺇﺭﺳﺎﻝ ﺇﺷﺎﺭﺓ ﺎﻳﺔ
١٣٩
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
ﻋﻤﻞ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ) (EOIﺣﻴﺚ ﳚﺐ ﺿﺒﻂ ﺍﻟﺒﺘﺎﺕ ﻹﺧﺘﻴﺎﺭ .Non specific EOI command
Example ٦.٩: Send EOI
١ ; send EOI to primary PIC
٢
٣ mov al, 0x20 ; set bit 4 of OCW 2
٤ out 0x20, al ; write to primary PIC command register
١٤٠
Programmable Interval Timer .٣.٦ﺍﳌﺆﻗﺘﺔ
Mask Registerﻟﻴﺘﺄﻛﺪ ﻣﻦ ﺃﻧﻪ ﻻ ﺗﻮﺟﺪ ﻫﻨﺎﻙ ﻣﻘﺎﻃﻌﺔ ﺫﺍﺕ ﺃﻭﻟﻴﺔ ﺃﻋﻠﻰ ﺣﻴﺚ ﰲ ﻫﺬﻩ ﺍﳊﺎﻟﺔ ﻋﻠﻰ ﺍﳌﻘﺎﻃﻌﺔ
ﺍﳉﺪﻳﺪﺓ ﺃﻥ ﺗﻨﻨﻈﺮ ﺣﱴ ﻳﺘﻢ ﲣﺪﱘ ﻛﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺫﺍﺕ ﺍﻷﻭﻟﻮﻳﺔ .ﻭﺑﻌﺪ ﺫﻟﻚ ﻳﺮﺳﻞ PICﺇﺷﺎﺭﺓ ﺍﱃ ﺍﳌﻌﺎﰿ ﻣﻦ
ﺧﻼﻝ ﻣﺸﺒﻚ INTAﻷﺧﺒﺎﺭ ﺍﳌﻌﺎﰿ ﺑﺄﻥ ﻫﻨﺎﻙ ﻣﻘﺎﻃﻌﺔ ﳚﺐ ﺗﻨﻔﻴﺬﻫﺎ .ﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ ﺍﳌﻌﺎﰿ ﺣﻴﺚ ﻳﻘﻮﻡ ﺑﺎﻹﻧﺘﻬﺎء
ﻣﻦ ﺗﻨﻔﻴﺬ ﺍﻷﻣﺮ ﺍﳊﺎﱄ ﺍﻟﺬﻱ ﻳﻌﻤﻞ ﻋﻠﻴﻪ ﻭﻣﻦ ﰒ ﻳﻘﻮﻡ ﺑﻔﺤﺺ ﻗﻴﻤﺔ ﺍﻟﻌﻠﻢ IFﺣﻴﺚ ﰲ ﺣﺎﻟﺔ ﻛﺎﻧﺖ ﻏﲑ ﻣﻔﻌﻠﺔ
ﻓﺎﻥ ﺍﳌﻌﺎﰿ ﺳﻮﻑ ﻳﺘﺠﺎﻫﻞ ﻃﻠﺐ ﺗﻨﻔﻴﺬ ﺍﳌﻘﺎﻃﻌﺔ ،ﺃﻣﺎ ﺇﺫﺍ ﻭﺟﺪ ﺍﳌﻌﺎﰿ ﻗﻴﻤﺔ ﺍﻟﻌﻠﻢ ﻣﻔﻌﻠﺔ ﻓﺎﻧﻪ ﻳﻘﻮﻡ ﺑﺎﺭﺳﺎﻝ ﺇﺷﻌﺎﺭ
) (Acnowledgesﻋﱪ ﻣﺸﺒﻚ INTRﺍﱃ ﻣﺘﺤﻜﻢ PICﺍﻟﺬﻱ ﺑﺪﻭﺭﻩ ﻳﺴﺘﻘﺒﻠﻬﺎ ﻣﻦ ﻣﺸﺒﻚ INTAﻭﻳﻀﻊ ﺭﻗﻢ
ﺍﳌﻘﺎﻃﻌﺔ ﻭﺭﻗﻢ IRQﰲ ﺍﳌﺸﺎﺑﻚ ، D0-D7ﻭﺃﺧﲑﺍ ﻳﻔﻌﻞ ﻗﻴﻤﺔ ﺍﻟﺒﺖ ٠ﰲ ﻣﺴﺠﻞ In Service Registerﺩﻻﻟﺔ
ﻋﻠﻰ ﺃﻥ ﻣﻘﺎﻃﻌﺔ ﺍﳌﺆﻗﺘﺔ ﺟﺎﺭﻱ ﺗﻨﻔﻴﺬﻫﺎ .ﻭﻋﻨﺪﻣﺎ ﳛﺼﻞ ﺍﳌﻌﺎﰿ ﻋﻠﻰ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻓﺎﻧﻪ ﻳﻘﻮﻡ ﺑﻮﻗﻒ ﺍﻟﻌﻤﻠﻴﺔ ﺍﻟﱵ
ﻳﻌﻤﻞ ﻋﻠﻴﻬﺎ ﻭﳛﻔﻆ ﻗﻴﻢ ﻣﺴﺠﻞ ﺍﻷﻋﻼﻡ ﻭﻣﺴﺠﻞ CS and EIPﻭﺇﺫﺍ ﻛﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳊﻘﻴﻘﻲ ﻓﺈﻧﻪ
ﻳﺄﺧﺬ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻳﺬﻫﺐ ﺎ ﻛﺪﻟﻴﻞ ﺍﱃ ﺟﺪﻭﻝ ﺍﳌﻘﻄﺎﻋﺎﺕ IVTﺣﻴﺚ ﳚﺪ ﻋﻨﻮﺍﻥ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻣﻦ ﰒ
ﻳﻨﻘﻞ ﺍﻟﺘﻨﻔﻴﺬ ﺍﻟﻴﻬﺎ ،ﺃﻣﺎ ﺍﺫﺍ ﻛﺎﻥ ﺍﳌﻌﺎﰿ ﻳﻌﻤﻞ ﰲ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ ﻓﺎﻧﻪ ﻳﺄﺧﺬ ﺭﻗﻢ ﺍﳌﻘﺎﻃﻌﺔ ﻭﻳﺬﻫﺐ ﺎ ﺍﱃ ﺟﺪﻭﻝ
ﻭﺍﺻﻔﺎﺕ ﺍﳌﻘﺎﻃﻌﺎﺕ ﺣﻴﺚ ﳚﺪ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ .ﻭﻋﻨﺪﻣﺎ ﺗﻨﺘﻬﻲ ﺩﺍﻟﺔ ﲣﺪﱘ ﺍﳌﻘﺎﻃﻌﺔ ﻣﻦ ﻋﻤﻠﻬﺎ ﻓﺎﺎ ﳚﺐ
ﺃﻥ ﺗﺮﺳﻞ ﺇﺷﺎﺭﺓ EOIﺣﱴ ﻳﺘﻢ ﺗﻔﻌﻴﻞ ﺍﳌﻘﺎﻃﻌﺎﺕ ﳎﺪﺩﴽ.
٧ﻻ ﻳﻘﺼﺪ ﺬﻩ ﻛﺮﺕ ﺍﻟﺼﻮﺕ ﻭﺇﳕﺎ ﻳﻮﺟﺪ ﰲ ﻛﻞ ﺣﺎﺳﺐ ﲰﺎﻋﺎﺕ ﺩﺍﺧﻠﻴﺔ ﺗﺴﺘﺨﺪﻡ ﰲ ﺇﺻﺪﺍﺭ ﺍﻟﺼﻮﺕ ﻭﺍﻟﻨﻐﻤﺎﺕ ﻭﺃﺣﺪ ﺍﺳﺘﺨﺪﺍﻣﺎﺎ
ﻹﺻﺪﺍﺭ ﺭﺳﺎﺋﻞ ﺍﳋﻄﺄ ﺑﻌﺪ ﻋﻤﻠﻴﺔ ﻓﺤﺺ ﺍﳊﺎﺳﺐ ) (POSTﰲ ﻣﺮﺣﻠﺔ ﺍﻹﻗﻼﻉ.
١٤١
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
١٤٢
Programmable Interval Timer .٣.٦ﺍﳌﺆﻗﺘﺔ
)ﻭﻫﻮ ﻣﺴﺠﻞ ﺑﻄﻮﻝ ٨ﺑﺖ( ﺣﻴﺚ ﳚﺐ ﺇﺭﺳﺎﻝ ﻗﻴﻢ ﻣﻌﻴﻨﺔ ﺣﱴ ﻧﺘﻤﻜﻦ ﻣﻦ ﺍﻟﻘﺮﺍءﺓ ﺃﻭ ﺍﻟﻜﺘﺎﺑﺔ ﰲ ﻋﺪﺍﺩ ﻣﺎ.
• 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; Don't use
١٤٣
Interrupts ﺍﳌﻘﺎﻃﻌﺎﺕ.٦
• 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 ١٠ )ﻛﻞ100Hz ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺑﺮﳎﺔ ﻋﺪﺍﺩ ﻣﺆﻗﺖ ﺍﻟﻨﻈﺎﻡ ﻹﺭﺳﺎﻝ ﻃﻠﺐ ﻣﻘﺎﻃﻌﺔ ﻛﻞ٦.١٠ ﻭﺍﳌﺜﺎﻝ
. ﻭﻫﺬﺍ ﻳﺘﻢ ﻋﻦ ﻃﺮﻳﻖ ﺇﺭﺳﺎﻝ ﺃﻣﺮ ﺍﻟﺘﺤﻜﻢ ﺃﻭﻻﹰ ﻭﻣﻦ ﰒ ﺇﺭﺳﺎﻝ ﺍﻟﻮﻗﺖ ﺍﳌﻄﻠﻮﺏ ﺍﱃ ﺍﻟﻌﺪﺍﺩ ﺍﳌﻄﻠﻮﺏ،
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 .٤.٦ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ
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
٤ #define I386 PIC IRQ SERIAL2 3
٥ #define I386 PIC IRQ SERIAL1 4
٦ #define I386 PIC IRQ PARALLEL2 5
٧ #define I386 PIC IRQ DESKETTE 6
٨ #define I386 PIC IRQ PARALLEL1 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
١٦
)١٧ // Operation Commamd Word 2 (OCW2
١٨ #define I386 PIC OCW2 MASK L1 1
١٩ #define I386 PIC OCW2 MASK L2 2
٢٠ #define I386 PIC OCW2 MASK L3 4
١٤٥
Interrupts ﺍﳌﻘﺎﻃﻌﺎﺕ.٦
١٤٦
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 ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ.٤.٦
PIT ﺩﻋﻢ.٢.٤.٦
١٤٩
Interrupts ﺍﳌﻘﺎﻃﻌﺎﺕ.٦
١٥٠
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 ﻳﻮﺿﺢ ﺍﻟﻮﺍﺟﻬﺔ ﺍﻟﻌﺎﻣﺔ ﻟﻄﺒﻘﺔ٦.١٥ ﺍﳌﺜﺎﻝ
١٥٢
HAL ﺗﻮﺳﻌﺔ ﻃﺒﻘﺔ.٤.٦
١٥٣
Interrupts ﺍﳌﻘﺎﻃﻌﺎﺕ.٦
١٥٤
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();
١٠٥ }
١٥٦
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);
١٥٨
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.\n\n";
١١
١٢ kclear(0x1f);
١٣ kgoto xy(0,0);
١٤ kset color(0x1f);
١٥ kputs(panic);
١٦ kprintf(" ∗∗∗ STOP: %s",msg);
١٧
١٨ /∗ hang ∗/
١٩ for (;;) ;
٢٠ }
١٥٩
Interrupts .٦ﺍﳌﻘﺎﻃﻌﺎﺕ
١٦٠
.٧ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ
ﺗﻌﺘﱪ ﺫﺍﻛﺮﺓ ﺍﳊﺎﺳﺐ ﺍﻟﺮﺋﻴﺴﻴﺔ ) (RAMﻣﻦ ﺃﻫﻢ ﺍﳌﻮﺍﺭﺩ ﺍﻟﱵ ﳚﺐ ﻋﻠﻰ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﺇﺩﺍﺭﺎ ﺣﻴﺚ ﳝﺜﻞ ﺍﳌﺨﺰﻥ
ﺍﻟﺬﻱ ﻳﻘﺮﺃ ﺍﳌﻌﺎﰿ ﻣﻨﻪ ﺍﻷﻭﺍﻣﺮ ﻭﻳﻘﻮﻡ ﺑﺘﻨﻔﻴﺬﻫﺎ ،ﻭﻻ ﳝﻜﻦ ﻟﻠﻤﻌﺎﰿ ﺍﻟﻮﺻﻮﻝ ﺍﳌﺒﺎﺷﺮ ﺍﱃ ﺃﺣﺪ ﺍﻟﺬﻭﺍﻛﺮ ﺍﻟﺜﺎﻧﻮﻳﺔ
ﻣﺒﺎﺷﺮﺓ ﻭﺇﳕﺎ ﻳﺘﻢ ﲢﻤﻴﻞ ﺍﻟﺒﻴﺎﻧﺎﺕ ﻭﺍﻟﱪﺍﻣﺞ ﺍﱃ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺮﺋﻴﺴﻴﺔ ﺣﱴ ﺗﺼﺒﺢ ﻣﺘﺎﺣﺔ ﻟﻠﻤﻌﺎﰿ .ﻭﻫﻨﺎ ﻳﺄﰐ ﺩﻭﺭ
ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ) (Memory Managerﺣﻴﺚ ﻳﺮﺍﻗﺐ ﻫﺬﺍ ﺍﻟﱪﻧﺎﻣﺞ ﺃﺟﺰﺍء ﺍﻟﺬﺍﻛﺮﺓ ﻭﻳﺘﻌﺮﻑ ﻋﻠﻰ ﻣﺎ ﻫﻮ ﻣﺴﺘﺨﺪﻡ
ﻭﻣﺎ ﻫﻮ ﻏﲑ ﻣﺴﺘﺨﺪﻡ ﻛﻤﺎ ﻳﻮﻓﺮ ﺩﻭﺍﻻ ﳊﺠﺰ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻭﲢﺮﻳﺮﻫﺎ ،ﻛﺬﻟﻚ ﻣﻦ ﺍﳌﻤﻜﻦ ﺃﻥ ﻳﻘﻮﻡ ﺑﻌﻤﻠﻴﺔ
ﺇﻋﺎﺩﺓ ﲡﺰﺋﺔ ﳌﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻭﺫﻟﻚ ﻟﺘﻮﻓﲑ ﻣﺴﺎﺣﺔ ﻭﺍﺳﺘﻐﻼﻝ ﺃﻓﻀﻞ.ﻭﰲ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﺳﻴﺘﻢ ﺩﺭﺍﺳﺔ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ
ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ ﻭﺍﻟﺘﺨﻴﻠﻴﺔ ﻭﻛﻴﻔﻴﺔ ﺑﺮﳎﺘﻬﻢ ﻛﺬﻟﻚ ﺳﻴﺘﻢ ﻋﺮﺽ ﺑﻌﺾ ﺍﻟﻄﺮﻕ ﳊﺴﺎﺏ ﺍﳌﺴﺎﺣﺔ ﺍﻟﻜﻠﻴﺔ ﻟﻠﺬﺍﻛﺮﺓ ﻭﻋﺮﺽ
ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺍﳌﺴﺘﺨﺪﻣﺔ ﻣﻦ ﻗﺒﻞ ﺍﻟﻨﻈﺎﻡ.
١٦١
.٧ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ
ﺍﳌﺴﺠﻞ :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:
١٦٣
.٧ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ
ﻭﳚﺪﺭ ﻣﻼﺣﻈﺔ ﺃﻥ ﻫﺬﺍ ﺍﳌﻘﺎﻃﻌﺔ ﻻ ﲢﺴﺐ ﺃﻭﻝ ﻣﻴﺠﺎ ﺑﺎﻳﺖ ﻣﻦ ﺍﻟﺬﺍﻛﺮﺓ ،ﻟﺬﻟﻚ ﻋﻨﺪ ﺍﺳﺘﺨﺪﺍﻡ ﻫﺬﻩ ﺍﻟﺪﺍﻟﺔ ﳚﺐ
ﺯﻳﺎﺩﺓ ﺍﳊﺠﻢ ﺍﻟﻜﻠﻲ ﲟﻘﺪﺍﺭ ١٠٢٤ﻛﻴﻠﻮﺑﺎﻳﺖ )ﺍﻟﺰﻳﺎﺩﺓ ﺗﻜﻮﻥ ﰲ ﻣﺴﺠﻞ ، (axﻛﺬﻟﻚ ﳚﺐ ﺿﺮﺏ ﺍﳌﺴﺠﻞ
bxﺑﺎﻟﻌﺪﺩ ٦٤ﻧﻈﺮﺍ ﻻﻥ ﺍﻟﻘﻴﻤﺔ ﺍﻟﱵ ﺗﻀﻌﻬﺎ ﺍﻟﺪﺍﻟﺔ ﻫﻲ ﻋﺪﺩ ﺍﻟﻮﺣﺪﺍﺕ ﺍﳌﻜﻮﻧﺔ ﻣﻦ ٦٤ﻛﻴﻠﻮﺑﺎﻳﺖ ،ﻭﻫﺬﺍ ﻳﻌﲏ
ﺍﻥ ﻛﺎﻥ ﺍﻟﻌﺪﺩ ﻫﻮ ٢ﻣﺜﻼ ﻓﺎﻥ ﺍﻟﻨﺘﻴﺠﺔ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ 2*64ﻭﺗﺴﺎﻭﻱ 128ﻛﻴﻠﻮﺑﺎﻳﺖ.
ﺍﳌﺴﺠﻞ :eaxﺍﻟﻘﻴﻤﺔ 0x534d4150ﻭﺗﺴﺎﻭﻱ SMAPﺑﺘﺮﻣﻴﺰ ،ASCIIﻭﰲ ﺣﺎﻟﺔ ﺣﺪﻭﺙ ﺧﻄﺄ ﻓﺎﻥ ﺭﻗﻢ •
ﺍﳋﻄﺄ ﺳﻴﺤﻔﻆ ﰲ ﺍﳌﺴﺠﻞ .ah
ﺍﳌﺴﺠﻞ :ebxﻋﻨﻮﺍﻥ ﺍﻟﺴﺠﻞ ﺍﻟﺘﺎﱄ ﺃﻭ ﺻﻔﺮ ﰲ ﺣﺎﻟﺔ ﺍﻹﻧﺘﻬﺎء. •
ﻭﺗﻌﻮﺩ ﺑﺎﳌﺨﺮﺟﺎﺕ:
ﺍﳌﺴﺠﻞ :eaxﺭﻗﻢ ﺍﻟﺪﺍﻟﺔ ﻭﻫﻲ .0xe820 •
١٦٤
Physical Memory Management .١.٧ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ
ﻭﺑﻌﺪ ﺗﻨﻔﻴﺬ ﺍﳌﻘﺎﻃﻌﺔ ﻓﺎﻥ ﺍﻟﺬﺍﻛﺮﺓ Bufferﻳﺘﻢ ﻣﻠﺌﻬﺎ ﺑﺄﻭﻝ ﺳﺠﻞ ﻭﻫﻮ ﺑﻄﻮﻝ ٢٤ﺑﺎﻳﺖ ﻭﻳﺘﻢ ﺗﻜﺮﺍﺭ ﺍﺳﺘﺪﻋﺎء
ﺍﳌﻘﺎﻃﻌﺔ ﺍﱃ ﺃﻥ ﺗﻜﻮﻥ ﻗﻴﻤﺔ ﺍﳌﺴﺠﻞ ebxﻣﺴﺎﻭﻳﺔ ﻟﻠﺼﻔﺮ .ﻭﳏﺘﻮﻳﺎﺕ ﻛﻞ ﺳﺠﻞ ﻳﻮﺿﺤﻬﺎ ﺍﳌﺜﺎﻝ .٧.٣
Example ٧.٣: Memory Map Entry Structure
١
٢ ; Memory Map Entry Structure
٣ struc memory map entry
٤ .base addr resq 1
٥ .length resq 1
٦ .type resd 1
٧ .acpi null resd 1
٨ endstruc
ﻭﻫﻲ ﺗﻮﺻﻒ ﻣﻘﻄﻊ ﺍﻟﺬﺍﻛﺮﺓ ﺣﻴﺚ ﲢﻮﻱ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﺍﳌﻘﻄﻊ ﻭﻃﻮﻟﻪ ﻭﻧﻮﻉ ﺍﳌﻘﻄﻊ ﻭﺃﺧﲑﺍ ﺑﻴﺎﻧﺎﺕ ﳏﺠﻮﺯﺓ.
ﻭﻧﻮﻉ ﺍﳌﻘﻄﻊ ﳛﺪﺩ ﻣﺎ ﺇﺫﺍ ﻛﺎﻥ ﺍﳌﻘﻄﻊ ﻣﺴﺘﺨﺪﻣﺎ ﺃﻭ ﳏﺠﻮﺯﺍ ﻭﻳﺄﺧﺬ ﻋﺪﺓ ﻗﻴﻢ:
ﺍﻟﻘﻴﻤﺔ :1ﺗﺪﻝ ﻋﻠﻰ ﺃﻥ ﺍﳌﻘﻄﻊ ﻣﺘﻮﻓﺮﺍ. •
ﺍﻟﻘﻴﻤﺔ ACPI Reclaim Memory :3ﻭﻫﻲ ﻣﻨﻄﻘﺔ ﳏﺠﻮﺯﺓ ﻟﻜﻲ ﻳﺴﺘﺨﺪﻣﻬﺎ ﺍﻟﻨﻈﺎﻡ. •
ﻭﺍﳌﺜﺎﻝ ٧.٤ﻳﻮﺿﺢ ﻛﻴﻔﻴﺔ ﺟﻠﺐ ﻣﻘﺎﻃﻊ ﺍﻟﺬﺍﻛﺮﺓ ﻟﻜﻲ ﻳﺴﺘﻔﻴﺪ ﻣﻨﻬﺎ ﻣﺪﻳﺮ ﺍﻟﺬﺍﻛﺮﺓ ﻻﺣﻘﺎ.
Example ٧.٤: Get Memory Map
; ١ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
٢ ; get memory map:
٣ ; Input:
; ٤ = EAX 0x0000E820
; ٥ = 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
١٦٥
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
١٦٦
Physical Memory Management .١.٧ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ
ﺣﺎﻟﺔ ﺍﳊﺎﺳﺐ
ﻣﻦ ﺿﻤﻦ ﻫﺬﻩ ﺍﳌﻘﺎﻳﻴﺲ ﺃﻳﻀﺎ ﺗﻮﻓﺮ ﺣﺎﻟﺔ ﻣﻌﻴﻨﺔ ﻟﻠﺤﺎﺳﺐ )، (Machine Stateﻭﻫﻲ ﺗﻨﺺ ﻋﻠﻰ ﺃﻧﻪ ﻋﻨﺪ ﲢﻤﻴﻞ
ﻧﻮﺍﺓ ﺃﻱ ﻧﻈﺎﻡ ﺗﺸﻐﻴﻞ ﻓﺎﻥ ﺑﻌﺾ ﺍﳌﺴﺠﻼﺕ ﳚﺐ ﺃﻥ ﺗﺄﺧﺬ ﻗﻴﻤﺎ ﳏﺪﺩﺓ ﻛﺎﻻﰐ:
ﺍﳌﺴﺠﻞ :eaxﳚﺐ ﺃﻥ ﻳﺄﺧﺬ ﺍﻟﺮﻗﻢ 0x2BADB002ﻭﻫﻲ ﺇﺷﺎﺭﺓ ﻟﻨﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﺑﺄﻥ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﻳﺪﻋﻢ •
ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ.
ﺍﳌﺴﺠﻞ :ebxﲢﺘﻮﻱ ﻋﻠﻰ ﻋﻨﻮﺍﻥ ﺑﺪﺍﻳﺔ ﻫﻴﻜﻠﺔ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ. •
١ﻋﻠﻰ ﺍﻟﺮﻏﻢ ﻣﻦ ﺃﻧﻪ ﳝﻜﻦ ﲤﺮﻳﺮ ﻫﺬﻩ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺑﺄﻱ ﻃﺮﻳﻘﺔ ﺇﻻ ﺃﻥ ﺍﻹﻟﺘﺰﺍﻡ ﻴﻜﻠﺔ ﻗﻴﺎﺳﻴﺔ ﺳﻴﻔﻴﺪ ﻻﺣﻘﺎ ﻋﻨﺪ ﺩﻋﻢ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ.
١٦٧
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
ﻭﺍﻧﺘﻬﺎءﺍ ﺑﺎﻟﻌﻨﻮﺍﻥ0x0 ﺗﻨﻔﻴﺬ ﺑﺪءﺍ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ/ ﺑﺖ ﻗﺮﺍءﺓ٣٢ ﻭﺍﺻﻔﺔ ﺍﻟﺸﻔﺮﺓ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ:cs ﺍﳌﺴﺠﻞ •
.0xffffffff
0x0 ﺑﺖ ﻭﺗﺒﺪﺃ ﻣﻦ ﺍﻟﻌﻨﻮﺍﻥ٣٢ ﳚﺐ ﺃﻥ ﺗﻜﻮﻥ ﻣﻘﺎﻃﻊ ﺍﻟﻘﺮﺍءﺓ ﻭﺍﻟﻜﺘﺎﺑﺔ:ds,es,fs,gs,ss ﺍﳌﺴﺠﻼﺕ •
.0xffffffff ﻭﺗﻨﺘﻬﻲ ﺑﺎﻟﻌﻨﻮﺍﻥ
.a20 ﳚﺐ ﺗﻔﻌﻴﻞ ﺑﻮﺍﺑﺔ •
ﳚﺐ ﺃﻥ ﻳﻌﻄﻞ )ﺗﻌﻄﻴﻞ٣١ ﳚﺐ ﺃﻥ ﻳﻔﻌﻞ )ﺗﻔﻌﻴﻞ ﺍﻟﻨﻤﻂ ﺍﳌﺤﻤﻲ( ﻭﺍﻟﺒﺖ0 ﺍﻟﺒﺖ:cr0 ﻣﺴﺠﻞ ﺍﻟﺘﺤﻜﻢ •
.(ﺍﻟﺘﺼﻔﻴﺢ
١٦٨
Physical Memory Management ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ.١.٧
ﻟﺘﺤﺪﻳﺪ ﺍﻟﺒﻴﺎﻧﺎﺕ ﺍﳌﺴﺘﺨﺪﻣﺔ ﰲ ﻫﻴﻜﻠﺔ ﻣﻌﻠﻮﻣﺎﺕ ﺍﻹﻗﻼﻉ ﺍﳌﺘﻌﺪﺩ ﻣﻦ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(;;);
٣٤ }
١٧١
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
٢ #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 ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﻔﻴﺰﻳﺎﺋﻴﺔ.١.٧
١٧٣
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
١٧٤
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;
١٦٤ }
١٦٥
١٧٥
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
١٧٦
Virtual Memory Management ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ.٢.٧
١٧٧
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
٩
١٠ #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
١٧٨
Virtual Memory Management ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ ﺍﻟﺘﺨﻴﻠﻴﺔ.٢.٧
١٧٩
ﺇﺩﺍﺭﺓ ﺍﻟﺬﺍﻛﺮﺓ.٧
٥٠ 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 ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.١.٨
١٨٣
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 ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.١.٨
١٨٥
Device Driver ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ.٨
١٨٦
Keyboard Driver ﺑﺮﳎﺔ ﻣﺸﻐﻞ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ.١.٨
١٨٧
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 ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ.٨
١٩٠
ﺍﳋﺎﲤﺔ
ﻭﻫﻜﺬﺍ ﻧﺼﻞ ﺍﱃ ﺎﻳﺔ ﺍﳌﻄﺎﻑ ﳍﺬﺍ ﺍﻟﺒﺤﺚ ﺍﳌﺘﻮﺍﺿﻊ ﻭﺍﻟﺬﻱ ﻧﺮﺟﻮ ﺃﻥ ﻳﻜﻮﻥ ﺇﺿﺎﻓﺔ ﻭﻟﻮ ﻳﺴﲑﺓ ﻟﻠﻤﻜﺘﺒﺔ ﺍﻟﻌﺮﺑﻴﺔ
ﻭﻟﻠﻘﺎﺭﺉ ﺍﻟﻌﺮﰊ ﰲ ﳎﺎﻝ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ .ﻭﻧﺴﺄﻝ ﺍﷲ ﺗﻌﺎﱃ ﺃﻥ ﻳﻨﻔﻌﻨﺎ ﲟﺎ ﻋﻠﻤﻨﺎ ﻭﺃﻥ ﻳﻨﻔﻊ ﺑﻨﺎ ﺍﻹﺳﻼﻡ
ﻭﺍﳌﺴﻠﻤﲔ ﻭﺃﻥ ﻳﻌﻴﻨﻨﺎ ﻋﻠﻰ ﺗﻌﻠﻢ ﺍﻟﻌﻠﻢ ﻭﺗﺒﻠﻴﻐﻪ ﺍﻧﻪ ﻭﱄ ﺫﻟﻚ ﻭﺍﻟﻘﺎﺩﺭ ﻋﻠﻴﻪ .ﻭﺃﺧﲑﺍ ﻣﺎ ﻛﺎﻥ ﻣﻦ ﺧﻄﺄ ﻓﻤﻦ ﻧﻔﺴﻲ
ﻭﺍﻟﺸﻴﻄﺎﻥ ﻭﻣﺎ ﻛﺎﻥ ﻣﻦ ﺻﻮﺍﺏ ﻓﻤﻦ ﺍﷲ ﻋﺰ ﻭﺟﻞ.
ﻭﺻﻠﻰ ﺍﻟﻠﻬﻢ ﻭﺳﻠﻢ ﻋﻠﻰ ﻧﺒﻴﻨﺎ ﳏﻤﺪ ﻭﻋﻠﻰ ﺁﻟﻪ ﻭﺻﺤﺒﻪ ﺃﲨﻌﲔ .ﻭﺁﺧﺮ ﺩﻋﻮﺍﻧﺎ ﺃﻥ ﺍﳊﻤﺪ ﷲ ﺭﺏ ﺍﻟﻌﺎﳌﲔ.
ﺍﻟﻨﺘﺎﺋﺞ
ﺍﻟﺘﻮﺻﻴﺎﺕ
ﺣﱴ ﻳﺼﻞ ﺍﻟﺒﺤﺚ ﳌﺮﺣﻠﺔ ﻣﻨﺎﺳﺒﺔ ﻓﺎﻧﻪ ﳚﺐ ﺍﳊﺪﻳﺚ ﻋﻦ ﻋﺪﺩﺍ ﻣﻦ ﺍﳌﻮﺿﻴﻊ ﺍﻟﱵ ﰎ ﲡﺎﻫﻠﻬﺎ ﻟﺴﺒﺐ ﺃﻭ ﻵﺧﺮ
،ﻓﺒﺪﺍﻳﺔ ﻣﻦ ﺍﻟﻔﺼﻞ ﺍﻷﻭﻝ ﻭﺍﻟﺬﻱ ﻳﻌﺘﱪ ﻣﻘﺪﻣﺔ ﻋﺎﻣﺔ ﺍﱃ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ ﺣﻴﺚ ﳝﻜﻦ ﺃﻥ ﺗﻀﺎﻑ ﻟﻪ ﺍﻟﻌﺪﻳﺪ
ﻣﻦ ﺍﳌﻌﻠﻮﻣﺎﺕ ﻋﻦ ﺍﻷﻧﻈﻤﺔ ﺍﳊﺎﻟﻴﺔ ﻭﻛﺬﻟﻚ ﻣﺰﻳﺪﺍ ﻣﻦ ﺍﻟﺘﻮﺿﻴﺤﺎﺕ ﻋﻦ ﻣﺎﻫﻴﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ .ﺃﻣﺎ ﺍﻟﻔﺼﻞ
ﺍﻟﺜﺎﱐ ﻓﻠﻢ ﻳﺘﺤﺪﺙ ﺳﻮﻯ ﻋﻦ ﺍﻟﻘﺸﻮﺭ ﰲ ﻣﻌﻤﺎﺭﻳﺔ ﺍﳊﺎﺳﺐ ﺣﻴﺚ ﺃﻧﻪ ﻳﺘﻄﻠﺐ ﻛﺘﺎﺑﺎ ﻣﺘﻜﺎﻣﻼ ﻟﺸﺮﺡ ﻛﻞ ﺟﺰﺋﻴﺔ
ﻭﻟﻜﻦ ﰎ ﺍﻹﳚﺎﺯ ﻭﺍﳊﺪﻳﺚ ﻋﻦ ﺍﳌﻮﺍﺿﻴﻊ ﺍﻟﱵ ﻳﻜﺜﺮ ﺗﻨﺎﻭﳍﺎ ﻋﻨﺪ ﺑﺮﳎﺔ ﺃﻧﻈﻤﺔ ﺍﻟﺘﺸﻐﻴﻞ .ﻭﻗﺒﻞ ﺍﻹﻧﺘﻘﺎﻝ ﺍﱃ ﺍﻟﻔﺼﻞ
ﺍﻟﺜﺎﻟﺚ ﳝﻜﻦ ﻛﺘﺎﺑﺔ ﻓﺼﻞ ﺟﺪﻳﺪ ﻋﻦ ﻟﻐﺔ ﺍﻟﺘﺠﻤﻴﻊ ﲝﻴﺚ ﻳﺸﺮﺡ ﺃﺳﺎﺳﻴﺎﺕ ﺍﻟﻠﻐﺔ ﻣﻊ ﻣﺘﺮﺟﻢ NASMﻻﻧﻪ ﺍﳌﺘﺮﺟﻢ
ﺍﳌﺴﺘﺨﺪﻡ ﰲ ﻋﻤﻠﻴﺔ ﲡﻤﻴﻊ ﺍﻟﱪﺍﻣﺞ ﺣﻴﺚ ﺃﻧﻪ ﳛﻮﻱ ﺃﻭﺍﻣﺮ ﺧﺎﺻﺔ ﺑﻪ ﳚﺐ ﺍﻟﻮﻗﻮﻑ ﻋﻨﺪﻫﺎ ﻭﺗﻮﺿﻴﺤﻬﺎ ﺑﺸﻜﻞ
ﺟﻴﺪ .ﺃﻣﺎ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﻟﺚ ﻭﺍﻟﺮﺍﺑﻊ ﻓﺘﻢ ﺍﳊﺪﻳﺚ ﻓﻴﻬﺎ ﻋﻦ ﳏﻤﻞ ﺍﻟﻨﻈﺎﻡ ﺍﻟﺬﻱ ﰎ ﺑﺮﳎﺘﻪ ﻟﺘﺤﻤﻴﻞ ﻧﻈﺎﻡ ﺇﻗﺮﺃ ﻭﳝﻜﻦ
ﻫﻨﺎ ﺍﳊﺪﻳﺚ ﻋﻦ ﺃﻱ ﻣﻦ ﺍﳌﺤﻤﻼﺕ ﺍﳌﻔﺘﻮﺣﺔ ﺍﳌﺼﺪﺭ )ﻣﺜﻞ ﳏﻤﻞ GRUBﻭﺍﻟﺬﻱ ﻳﻌﺘﱪ ﻣﻦ ﺃﺷﻬﺮ ﺍﳌﺤﻤﻼﺕ
ﻭﺃﻛﺜﺮﻫﻢ ﺍﺳﺘﺨﺪﺍﻣﺎ( ﻭﻛﻴﻔﻴﺔ ﲢﻤﻴﻞ ﻧﻮﺍﺓ ﺍﻟﻨﻈﺎﻡ ﻣﺒﺎﺷﺮﺓ ﻣﻦ ﺧﻼﳍﻢ .ﻭﺍﻟﻔﺼﻞ ﺍﳋﺎﻣﺲ ﲢﺪﺙ ﻋﻦ ﺍﻟﻨﻮﺍﺓ ﻭﻃﺮﻕ
ﺗﺼﻤﻴﻤﻬﺎ ﺑﺸﻜﻞ ﳐﺘﺼﺮ ﻭﱂ ﻳﺘﻨﺎﻭﻝ ﺍﻻﺧﺘﻼﻑ ﺑﻴﻨﻬﻢ ﻭﻃﺮﻕ ﺑﺮﳎﺔ ﻛﻞ ﻣﻨﻬﻢ ﻋﻠﻰ ﺣﺪﺓ ﻭﻳﻌﺘﱪ ﻫﺬﺍ ﺍﻟﻔﺼﻞ ﳎﺎﻻ
ﻛﺎﻣﻼ ﻟﻠﺒﺤﺚ ﻓﻴﻪ .ﺃﻣﺎ ﺍﻟﻔﺼﻞ ﺍﻟﺴﺎﺩﺱ ﻓﻬﻮ ﻣﻜﺘﻤﻞ ﺗﻘﺮﻳﺒﺎ ﻭﳝﻜﻦ ﺍﺿﺎﻓﺔ ﺍﳌﺰﻳﺪ ﻣﻦ ﺍﻟﻌﻠﻮﻣﺎﺕ ،ﺑﻴﻨﻤﺎ ﺍﻟﻔﺼﻞ
ﺍﻟﺴﺎﺑﻊ ﱂ ﻳﺘﺤﺪﺙ ﻋﻦ ﺧﻮﺍﺭﺯﻣﻴﺎﺕ ﺍﺩﺭﺍﺓ ﺍﻟﺬﺍﻛﺮﺓ ﻭﰎ ﺗﻄﺒﻴﻖ ﺧﻮﺍﺭﺯﻣﻴﺔ First Fitﻟﻠﺒﺤﺚ ﻋﻦ ﺃﻣﺎﻛﻦ ﺷﺎﻏﺮﺓ
ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﻭﳝﻜﻦ ﺗﻄﺒﻴﻖ ﺃﻱ ﻣﻦ ﺍﳋﻮﺍﺭﺯﻣﻴﺎﺕ ﺍﻟﺸﻬﲑﺓ ،ﻛﺬﻟﻚ ﳝﻜﻦ ﺗﻄﺒﻴﻖ ﺍﻟﻘﺎﺋﻤﺔ ﺍﳌﺘﺼﻠﺔ ﳌﺘﺎﺑﻌﺔ ﺍﻷﻣﺎﻛﻦ
ﺍﻟﺸﺎﻏﺮﺓ ﰲ ﺍﻟﺬﺍﻛﺮﺓ ﺑﺪﻻ ﻣﻦ ﺍﺳﺘﺨﺪﺍﻡ .Bit Mapﺃﻣﺎ ﺍﻟﻔﺼﻞ ﺍﻟﺜﺎﻣﻦ ﻓﻬﻮ ﻋﻦ ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ ﻟﻜﻦ ﻧﻈﺮﺍ
ﻟﻀﻴﻖ ﺍﻟﻮﻗﺖ ﻓﻘﺪ ﰎ ﺍﳊﺪﻳﺚ ﻋﻦ ﻣﺘﺤﻜﻢ ﻟﻮﺣﺔ ﺍﳌﻔﺎﺗﻴﺢ ﻭﻛﻴﻔﻴﺔ ﻗﺮﺍءﺓ ﺍﻷﺣﺮﻑ ﺍﳌﺪﺧﻠﺔ ﻣﻨﻪ ،ﻭﳝﻜﻦ ﰲ ﻫﺬﺍ
ﺍﻟﻔﺼﻞ ﺍﺿﺎﻓﺔ ﺍﻟﻌﺪﻳﺪ ﻣﻦ ﻣﺸﻐﻼﺕ ﺍﻷﺟﻬﺰﺓ ﻣﺜﻞ ﻣﺸﻐﻞ ﺍﻟﻘﺮﺹ ﺍﳌﺮﻥ ﻭﺍﻟﻘﺮﺹ ﺍﻟﺼﻠﺐ ﻭﻣﺸﻐﻞ ﻟﻜﺮﺕ ﺍﻟﺸﺒﻜﺔ
١٩١
Device Driver .٨ﻣﺸﻐﻼﺕ ﺍﻻﺟﻬﺰﺓ
ﻭﻛﺮﺕ ﺍﻟﺼﻮﺕ ﻭﺍﻟﻌﺪﻳﺪ ﻣﻦ ﺍﳌﺸﻐﻼﺕ ﺍﻟﻀﺮﻭﺭﻳﺔ .ﺃﺧﲑﺍ ﳝﻜﻦ ﺇﺿﺎﻓﺔ ﻓﺼﻞ ﻟﻠﺤﺪﻳﺚ ﻋﻦ ﺃﻧﻈﻤﺔ ﺍﳌﻠﻔﺎﺕ
ﻭﻛﻴﻔﻴﺔ ﺑﺮﳎﺘﻬﻢ ﻣﺜﻞ FAT12,FAT16,FAT32,EXT3,EXT4,...etcﻭﻓﺼﻞ ﻟﱪﳎﺔ ﺍﳌﺠﺪﻭﻝ ﻟﺪﻋﻢ ﺗﻌﺪﺩ ﺍﳌﻬﺎﻡ.
١٩٢
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.
[٥] 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 Developer's Manuals. http:
//www.intel.com/products/processor/manuals/
١٩٣
ﺍ .ﺗﺮﲨﺔ ﻭﺗﺸﻐﻴﻞ ﺍﻟﱪﺍﻣﺞ
ﻟﺘﻄﻮﻳﺮ ﻧﻈﺎﻡ ﺍﻟﺘﺸﻐﻴﻞ ﳚﺐ ﺍﺳﺘﺨﺪﺍﻡ ﳎﻤﻮﻋﺔ ﻣﻦ ﺍﻻﺩﻭﺍﺕ ﻭﺍﻟﻠﻐﺎﺕ ﺍﻟﱵ ﺗﺴﺎﻋﺪ ﻭﺗﻴﺴﲑ ﻋﻤﻠﻴﺔ ﺍﻟﺘﻄﻮﻳﺮ ﻭﰲ ﻫﺬﺍ
ﺍﻟﻔﺼﻞ ﺳﻴﺘﻢ ﻋﺮﺽ ﻫﺬﻩ ﺍﻷﺩﻭﺍﺕ ﻭﻛﻴﻔﻴﺔ ﺍﺳﺘﺨﺪﺍﻣﻬﺎ.
ﺍﻋﺪﺍﺩ ﻣﺘﺮﺟﻢ ﻓﻴﺠﻮﺍﻝ ﺳﻲ ++ﻟﱪﳎﺔ ﺍﻟﻨﻮﺍﺓ.
١٩٥
ﺏ .ﺷﻔﺮﺓ ﻧﻈﺎﻡ ﺇﻗﺮﺃ
ﻛﻮﺩ ﺍﻟﻨﻈﺎﻡ
١٩٧