Mikä on suojattu tila ja minkä kanssa sitä syödään. Intel-prosessorien vaihtaminen suojattuun tilaan Siirtyminen suojatun tilan kokoonpanijaan

rPUME OEDEMSHOPZP RETETSHCHB CHOPCHSH NPZH PVTBPCHBFSH CHBU OPCHSHCHN CHSHCHHRHULPN UCHPEK TBUUSCHMLY.

yFBL, LBL CHSH RPNOYFE, H TEBMShOPN TETSYNE TBVPFSCH RTPGEUUPTB OBN DPUFKHREO CHUEZP MYYSH 1 NEZBVBKF BDTEUOPZP RTPUFTBOUFCHB (Yb LPFCHPTSCHI PVSHCHUOPK CHFSHUPLY4MSEFUSYSYSH). fBL LFP Y VSHMP CHP LUKEMINEN RETCHSHCHI RTPGEUUPTPCH CHTPDE 8086, OP RPUFEREOOOP PVYaЈNB PRETBFICHOPK RBNSFY UFBMP OE ICHBFBFSH. h FP TSE CHTENS FTEVPCHBMPUSH UPITBOYFSH RPMOHA PVTBFOHA UPCNEUFYNPUFSH, UFPVShch 16-TBTSDOSCHHE PRETBGYPOOSCHE UYUFENSCH CHTPDE DOS UNPZMY OPTNBMSSHOP TBVPFBFSH. rPFPNKh VSCHM CHCHEDIO OPCHSHCHK TETSYN TBVPFSCH RPGEUUPTB - BEEYEIIOOSCHK TETSYN. rPUME RETEIPDB CH OEZP DMS BDTEUBGYY YURPMSHHEFUS OE 16, B 32 YMY DBTSE 64 VYFB, B UEZNEOFSHCH UFBTPN RPOINBOY YUYUEBAF. fBLCE DPVBCHMSAFUS BEIFOSCHE NEIBOYNSCH (YNEOOP RPFPNH BEEYEIIOOSCHK TETSYN), UFPVShch SDTP pu VShchMP YЪPMYTPCHBOOP PF RTYMPTSEOIK Y NPZMP YNY UCHPVPDOP HRTBCHMSFSH. sFP OEVPVIPDYNP MAVPK RPMOPGEOOPK NOPZPЪBDBYuOPK UYUFENE.

оБЮОЈН У ФПЗП, ЮФП ДПВБЧМСЕФУС Ч ТЕБМШОПН ТЕЦЙНЕ ОБ РТПГЕУУПТБИ, ЛПФПТЩЕ РПДДЕТЦЙЧБАФ 32-ВЙФОЩК БДТЕУ (i386 Й ЧЩЫЕ) - ДПВБЧМСАФУС ОПЧЩЕ ТЕЗЙУФТЩ, ЧЕТОЕЕ ТБУЫЙТСАФУС УФБТЩЕ: EAX, EBX, ECX, EDX, ESP, EBP, EIP, ESI, EDI, LIPUT. LBL NPTsOP DPZBDBFSHUS, LFP 32-VYFOSHCHE CHETUYY PVSCHYUOSCHI TEZYUFTCH TEBMSHOPZP TETSYNB (L YNEOY TEZYUFTB DPVBCHMSEFUS RTYUFBCHLB "E"). CHUE LFY 32-VYFOSHCHE TEZYUFTSHCH LTPNE EIP DPUFKHROSCH Y CH TEBMSHOPN TETSYNE, OP CH FBLPN UMHYUBE VHDHF OBOYNBFSH OB 1 VBKF VPMSHYE (LEYN DPVBCHMSEFUS UREGYB). Tietoja RTPGEUUPTE NPMPTS 286 FY LPNBODSCH VHDHF OELPTTELFOSCH. nSch NPTSEN, OBRTYNET, OBRYUBFSH mov eax, 0x12345678 Y RPUME LFPZP H AX VKhDEF 0x5678, RPFPNH UFP ON LBL VSCHMSEFUS "PLOPN" H NMBDYHA YUBUFSH TEZYBOUFTBYAXYBOUFTBYAXY, E. тЕЗЙУФТБ-ПФПВТБЦЕОЙС УФБТЫЕК ЮБУФЙ 32-ВЙФОЩИ ТЕЗЙУФТПЧ ОЕ УХЭЕУФЧХЕФ - НПЦОП ЕЈ ЙЪЧМЕЮШ ФПМШЛП У РПНПЭША БТЙЖНЕФЙЛЙ (ОБРТЙНЕТ, УДЧЙОХФШ EAX ОБ 16 ВЙФ ЧРТБЧП У РПНПЭША shr eax, 16, ФПЗДБ Ч AX ВХДЕФ УФБТЫБС РПМПЧЙОБ, ОП УПДЕТЦЙНПЕ НМБДЫЙИ ВЙФ ВХДЕФ ХФЕТСОП). юФП ИБТБЛФЕТОП, Ч ЪБЭЙЭЈООПН ТЕЦЙНЕ ОБПВПТПФ, ЛПНБОДЩ ТБВПФЩ У 16-ВЙФОЩНЙ ТЕЗЙУФТБНЙ (ОП ОЕ 8-ВЙФОЩНЙ) ФТЕВХАФ РТЕЖЙЛУ, РПЬФПНХ ОЕУНПФТС ОБ ФП, ЮФП ТБЪТСДОПУФШ Ч ДЧБ ТБЪБ ВПМШЫЕ, Ч ЪБЭЙЭЈООПН ТЕЦЙНЕ ВЩУФТЕЕ ЧЩРПМОСАФУС Й ЪБОЙНБАФ НЕОШЫЕ НЕУФБ ЙНЕООП ЛПНБОДЩ 32- VYFOPC BTYZHNEFILY.

fBLCE, FERETSCH H OBU OB 2 UEZNEOFOSHCHI TEZYUFTB VPMSHIE - GS TH FS. TBVPFB U ONYY RPMOPUFSHHA BOBMPZYUOB DS Y ES Y CH NPTSEFE YI UCHPPVPDOP YURPMSHЪPCHBFSH CH TEBMSHOPN TETSYNE. пФМЙЮЙЕ ФПМШЛП Ч ФПН, ЮФП ОЙЛБЛЙЕ ЛПНБОДЩ ЙИ СЧОП ОЕ РПДТБЪХНЕЧБАФ (DS ЙУРПМШЪХЕФУС РП ХНПМЮБОЙА РТБЛФЙЮЕУЛЙ ЧУЕНЙ ЛПНБОДБНЙ Й ОЕЛПФПТЩНЙ УФТПЛПЧЩНЙ ПРЕТБГЙСНЙ, ES ОЕЛПФПТЩНЙ УФТПЛПЧЩНЙ ПРЕТБГЙСНЙ) Й ОБДП СЧОП ХЛБЪЩЧБФШ, ЮФП ЧЩ ИПФЙФЕ ПВТБЭБФШУС ЮЕТЕЪ ОЙИ. BRIGHTNET, mov ax, .

rPNYNP LFPZP TBUYTEOYS TEZYUFTCH, DPVBCHMSAFUS OPCHSHCHE HRTBCHMSAEIE TEZYUFTSHCH (TBOSHIE CHMYSM TIETOJA TETSYN TBVPFSCH RTPGEUUPTB FPMSHLP FLAGS) - CR0, CR2, CR3 TH CR4. EUFSH Y DTHZYE (OBRTYNET, PFMBDPYUOSCHE TEZYUFTSHCH), OP POY OBU UEKYUBU OE YOFETEUKHAF. yNEOOP U RPNPESHA LFYI TEZYUFTCH RTPYJCHPDYFUS RETELMAYUEOYE RTPGEUUPTB H BEEYEIOOOSCHK TETSYN Y OBUFTPKLB OPCHSCHI ZHHOLGYK CHTPDE UFTBOYUOPK BDTEUBGYY. laula DPUFKHROSCH CH TEBMSHOPN TETSYNE.

h ЪBEEIЈOOPN TETSYNE RPOSFIE UEZNEOFB YЪNEOSEFUS. FERETSH FP OE RTPUFP VBPCHSHCHK BDTEU, B OPNET LMENEOFB (DEULTYRFPTB UEZNEOFB) CH UREGIBMSHOPK FBVMYGE. fBVMYGB DEULTYRFPTPCH UEZNEOPFCH UPDBЈFUS PRETBGYPOOPK UYUFENPK Y NPTCEF UPDETTSBFSH OEPVIPDYNPE LPMYUEUFCHP PRYUBOYK UEZNEOPPCH ЪBEYEIIOOPZP TETSYNB. LBCDShCHK LMENEOF FBVMYGSHCH BOINBEF 8 VBKF Y CH UREGIBMSHOPN ZHPTNBFE PRYUSCHCHBEF VBPCHSCHK BDTEU UEZNEOFB, TBNET, RTBCHB DPUFHRB Y F.D.

UEZNEOFSCH BEEIEIIOOPZP TETSYNB DEMSFUS TIETOJA DCHB FIRB:stä - UEZNEOFSC LPDB Y UEZNEOFSC DBOOSCHI (TIETOJA UBNPN DEME EUFSH EEI CHUSLYE TSS Y LDT, OP RPLB SING OBNO OE CHBTSOSH FPTS). h CS NPTsOP ЪBZTHTSBFSH FPMSHLP OPNETB DEULTYRFPTPCH, PRYUBOOSHCHI LBL UEZNEOF LPDB, Ch PUFBMSHOSHCHE UEZNEOFOSHCHE TEZYUFTSH NPTsOP ЪBZTHTSBFSH MAVSHE BBLNEOF BLOOSCH, FPMSHLP BEBLNEOF SHOP. CHBTSOBS TBOYGB CH FPN, YuFP UEZNEOF LPDB NPTsOP FPMSHLP YUYFBFSH Y YURPMOSFSH, B UEZNEOF DBOOSCHI FPMSHLP YUYFBFSH Y RYUBFSH. L Uyubufsha, ueresenofsh NPZHF RETELTSHCHSHS CH RBNSFY, RPFPNH UPDSOPPSHE DELTRFPTB Dultirfptb, Ushchmbaeus noin SAN FPF TEZIPO RBNSPHA, OPEI Oydbfsh yurpynchenshn.

oEUNPFTS TIETOJA RPDDETZLH UEZNEOFBGYY:stä, POB UYUYFBEFUS HUFBTECHYEK. oh Windows, oh Linux OE YURPMSHHAF EE H RPMOPC NO, B OB PFMYUOSCHI PF x86 BTIYFELFHTSHCH (OBRTYNET, ARM) PB MITÄ FUHFUFFCHHEF. DMS TBZTBOYUEOIS DPUFHRB L RBNSFY YURPMSH'HEFUS ZPTBDDP VPMEE ZYVLYK NEIBOYN UFTBOYUOPK BDTEUBGYY, LPFPTSCHK NSC TBUUNPFTYN DBMEE. YuFPVSCH YUVBCHIFSHUS PF UEZNEOFBGYY PU RTPUFP PRIUSHCHBEF FBVMIGH YU DULTIRFPPCH, X LBCDPZP YH LPFPSHSHK BDTEU 0, B TBIPHK RBNSTEPHEPHEPHEPHP h FBLPN UMHYUBE ZPCHPTSF, YuFP NSCH CHLMAYUYMY TETSYN MYOEKOSHCHI BDTEUPCH - UNEEEOYE UPPFFCHEFUFCHHEF ZHYYYYUEULPNH BDTEUKH. FP PYUEOSH KDPVOP Y S RPKDH RP FPNKh CE RHFY. оЕ УМЕДХЕФ РЩФБФШУС ЙУРПМШЪПЧБФШ УЕЗНЕОФБГЙА Ч УЧПЕК ПРЕТБГЙПООПК УЙУФЕНЕ - ЬФП УЙМШОП ХУМПЦОСЕФ ЛПД СДТБ, СЪЩЛЙ ЧЩУПЛПЗП ХТПЧОС (ОБРТЙНЕТ, у ЙМЙ у++) ОЕ РПДДЕТЦЙЧБАФ УЕЗНЕОФБГЙА (ФП ЕУФШ ЧЩ УНПЦЕФЕ РПМОПГЕООП РТПЗТБННЙТПЧБФШ ФПМШЛП ОБ Assembler) Й, ОБЛПОЕГ, ЧЩ ОЕ УНПЦЕФЕ РЕТЕОЕУФЙ УЙУФЕНХ ОБ ДТХЗХА БТИЙФЕЛФХТХ, РПФПНХ ЮФП x86 ЕДЙОУФЧЕООБС, ЛПФПТБС ХНЕЕФ ЬФПФ НЕИБОЙЪН (Й ФП, Ч 64-ВЙФОПН ТЕЦЙНЕ РПМС ВБЪПЧПЗП БДТЕУБ Й ТБЪНЕТБ УЕЗНЕОФБ ЙЗОПТЙТХАФУС, Б ЙУРПМШЪХЕФУС МЙЫШ ЙОЖПТНБГЙС П РТБЧБИ ДПУФХРБ).

LBL S HCE ULBBM, FBVMYGB DEULTYRFPTPCH UEZNEOPHFCH ZHPTNYTHEFUS UBNPK PRETBGYPOOPK UYUFENPC. uFPVSC HLBBFSH RPGEUUPTH, ZDE POB OBIPDIFUS YURPMSHHEFUUS UREGYBMSHOBS LPNBODB - lgdt (Lataa yleiskuvaustaulukko). SY. RTYOYNBEF 6-VBKFPCHHA RETENEOHA CH RBNSFY. рЕТЧЩЕ ЕЈ 16 ВЙФ УПДЕТЦБФ ТБЪНЕТ ФБВМЙГЩ Ч ВБКФБИ (ФБЛЙН ПВТБЪПН, НБЛУЙНБМШОПЕ ЛПМЙЮЕУФЧП ДЕУЛТЙРФПТПЧ - 65536 / 8 = 8192), РПУМЕДХАЭЙЕ 32 ВЙФБ - ВБЪПЧЩК МЙОЕКОЩК БДТЕУ Ч РБНСФЙ УБНПК ФБВМЙГЩ (ФП ЕУФШ ВЕЪ ХЮЈФБ ЧУЕИ УЕЗНЕОФПЧ). yNEEF UNSCHUM CHSHCHTBCHOSFSH OBYUBMP FBVMYGSHCH OB 16 VBKF, RPFPNKh YUFP LFP HMHYUYBEF ULTPUFSH DPUFHRB L EY EMENEOFBN. RETCHSHCHK LMENEOF FBVMYGSHCH CHUEZDB DPMTSEO VSHCHFSH TBCHEO OHMA Y MAVPE YURPMSHCHCHBOYE OHMECHPZP UEMELFPTB(HLBBFEMSH TIETOJA MENEOF FBVMYGSCH DEULTYRFPTPCH CH UEZNEOFOPN TEZYUFTE OBSCCHCHBEFUS FBL) RTYCHPDYF L PYYVLE. OBYUYF VPMEE-NEOE TBVPFPPURPUPVOBS FBVMYGB DEULTYRFPTPCH DPMTSOB UPDETTSBFSH IPFS VSC FTY DEULTYRFPTTB - RHUFPK, DEULTYRFPT LPDB, DEULTYRFPT DBOOSCHI.

OH UFP EEJ UFPYF TBUULBЪBFSH, RTETSDE, YUEN NSCH RPRTPVKHEN RETEKFI CH ЪBEIEIIOOSCHK TETSYN? RPTsBMHK, EEI UFPYF HRPNSOHFSH RTP HTPCHOY DPUFHRB. LPD SDTB UYUFENSCH Y LPD RTYMPTSEOYK PFDEMEOSCH DTHZ PF DTHZB U FPK GEMSHHA, YuFPVSHCH SDTP NPZMP RPMOPUFSHA HRTBCHMSFSH RTPGEUUPTPN, B RTYMPTSEOIS HTYMPTSEOYK PFDEMEOSCH DTHZ PF DTHZB U FPK GEMSHHA. LPD YURPMOSEFUS U PRTEDEMIOOSCHN HTPCHOYEN RTYCHYMEZYK. h x86 YI GEMSHI 4 YFKHLY - PF 0 DP 3. OHMECHPK HTPCHEOSH UBNSCHK RTYCHYMEZYTPCHBOOSCHK (NPCEF CHSHCHRPMOSFSH MAVSHE LPNBODSCH Y NEOSFSH TETSYNSCH TBVPFSCH RTBCEFPGEUUPKTB), LBB Comkhuba osoitteessa Uerezneoofbgyek, TBTBPFULY X86 RETEVPTAMYA osoitteessa Zholgypobmpn Yurpmshkhaf MYYSHA HTPCHOS YUEFSHTSHIEYA, BTIZYEEPHTHPHPHPHTHPHPHTHPHTHPHTHPHTHPHTHPHTHBB FPPHPHBAPHBAPHBAPHULBEUTBFPTBEUTBFPPFEUPPHULTBUPTB FPPHEUPPUPP x LBTsDPZP UEZNEOFB MVA EZP DEULTYRFPTE HLBBO DPL (Descriptor privilege level)- HTPCHEOSH DPUFHRB OEPVIPDYNSCHK DMS DBOOPZP UEZNEOFB. oERTYCHYMEZYTPCHBOOSCHK LPD OE NPTCEF RPMHYUYFSH DPUFHR L UEZNEOPH U HTPCHOYEN DPUFHRB 0, B RTYCHYMEZYTPCHBOOSCHK LPD NPTCEF RPMHYUYFSH DPUFHR LP CHUEN UEZNEOFBN.

уЕМЕЛФПТ УЕЗНЕОФБ, ЛПФПТЩК УПДЕТЦЙФУС Ч УЕЗНЕОФОПН ТЕЗЙУФТЕ, СЧМСЕФУС ОЕ РТПУФП ОПНЕТПН ЬМЕНЕОФБ Ч ФБВМЙГЕ, ОП Й ХЛБЪБФЕМЕН ХТПЧОС ДПУФХРБ - НМБДЫЙЕ 2 ВЙФБ УПДЕТЦБФ ХТПЧЕОШ РТЙЧЙМЕЗЙК (ПФ 0 ДП 3), Б ХЦЕ УФБТЫЙЕ ОПНЕТ УБНПК ФБВМЙГЩ. fBLYN PVBPN UEMELFPT = (YODELU_DEULTYRFPTB shl 2) + RPL. RPL- Pyydetty etuoikeustaso - RTY LFPN RPL DPMCEO VSCFS VPMSHY YMY TBCHEO NBLUINBMSHOPNH Ъ DPL й CPL (nykyinen käyttöoikeustaso). CPL TBCHEO RPL UEMELFPTB H CS. fBLYN PVTBBPN LPD OE NPTCEF RPMKHYuYFSH DPUFHRB L UEZNEOFBN, H LPFPTSCHI HTPCHEOSH DPUFHRB CH YUYUMPCHPN CHYDE OYCE, YUEN X OEZP UBNPZP. s, CHETPSFOP, PRIUBM DPUFBFPYuOP BRHFBOOP, OP CHRPMOE NPTsOP PVPKFYUSH RPL = DPL, LBL NSCH Y RPUFHRIN.

rPLB NSC RYYEN FPMSHLP SDTP, NSC VKHDEN TBVPFBFSH CH OKHMECHPN LPMShGE BEIFSHCH (FBL EEI OBSCCHBAF HTPCHOY RTYCHYMEZYK), YUFPVSH YNEFSH RPMOSHK DPUFHR L BRRBTBFKhTE.

UEZNEOFBGYS OBN O OHTSOB, RPFPNKH S OE VKHDH PUFBOBCHMYCHBFSHUS RPLB UFP TIETOJA ZHPTNBFE DEULTYRFPTB, B DBN ZPFPCHSHCHE OBBYUEOYS. eUMY YOFETEUOP, NPTSEFE RPYUYFBFSH LFH UFBFSHHA. tBUUNPFTYN RTPUFEKYYK LPD RETEIPDB CH ЪBEYEIIOOSCHK TETSYN.

; bBRHUL 32-TBTSDOPZP SDTB.start32: ; WHCHCHPDYN HCHEDPNMEOYE P BRHULE 32-VYFOPZP SDTB mov si, start32_msg call write_str ; bztkhjn bobyueoye h GDTR lgdt ; bBRTEFYN RTETSHCHCHBOYS cli ; RETEKDYN H BEEYEIIOOSCHK TEZYN mov eax, cr0 tai eax, 1 mov cr0, eax ; RETEKDIN TIETOJA 32-VYFOSHK LPD jmp 8: start32 ; fBVMYGB DEULTYRFPTPCH UEZNEOPFC DMS 32-VYFOPZP SDTB kohdistus 16 gdt32: dq 0; NULL - 0 dq 0x00CF9A000000FFFF ; KOODI - 8dq 0x00CF92000000FFFF ; TIEDOT - 16 gdtr32: dw $ - gdt32 - 1 dd gdt32 ; 32-VYFOSHK LPD käyttö32 aloitus32: ; mov eax, 16 mov ds, axe mov es, ax mov fs, ax mov gs, ax mov ss, ax movzx esp, sp ; WHCHCHPDYN UYNCHPM TIETOJA LLTBO:sta mov byte, "!" ; jmp $

FFPF LPD UMEDHEF DPRYUBFSH L

рЕТЕД РЕТЕИПДПН Ч ЪБЭЙЭЈООЩК ТЕЦЙН ОЕПВИПДЙНП ЪБРТЕФЙФШ РТЙЈН БРРБТБФОЩИ РТЕТЩЧБОЙК (ЛМБЧЙБФХТБ, НЩЫШ, ФБКНЕТ Й ДТХЗЙЕ ХУФТПКУФЧБ), РПФПНХ ЮФП BIOS РПУМЕ РЕТЕИПДБ ПУФБЈФУС ОЕ Х ДЕМ, Б УЧПЙ ПВТБВПФЮЙЛЙ НЩ ЕЭЈ ОЕ ОБРЙУБМЙ, РПЬФПНХ РЕТЧПЕ ЦЕ РТЕТЩЧБОЙЕ ПВТХЫЙФ УЙУФЕНХ.

oERPUTEDUFHEOOP RETEIPD H ЪBEYEIIOOSCHK TETSIN PUKHEEUFCHMSEF HUFBOPCHLB OHMECHPZP VYFB CH CR0. yNEOOP LFP NSCH Y DEMBEN (RTSNPC DPUFKhR L CR0,2,3,4 OECHPЪNPTSEO FBL TSE LBL Y L UEZNEOFOSHCHN TEZYUFTBN, RPFPNKh YURPMSHEKHEN EAX). oEUNPFTS OB FP, UFP NSC HCE RETEYMY MVA BEEIEIOOSHCHK TETSIN, LPD RTPDPMTSBEF YURPMOSFSHUS RP-RTETSOENH 16-VYFOSHCHK. dms dYTELFYCHB BUUENVMETB use32 ZPCHPTYF ENH, UFP DBMSHOEKYK LPD CHSHCHRPMOSEFUS CH ЪBEEIЈOOPN TETSYNE Y OEVPVIPDYNP RETELMAYUYFSHUS CH TETSYN ZEOETBGYY LPNBVOD OPHOPPZZYPPHOPPZ6, BNBVOD DMS OEZPEPZ6

lPNBODB movzx TBUYTSEF CHFPTPK BTZHNEOF DP RETCHPZP. h UNSHUME, YUFP YЪ 16 VYFOPZP OBBYUEOYS SP RPMHYUBEFUS 32-VYFOPE. uFBTYYE VYFSCH PVOHMSAFUS (NBMP MY, UFP FBN VSCHMP DP OBU). m CH RTBCHSHCHK OYTSOYK HZPM LTBOB (FELUFPCHSCHK LTBO YNEEF TBTEYOYE 80 x 25 Uinchpmch, LBCDShCHK UINCHPM BOINBEF CH RBNSFY DCHB VBKFB - LPD UINCHPMB Y EZP BFTYVHFSHCH).

NSC VPMSHIE OE NPTSEN PVTBEBFSHUS L UETCHYUBN BIOS, FERETSH RTYYMP CHTENS OBN UFBFSH RPMOPUFSHHA UBNPUFPSFEMSHOSHCHNY Y UBNYN HRTBCHMSFSH CHUEN PVPTKHDPCHBOYEN. RETEBZTHTSBFSHUS Y TsDBFSH OBTSBFYS TIETOJA LMBCHYYH NSC RPLB OE HNEEN, RPFPPNKh RTPUFP ЪBCHYUBEN U RPNPESHA LPNBODSCH jmp $ (RETEIPD TIETOJA FX CE UBNHA LPNHA LPULPOLMEYSCH - VELKULPODODHISTA).

h YLEINEN boot.cfg LPNBODH S64 RPLB JBNEOIN OB S32. FERETSH, EUMY CHSHCHUY RTBCHYMSHOP UDEMBMY, OBY ЪBZTKHYUYL VKHDEF ЪBCHETYBFSH UCHPA TBVPFKH CHSHCHCHPDPN ChPULMYGBFEMSHOPZP ЪOBLB MVA KhZPM LTBOB TTOBZBETSYЪNB. FP FPMSHLP OBUBMP. NS OBLPOEG-FP RTBLFYUEULY KHYMYY YЪ TEBMSHOPZP TETSYNB (ON UBNPN DEME FBN EEI PUFBMPUSH OENPZP DEM) H BEEYEIIOOSCHK. Rpulpmshlh CHABZTHYUILEL CHCHRPMOSEFUS chMECHENEOFE TEBMshopzp Tekinb, Chueeoeeois Uppeffchhaf Zhyryotyipda Chuyoshchk Tsin, Oyuyuzp.

h ЪBCHETEOYE CHSHCHHRULB, RPTsBMHK, DPVBCHMA RPUMEDOYK YFTYI - RTPCHETLKH, UFP RTPGEUUPT RPDDETSYCHBEF ЪBEIEIIOOSCHK TETSYN. UHFSH RTPCHETLY CH FPN, UFP OE CHUE VYFSCH FLAGS NPTsOP YЪNEOYFSH RTPZTBNNOP. FP EUFSH TEZYUFT OE UPCHUEN 16-VYFOSHCHK. TIETOJA OPCHSCHI RTPGEUUPTBI DPUFHROP DMS YNEOEOYS VPMSHIE VYF Y FP NPTsOP PVOBTHTSYFSH. TBVETYFE LPD OYCE UBNY, ULBTSH FPMSHLP, UFP LPNBODB pushf RPNEEBEF TEZYUFT ZHMBZPCH H UFEL, B popf CCHHFBMLYCHBEF UPDETSYNPE UFELP PE FLAGS. fBLYN PVTBYPN EZP NPTsOP NEOSFSH GEMILPN, BOE PFDEMSHOSHCHNY LPNBODBNY. CHPF RPMOSHCHK LPD OBYEZP ЪBZTKHYULB:

Org 0x7C00 jmp boot ; bZPMCHPL ListFS align 4 fs_magic dd ? fs_version dd? fs_flags dd ? fs_base dq? fs_size dq? fs_map_base dq? fs_map_size dq ? fs_first_file dq? fs_uid dq? fs_block_size dd ? ; bZPMCHPL JBKMB virtuaalinen 0x800 f_info: f_name rb 256 f_next dq ? f_prev dq ? f_parent dq ? f_flags dq ? f_data dq? f_size dq? f_ctime dq? f_mtime dq? f_atime dq? endvirtuaali; DBOOSH OBJUBMSHOPZP JBZTHYULB otsikko sektorin_raitaa kohden sana $$ otsikko head_count tavu $$ + 2 nimike disk_id tavu $$ + 3 reboot_msg db "Paina mitä tahansa näppäintä...",13,10,0 boot_file_name db "boot.bin",0 ; hHCHPD UFTPLY DS:SI OB LTLBO write_str: push si mov ah, 0x0E @: lodsb testi al, al jz @f int 0x10 jmp @b @: pop si ret ; lTYFYUEULBS PYVLB-virhe: pop si call write_str ; rete_bzthlb reboot: mov si, reboot_msg call write_str xor ah, ah int 0x16 jmp 0xFFFF:0 ; bZTHLB UELFPTB DX:AX H WCHET ES:DI load_sector: push dx add ax, word adc dx, word cmp tavu, 0xFF je .use_EDD push bx cx si div mov cl, dl inc cl div mov dh, ah mov ch, al mov dl, mov bx, di mov al, 1 mov si, 3 @: mov ah, 2 int 0x13 jnc @f xor ah, ah int 0x13 dec si jnz @b .error: call error db "DISK ERROR",13,10 ,0 @: pop si cx bx dx ret .use_EDD: push si mov tavu, 0x10 mov tavu, 0 mov sana, 1 mov , di push es pop sana mov , ax mov , dx mov sana, 0 mov sana, 0 mov ah , 0x42 mov dl, mov si, 0x600 int 0x13 jc .error pop si dx ret ; rPYUL JBKMB U YNEOEN DS:SI H LBFBMPZE DX:AX find_file: push cx dx di .find: cmp ax, -1 jne @f cmp dx, -1 jne @f .not_found: puheluvirhe db "EI LÖYDY",13, 10,0 @: mov di, f_info call load_sector push di mov cx, 0xFFFF xor al, al repne scasb neg cx dec cx pop di push si repe cmpsb pop si je .found mov ax, word mov dx, word jmp .find . löytyi: pop di dx cx ret ; ъBZTHЪLB FELHEEZP ZhBKMB Ch RBNSFSH RP BDTEUKh BX:0. lPMYUEUFFCHP JBZTHCEOOOSCHI UELFPTPCH CHPCHTBEBEFUS H AX load_file_data: push bx cx dx si di mov ax, word mov dx, word .load_list: cmp ax, -1 jne @f cmp dx, -1 @f .file jne.file: ax, bx pop bx sub ax, bx shr ax, 9 - 4 ret @: mov di, 0x8000 / 16 call load_sector mov si, di mov cx, 512 / 8 - 1 .load_sector: lodsw mov dx, add si, 6 cmp ax, -1 jne @f cmp dx, -1 je .file_end @: push es mov es, bx xor di, di call load_sector add bx, 0x200 / 16 pop es loop .load_sector lodsw mov dx, jmp .load_list ; fPYULB CHIPDB CH OBYUBMSHOSHCHK ЪBZTHYUYL boot: ; oBUFTPYN WEZNEOFOSHCHE TEZYUFTSH jmp 0:@f @: mov axe, cs mov ds, axe mov es, axe ; oBUFTPYN UFEL mov ss, ax mov sp, $$ ; tbteyyn rtetschchchboys sti ; bRPNOIN OPNET bZTHЪpyuopzp DYULB mov , dl ; mov ah, 0x41 mov bx, 0x55AA väli levy_havaittu: ; bZTHJIN RTPPMTSEOYE OBJUBMSHOPZP bZTKHJULB mov si, käynnistystiedoston_nimi mov ax, sana mov dx, sanakutsu find_file mov bx, 0x7E00 / 16 kutsu load_file_data ; RETEIPDYN TIETOJA RTPDPMCEOJESTA jmp boot2 ; rHUFPE RTPUFTBOUFCHP Y UYZOBFHTTB rb 510 - ($ - $$) db 0x55,0xAA ; dRPMYFEMSHOSHE DBOOSHE JBZTHYULB load_msg_preffix db "Ladataan "",0 load_msg_suffix db ". ..",0 ok_msg db "OK",13,10,0 config_file_name db "boot.cfg",0 start16_msg db "Aloittaa 16-bittinen ydin...",13,10,0 start32_msg db "Aloittaa 32-bittinen ydin. ..",13,10,0 ; tBVEOYE UFTPLY DS:SI RP UYNCHPMH UMEYB split_file_name: push si @: lodsb cmp al, "/" je @f test al, al jz @f jmp @b @: mov tavu, 0 mov ax, si pop si ret ;bZTHJLB JBKMB U YNEOEN DS:SI N VHZET BX:0.tBNET JBKMB N UELFPTBI PPCHTBEBEFUS N AX load_file: push si mov si, load_msg_preffix call write_str pop si call momssi push si bp mov dx, sana mov ax, sana @: push ax call split_file_name mov bp, ax pop ax call find_file testitavu, 1 jz @f mov si, bp mov dx, sana mov ax, sana jmp @b @ : call load_file_data mov si, ok_msg call write_str pop bp si ret ; рТПДПМЦЕОЙЕ ОБЮБМШОПЗП ЪБЗТХЪЮЙЛБ boot2: ; ъБЗТХЪЙН ЛПОЖЙЗХТБГЙПООЩК ЖБКМ ЪБЗТХЪЮЙЛБ mov si, config_file_name mov bx, 0x1000 / 16 call load_file ; чЩРПМОЙН ЪБЗТХЪПЮОЩК ​​​​УЛТЙРФ mov bx, 0x9000 / 16 mov bp, 0x6000 mov dx, 0x1000 .parse_line: mov si, dx .parse_char: lodsb testi al, al jz .config_end cmp al, 10 je .run_command cmp al, 13 je .run_command jmp .parse_char .0 xsi bygte_char . cmp-tavu, 0 je .parse_line ; rHUFBS UFTPLB cmp-tavu, "#" je .parse_line ; lPNNEOFBTYK cmp-tavu, "L" je .load_file ; bZTHJLB JBKMB cmp-tavu, "S" je .start ; bBRHUL SDTB; oEYCHEUFOBS LPNBODB mov al, mov [.cmd], al call error db "Tuntematon käynnistyskomentokomento "" .cmd db ? db ""!",13,10,0 .config_end: ; rTY RTBCHYMSHOPN LPOZHYZHTBGYPOOPN ZHBKME NSC OE DPMTSOSCH UADB RPRBUFSH; jmp uudelleenkäynnistys; load_file: push dx inc si call load_file push ax mov cx, 512 mul cx mov sana, ax mov sana, dx mov sana, 0 mov sana, 0 mov ax, bx mov cx, 16 mul cx mov sana, ax mov sana, dx mov sana, 0 mov sana, 0 pop ax shr ax, 9 - 4 add bx, ax add bp, 16 pop dx jmp .parse_line ; bBRHUL SDTB.aloitus: ; rTPCHETYN, UFP ЪBZTKhTSEO IPFS VSH PYO ZHBKM cmp bx, 0x9000 / 16 ja @f call error db "NO KERNEL LOADED",13,10,0 @: ; bBRPMOSEN RPUMEDOIK LMENEOF URYULB JBKMPCH xor ax, ax mov cx, 16 mov di, bp rep stosw ; RETEIPDYN L RTPGEDHTE YOYGYBMYYBGYY SDTB DMS OHTSOPK TBTSDOPUPY inc si cmp sana, "16" je .start16 cmp sana, "32" je .start32 ;cmp sana, "64" ;je start64 ; oEYCHEUFOBS TTSDSDOPUFSH SDTB-kutsuvirhe db "Virheellinen aloituskomennon argumentti",13,10,0 ; bBRHUL 16-TBTSDOPZP SDTB.start16: mov si, start16_msg mov bx, 0x6000 mov dl, jmp 0x9000 ; bBRHUL 32-TBTSDOPZP SDTB.start32: ; WHCHCHPDYN HCHEDPNMEOYE P BRHULE 32-VYFOPZP SDTB mov si, start32_msg call write_str ; rTPCHETYN, UFP RTPGEUUPT OE IHCE i386 mov ax, 0x7202 push ax popf pushf pop bx cmp ax, bx je @f call error db "Pakollinen i386 tai parempi",13,10,0 @: ; bztkhjn bobyueoye h GDTR lgdt ; bBRTEFYN RTETSHCHCHBOYS cli ; RETEKDYN H BEEYEIIOOSCHK TEZYN mov eax, cr0 tai eax, 1 mov cr0, eax ; RETEKDIN TIETOJA 32-VYFOSHK LPD jmp 8: start32 ; fBVMYGB DEULTYRFPTPCH UEZNEOPFC DMS 32-VYFOPZP SDTB kohdistus 16 gdt32: dq 0; NULL - 0 dq 0x00CF9A000000FFFF ; KOODI - 8dq 0x00CF92000000FFFF ; TIEDOT - 16 gdtr32: dw $ - gdt32 - 1 dd gdt32 ; 32-VYFOSHK LPD käyttö32 aloitus32: ; mov eax, 16 mov ds, axe mov es, ax mov fs, ax mov gs, ax mov ss, ax movzx esp, sp ; WHCHCHPDYN UYNCHPM TIETOJA LLTBO:sta mov byte, "! " ; 'NELJÄ' jmp $

Jotta voit kirjoittaa käyttöjärjestelmän, sinun on ymmärrettävä monia yksityiskohtia. Tässä, haluan valaista sinua hieman (mutta sovitaan, että luet manan itse, jotta on jotain puhuttavaa).
Rehellisesti sanottuna verkossa on paljon PM-materiaaleja, ja iley ja pehat puhuivat hieman tästä tilasta, mutta minua pyydettiin kuvailemaan sitä yleisesti. Annan nyt lyhyesti teorian (itse asiassa Intel kirjoitti manan erityisesti tätä varten), sitten alamme kirjoittaa koodia.

Johdatus suojattuun tilaan.
Joten PM eroaa merkittävästi kaikesta DOS:n todellisesta tilasta (RM) tutusta. Nyt siihen on totuttava: ei ole staattisia, 64 kilotavun segmenttejä, keskeytystaulukoita 1 kilotavussa, segmenttien kantaosoitteita segmenttirekistereissä, yleensä täysin uusi maailma.
Segmentit on nyt kuvattu kohdassa Global Descriptor Table (GDT). Tämä taulukko voi olla vain yksi kopio. Hän on rakenne muistissa. Ei segmentti! Se voi sijaita missä tahansa muistissa, mutta sen osoite ja raja kirjoitetaan GDTR-rekisteriin. Tässä sen rakenne:

Taulukko itsessään koostuu seuraavan rakenteen merkinnöistä (muuten, tyhjä merkintä on tyhjä. Tämä on tärkeää. Kun käytät tyhjää kuvaajalla 'kuvattua' muistia, hanki #GP - General Protection Fault):
Katsotaanpa tätä rakennetta tarkemmin.

1. Segmenttiraja:
Tämän kentän tarkoitus on selvä nimestä, mutta siinä on hienovaraisuutta. Koira on haudattu G (granularity) -palaan.
Jos sitä ei ole asetettu, muisti "lasketaan" tavuina. Tällaisessa tapauksessa segmentin koko voi vaihdella 1 tavusta 1 megatavuun 1 tavua kohden.
Jos asetamme sen arvoon 1, muistin haku otetaan käyttöön. Sitten pystymme käsittelemään 4 kilotavua 4 gigatavuun RAM-muistia 4 kilotavun (sivun koon) muutoksella. Yleensä sivun osoitus on parempi (vertaa (1Mb+64Kb-16tavu) ja 4Gb). Puhutaan tässä viestissä vain segmenttien osoittamisesta. Sivut ansaitsevat erillisen keskustelun.

2. Perusosoite:
Tässä määritetään tukikohdan fyysinen osoite.

3. Kirjoita kenttä:
Bittiyhdistelmät määrittävät segmentin tyypin:

4. S (kuvaajan tyyppi):
Intelin dokumentaatiossa sanotaan, että jos tätä bittiä ei ole asetettu, tämä kuvaaja on järjestelmäsegmentille, muuten - koodi tai data. System tarkoittaa LDT:tä, TSS:ää, Interrupt Gatesia ja muita niiden kaltaisia ​​(lisää niistä myöhemmin).

5. DPL (Descriptor Privilege Level):
Kuvatun segmentin oikeudet. Kaikki tietävät Ringsin.

6. P (segmentti läsnä):
Jos tämä bitti on asetettu, prosessori "tietää", että segmentti on jo muistissa (vaikka se on parempi sanoa kelvollinen). Jos lataat kuvaajan valitsimen, jonka P-bittiä ei ole asetettu segmenttirekisteriin, tapahtuu #NP (ei läsnä) poikkeus. Yleensä tämän koristeellisen lauseen merkitys selitetään hieman myöhemmin.

7.D/B:
Erityyppisten segmenttien osalta se tulkitaan eri tavalla.
1. Koodisegmentit:
32 tai 16 bitin tehollinen osoitteen pituus ja operandipituus.
(1-32; 0-16);
2. Pino:
Pinoosoitin on 32 tai 16 bittiä. (1-32; 0-16);

8.G:
Vaikuttaa millä yksiköillä (tavuilla, sivuilla) segmenttiraja mitataan. Yleisesti ottaen haku voidaan ottaa käyttöön PM:ää syötettäessä asettamalla CR0-rekisterin bitti 31.

Muutama lisätietoa:
Oletamme, että sanaa Global ei laitettu turhaan. On siis toinenkin merkki. Totta, on myös Paikallinen kuvaajataulukko. Niitä voi olla paljon. Niitä voidaan käyttää esimerkiksi tehtävien toteutuksessa jne. Ja täällä LDT edustaa jo segmenttiä! Joten totu sellaisiin lauseisiin kuin "paikallinen kuvaajataulukon segmenttikuvaaja".

Kun olemme kuvanneet taulukon, meidän on ladattava se rekisteriin GDTR. Tämä tehdään kaukana mov. GDTR joukkueen täyttämä lgdt fword (arvo). Eli tämä rakenne on tarpeen muodostaa itse ja ladata se edellä mainittuun rekisteriin. Tämän rekisterin parissa työskentelee edelleen tiimejä, mutta me laukkaamme ympäri Eurooppaa.

Vielä hetki. PM:ssä segmenttirekisterit eivät tallenna segmenttien perusosoitteita (kuten RM:ssä), vaan erityisesti koulutettuja kappaleita ns. valitsimia. Niiden rakenne on:

Tässä indeksi on taulukon kuvaajan järjestysnumero.
TI näyttää, mistä kuvaajaa etsitään (in GDT tai LDT).

Nyt kun on jo selvää, kuinka taulukko rakennetaan, puhutaan kuinka vaihtaa PM:ään (huomaa, että tämä voidaan tehdä vain RM: stä). Yleensä... sinun tarvitsee vain asettaa ohjausrekisterin CR0 bitti 0. Vaikka valehtelen. Ensin sinun on poistettava kaikki keskeytykset ( NMI (Ei-maskoitavat keskeytykset) mukaan lukien), avaa osoiterivi A20(jotta 32-bittinen osoitus on käytettävissä), lataa GDTR, ja hyppää merkkiin - aloita.

Käytetään latausohjelmaa (voit ottaa KOLIBRI:n), joka lataa koodimme osoitteeseen 1000h: 0 (RM:t, huomautan, osoite).
Täällä kaikki ei ole niin sujuvaa kuin niissä manasissa, kun he siirtyvät PM: ään suoraan käynnistyslataimesta. Kaikki on hieman monimutkaisempaa. Mutta ensin katsotaan koodia, jonka käynnistyslatain lataa (kirjoitamme kaikki FASM "e":llä). Tämä on eräänlainen helloworld. Käynnistetään, mennään PM:ään ja tulostetaan tervehdys. Siinä se.

binaarimuodossa
xorax, ax
cli ; alusta segmenttirekisterit uudelleen
mov ss, ax
xorsp,sp
sti
movax, 3
int 10h

Jmp 1000h:r_start

Mov ax, 1000h; konfiguroi rekisterit uudelleen
mov ds, ax
mov es, ax

Al, 0x92; ota A20 käyttöön
tai al, 2
ulos 0x92, al

Lgdt fword ;lataa GDTR-rekisteri
mov eax,cr0
tai al,1; aseta bitti 0
mov cr0,eax;ota PM käyttöön

Jmp fword 08h:Käynnistys32; hyppää PM:ään

Kohdista 8 ; prosessori käsittelee kohdistetun levyn nopeammin
GDT:
dq 0 ;tyhjä
db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ;koodi
db 0FFh,0FFh,0,0,0,92h,0CFh,0;data
db 0FFh,0FFh,0,80h,0Bh,92h,40h,0 ; videosegmentti
tunniste GDT_SIZE hintaan $-GDT
GDTR:
dw GDT_SIZE-1
ddGDT+10000h
; sinun on kirjoitettava 32-bittinen osoite. Nyt ollaan segmentissä 1000h, jonka kanta on 1000h*10h (by; fyysinen osoite) => GDTR:n fyysinen osoite (tarrat!) = 10000h (segmenttipohjan fyysinen osoite)+offset

Virtuaalinen; nyt itse asiassa täytämme tilan segmentin loppuun
rb 10000h-$;
loppu virtuaalisesti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
käyttö32
org $+10000h; tässä mitä: PM:ssä työskentelemme Flat-segmenttien kanssa, ja jos jätämme koodin; PM:lle ennen organisaatiota, niin segmentin sisäinen osoite ei vastaa Flat-osoitetta. Niin.

Käynnistys32: ;PM-tulopiste
mov ax,10h ;työnnä valitsimet tähän. Usein (! älä unohda sarjanumeroa
mov es,ax ;table) koodisegmentin valitsin - 08h. data - 10h, videosegmentti - 18h
mov ds, ax
mov fs,ax
mov ss, ax
mov esp, 10000h; pino
movax, 18h
mov gs, ax

Mov esi,hi_string ;osoita, että läpäisimme onnistuneesti
soita tulostaa
jmp $

;ESI - merkkijonoosoite
Tulosta:
pushad
x tai ebx, ebx
mov ah,07h;attribuutti
laittaa:
mov al,
mov, ax
inc ebx
testi al, al
jnz laittaa
popad
ret
hi_string db 'Tervetuloa PM:ään, jätkä',0

Mitä me olemme tehneet? Kuormaaja latasi meidät onnistuneesti klo 1000h:0, josta jatkoimme suoritusta. Ensin kytketty päälle A20, kaikki keskeytykset pois käytöstä, ladattu GDTR sopiva arvo, hyppäsi syöttötunnisteeseen. Huomaan, että hyppäsimme päälle
jmp fword 08h:Käynnistys32
Eli 08h - koodikuvaajan valitsin. Totu siihen.

Kuinka aloittaa tämä ihme. Itse käytän WinImagea ja VirtualBoxia. Työnämme käynnistyslataimen levykkeen käynnistyssektoriin ja laitamme .bin-tiedoston juureen. Tallennamme sen .vfd-tiedostoon, kirjoitamme polku levykekuvaan virtuaalikoneen ominaisuuksiin, suoritamme sen ja katsomme tuloksen.

Seuraavassa numerossa tarkastellaan keskeytyksiä, vikoja, ansoja, keskeytyksiä ja niiden toimintaa, kiinnijäämistä ja virheenkorjausta. Aloitetaan puhuminen arkkitehtuurista.

Tietolähteet.
1) Haluan vain ilmaista kiitollisuuteni Phantom_84:lle eli egoille siitä, että hän osoitti minulle oikean tien ja auttoi minua heti alussa. Ilman häntä minun olisi paljon vaikeampaa selvittää se.

Kaikki prosessorit Intel, alkaen i80286:sta ja aina uusimpiin, käynnistettäessä (alkuperäisen "nollauksen" jälkeen) toimivat todellisessa osoitetilassa (todellisessa tilassa). Tyypillisesti reaalitilaa käytetään joko väliaineena suojattuun tilaan siirtymiseen mikroprosessorijärjestelmän alustuksen jälkeen tai mikroprosessoreille kirjoitettujen ohjelmien nopeampaan suorittamiseen. 8086 , 80186 , mutta verrattuna 8086 , 80186 , nykyaikaisissa reaalitilassa olevissa mikroprosessoreissa on laajempi joukko suoritettavia käskyjä ja kyky käsitellä 32-bittisiä operandeja.
Prosessorin vaihtaminen suojattuun tilaan reaalitilasta tapahtuu käynnistämällä CR0(Kuva 1) sanoja, joilla on yksi PE-bitin arvo ( Suojaus Ota käyttöön). Yhteensopivuuden vuoksi 80286-ohjelmiston kanssa PE-bitti voidaan asettaa myös LMSW-käskyllä. Ennen muistiin kytkemistä on alustettava tarvittavat kuvaajataulukot IDT Ja GDT. Välittömästi suojatun tilan käyttöönoton jälkeen prosessori on CPL = 0.

Riisi. 1

Kaikille 32-bittisille prosessoreille suositellaan seuraavaa vaihesarjaa siirtyäksesi suojattuun tilaan:
1. Poista maskoitavat keskeytykset käytöstä nollaamalla IF-lippu ja estä ei-maskeoitavien keskeytysten esiintyminen ulkoisella logiikalla.Ohjelmakoodin tulee "siirtymäjakson" aikana taata poikkeusten puuttuminen eikä ohjelmistokeskeytyksiä saa käyttää. Tämä vaatimus johtuu muutoksesta keskeytyskäsittelijöiden kutsumismekanismissa.
2. Lataa kohteeseen GDTR perusosoite GDT(LGDT:n ohjeiden mukaan).
3. Ohje MOV CRO aseta PE-lippu ja jos hakumuistia tarvitaan, niin PG-lippu.
4. Välittömästi tämän jälkeen segmenttien välinen hyppykomento ( JMP kaukana) tai soita ( Soita Kauas) tyhjentääksesi reaalitilan dekoodattujen käskyjen jonon ja suorittaaksesi suorittimen serialisoinnin. Jos sivutus on käytössä, ohjekoodit MOV CRO Ja JMP tai PUHELU on oltava sivulla, jonka fyysinen osoite vastaa loogista osoitetta (koodille, johon ohjaus siirretään, tätä vaatimusta ei vaadita).
5. Jos aiot käyttää paikallista kuvaajataulukkoa, ohje LLDT kuorman segmentin valitsin LDT rekisteröityä LDTR
6. Ohje LTR ladata tehtävärekisterin valitsimeen TSS alkuperäistä suojatun tilan tehtävää varten.
7. Lataa uudelleen segmenttirekisterit (paitsi CS), joiden sisältö kuuluu edelleen reaalimoodiin, tai suorita siirtymä tai kutsu jokin muu tehtävä (tässä tapauksessa rekisterit ladataan automaattisesti uudelleen). Käyttämättömät segmenttirekisterit ladataan valitsimella nolla.
8. Ohje LIDT lataa rekisteröityäksesi IDTR osoite ja raja IDT- Suojatun tilan keskeytyskuvaustaulukot.
9. Salli maskoitavat ja ei-maskettavat laitteistokeskeytykset

Tämä artikkeli sisältää johdannon prosessorin suojatussa tilassa toimivien ohjelmien kehittämiseen. Täällä asetetaan suojatussa tilassa toimivien ohjelmien päätehtävät ja annetaan niiden ratkaisut. Periaatteessa ohjelmat kirjoitetaan kielellä FASM.

Intel 80386 -prosessorin toimintatilat

Prosessorin myötä Intel 80386 arkkitehtuuri syntyi IA32. Se oletti prosessorin uuden toimintatavan syntymisen - suojattu (" Suojattu tila"). Yhteensopivuus sarjan aikaisempien prosessorien kanssa Intel 80x86 prosessori 80386 ei käynnistynyt heti suojatussa tilassa, vaan toimi niin sanotussa todellisessa tilassa (" Todellinen tila"). Lisäksi jokaisessa tilassa on yksi tai useampi alitila. Analysoidaan niitä.

todellinen tila

Tässä tilassa prosessori on heti "" tehoa"tietokone. Reaalitilan muistia käytetään suunnittelun mukaan" segmentti:offset", joka kuvaa loogista osoitetta. Segmentin arvo, kuten offset, vaihtelee 0 ennen 0FFFFh.

Koska voit osoittaa vain yhden segmentin sisällä, segmentin enimmäiskoko on 64 kilotavu. Prosessorin osoiteväylään asetettu fyysinen osoite lasketaan kaavalla:

lineaarinen osoite = segmentti * 16 + offset

Reaalitilan prosessorit 80186 Ja 8086 segmentin arvo vaihteli 0 ennen 0F000h. Siten osoiteväylän suurin paljastettu osoite on 0FFFFH, joka vastaa (2^20)-1 , eli 1 megatavu.

Tietenkin aluksi tällaisen muistin määrä tuntui valtavalta, mutta ajan myötä yksi megatavu ei riittänyt. Prosessorin myötä 80286 niin sanottu muistilohko tuli saataville UMB osoitteesta alkaen 0FFFFh:0010h ja päättyy osoitteeseen 0FFFFh:0FFFFh(65520 tavua yli yhden megatavun). Nyt oli mahdollista määrittää käyttöjärjestelmä uudelleen MS-DOS niin, että se täyttää tämän lohkon ja vapauttaa 64 kilotavua RAM-muistia.

Suojattu tila

Tällä tilalla on monimutkainen rakenne verrattuna todelliseen. Loogista osoitetta edustaa rakenne " valitsin:offset". Valitsin on välillä 0 ennen 0FFFFh(itse asiassa valitsimia on 4 kertaa vähemmän - lisää tästä seuraavissa artikkeleissa). Poikkeama, toisin kuin todellinen tila, on 32-bittinen, mikä mahdollistaa 4 gigatavun segmenttien osoittamisen. Looginen osoite muunnetaan lineaariseksi osoitteeksi seuraavan kaavion mukaisesti:

lineaarinen osoite = segmentin kanta + offset

Lineaarinen osoite asetetaan sitten osoiteväylään, ellei hakutila ole käytössä. Muuten lineaarinen osoite muunnetaan fyysiseksi ja vasta sen jälkeen se asetetaan osoiteväylään. Lisäksi suojattu tila mahdollistaa virtuaalisen muistin järjestämisen jopa 64 teratavun koon mukaan ja vain kiintolevyn koosta riippuen (esim. sama sivutustiedosto Windows toteuttaa virtuaalimuistia). Lähes kaikki nykyaikaiset käyttöjärjestelmät toimivat suojatussa tilassa.

Multitasking Protected Mode -alitila

Tämän tilan avulla voit järjestää moniajoa, toisin sanoen mahdollisuuden suorittaa useita tehtäviä samanaikaisesti tai usean käyttäjän järjestelmää.

Virtuaalinen 8086-tila

Se on myös suojatun tilan alitila, jonka avulla voit luoda virtuaalikoneen, joka toimii ikään kuin se olisi todellisessa tilassa, mutta toimii itse asiassa suojatussa tilassa.

Epätodellinen tila

Tämä on todellisen tilan erityinen alitila. Prosessori on reaalitilassa, mutta se käsittelee muistia rakentamalla " valitsin: offset". Näin ollen yli 1 megatavun muistia on käytettävissä. Jatkossa suojattu tila ja sen alitilat otetaan huomioon.

Ensimmäinen ohjelma: Vaihtaminen suojattuun tilaan

Vaihtaminen suojattuun tilaan tapahtuu asettamalla bitti 0 rekisteröidy CR0. Siirtyminen reaalitilaan tapahtuu nollaamalla sama nollabitti. Harkitse ohjelmaa, joka suorittaa tämän toiminnon (kieli - Tasainen kokoaja):

käyttö 16 ; 16-bittisiä ohjeita käytetään

org 100h

alkaa:

; Olemme reaaliajassa

mov eax,cr0 ; Lue rekisterin CR0 arvo
tai al, 1 ; Aseta nollabitti
mov cr0,eax ; Kirjoita uusi arvo CR0:lle

; Olemme suojatussa tilassa

mov eax,cr0 ; CR0:n arvon lukeminen
ja al, 0feh ; Palauta nollabitti arvoon 0
mov cr0,eax ; Vaihtaa reaalitilaan

; Olemme reaaliajassa

ret ; Ohjelmasta poistuminen

Tämä ohjelma on kuitenkin melko "raaka", koska silmukoita ei voida toteuttaa siinä. Jos kirjoitat komentoja, kuten hlt tai jmp $, sitten kun ensimmäinen keskeytys laukeaa, tietokone käynnistyy uudelleen.

Meidän tapauksessamme komennot toimivat melko nopeasti, mutta on mahdollista, että ohjelmamme komentojen suorittamisen välisenä aikana keskeytys toimii edelleen, mikä johtaa välittömään kaatumiseen ja uudelleenkäynnistykseen. Siksi sinun on huolehdittava keskeytyksistä. Katsotaanpa siis listaa uudelleen. Tätä ei voida kutsua ensimmäiseksi ohjelmaksi (pikemminkin se olisi nolla), koska se ei toteuta päätoimia suojattuun tilaan siirtymiseksi. Jos haluat siirtyä kokonaan suojattuun tilaan minimaalisilla asetuksilla, sinun on suoritettava seuraavat vaiheet:

1. tarkista, onko mahdollista vaihtaa suojattuun tilaan;

2. alusta kuvaajataulukot;

3. poista keskeytykset käytöstä (sekä maskettavissa että ei-maskeoitavissa);

4. avoin linja A20;

5. lataa muistinhallintarekisterit;

7. hypätä 32-bittiseen koodisegmenttiin ohittamalla CS-rekisteri.

Mutta riittää, että ensimmäinen ohjelma suorittaa vaiheet 3, 4, 5. Silloin sen silmukka ei käynnistä tietokonetta uudelleen. Katsotaanpa jokaista vaihetta.

Keskeytusten poistaminen käytöstä estää meitä käynnistymästä uudelleen. Keskeytykset on jaettu maskoitaviin ja ei-maskoitaviin. Voit poistaa maskattavat keskeytykset käytöstä poistamalla lipun JOS rekisteröidy LIPUT tiimi cli, kun taas keskeytykset otetaan käyttöön komennolla sti. Ei-maskettavat keskeytykset poistetaan käytöstä hieman eri tavalla. On kaksi tapaa tehdä tämä: ohjelmoida keskeytysohjaimen rekisterit (tätä menetelmää käsitellään hieman myöhemmin) tai muuttaa portin seitsemäs bitti 70h: jos bitti on asetettu, keskeytykset eivät ole käytössä, jos bitti on tyhjä, keskeytykset voidaan suorittaa.

Kysytään nyt itseltämme, mikä on linjan tehtävä A20, Mikä tämä sitten on. Linja A20- yksi 32 osoiterivistä. Kun tietokone käynnistyy, linja A20 suljettu. Tämä johtaa 20-bittisten osoitteiden luomiseen (eli koko osoiteavaruus on yhtä suuri kuin (2^20)=1 megatavu). Tämä otettiin käyttöön prosessorin kanssa yhteensopivuuden vuoksi 8086 : yrittää näin kirjoittaa lineaariseen osoitteeseen 12345678h, kirjoitamme itse asiassa osoitteeseen 00045678h, mikä voi johtaa täysin odottamattomiin tuloksiin. Siksi 32-bittisen sovelluksen täyden toiminnan varmistamiseksi linja A20 täytyy olla auki. Tämä tehdään asettamalla terä 1 portti 92h, linja sulkeutuu A20- nollaa tämä bitti.

Lukija tuntee jo viimeisen toiminnon, eikä sen pitäisi enää herättää hänelle kysymyksiä.

Joten katsotaanpa listaa uudesta, ensimmäisestä ohjelmastamme, jossa pieni silmukka on jo toteutettu. Edelliseen listaukseen lisätyt rivit on merkitty tähdellä (*).

org 100h

alkaa:

; Olemme reaaliajassa

cli ;*

sisään al, 70h ;*
tai al, 80h ;*
ulos 70h, al ;*

; Avaa linja A20

sisään al, 92h ;*
tai al, 2 ;*
ulos 92h, al ;*

mov eax,cr0
tai al, 1
mov cr0,eax


; pieni kaksoissykli

mov cx, 20 ;*

sykli: ;*
mov kirves, cx ;*
mov cx, 0ffffh ;*
silmukka $ ;*
mov cx, ax ;*
silmukka pyöräillä ;*

mov eax,cr0
ja al, 0feh
mov cr0,eax

; Sulje rivi A20

sisään al, 92h ;*
ja al, 0fdh ;*
ulos 92h, al ;*

sisään al, 70h ;*
ja al, 7fh ;*
ulos 70h, al ;*

sti ;*

ret ; suorita ohjelma loppuun

Voit varmistaa ohjelman toiminnan suorittamalla suoritettavan tiedoston puhtaalta MS-DOS. Jos ohjelma päättyy oikein, kaikki on kunnossa.

Kuitenkin myös seuraavat ongelmat voivat ilmetä:

1. tietokone jäätyy";

2. tietokone käynnistyy uudelleen.

Tämä voi johtua seuraavista syistä:

1. ohjelma on käynnissä V86(virtuaali 8086 );

2. ohjelma on käynnissä suojatussa tilassa tai tietyssä käyttöjärjestelmässä.

Siksi, ennen kuin käynnistät suojatussa tilassa toimivan ohjelman, sinun tulee tarkistaa ohjelman jatkotyöskentelymahdollisuus. Tästä keskustellaan lisää.

Tarkistetaan kykyä siirtyä suojattuun tilaan

Edellisessä luvussa meillä oli seuraava ongelma: ohjelma ei tunnista olevansa suojatussa tilassa tai V86, mikä saa järjestelmän jumittumaan tai käynnistymään uudelleen. Jos yritämme ajaa ohjelmaa käyttöjärjestelmän alla Windows, Tuo Windows havaitsee ohjelman yrityksen siirtyä suojattuun tilaan ja kehottaa käynnistämään uudelleen emulointitilassa MS-DOS(alustalle 9x), tai lopettaa ohjelman väkisin (alusta NT).

Joten varmistaaksemme, että olemme todella todellisessa tilassa, meidän tulisi suorittaa seuraavat toiminnot:

1. tarkista rekisterin nollabitti CR0;

2. varmista, että Windows-käyttöjärjestelmää ei ole ladattu.

Ensimmäinen toimenpide suoritetaan lukemalla suoraan rekisteri CR0 rekisterin nollabitin lisätarkistuksen kanssa EAX, KIRVES tai AL. Jos bittiä ei ole asetettu, olemme reaalitilassa. Muuten ohjelman jatkaminen menettää merkityksensä.

Toinen toiminto suoritetaan kutsumalla toimintoa 1600h keskeyttää 2fh. Tämän toiminnon avulla voit saada käyttöjärjestelmän nykyisen version Windows. Jos toiminnon kutsumisen jälkeen rekisterissä AL sisältää nollan, käyttöjärjestelmää ei ole ladattu. Muuten ohjelmamme on taas turha jatkaa muita toimia.

Harkitse esimerkkiä seuraavasta ohjelmasta. Se on muunnos edellisestä ohjelmasta, kaikki uudet ohjeet on merkitty tähdellä (*).

Organisaatio 100h

alkaa:

; Aseta segmenttirekisterit

mov kirves, cs ;*
mov ds, kirves ;*

; Tarkistamme, että olemme todella todellisessa tilassa

mov eax,cr0 ;* nolla bitin tarkistus
testata al, 1 ;* rekisteri CR0
jz ei_pm ;*

mov ah, 09h ;* DOS-toiminto 09h
mov dx, pm_msg ;* merkkijonotuloste
int 21h ;*
ret;* ja poistu

no_pm:
; Tarkistaa, onko ohjelma käynnissä Windowsissa

mov kirves, 1600h ;* toiminto 1600h multiplekseri
int 2fh ;* keskeyttää - hanki Windows-versio
testata al, al ;* jos ei 0 - virhe
jz no_windows

; Näytä virheilmoitus

mov ah, 09h ;*
mov dx, win_msg ;*
int 21h ;*
ret ;*

no_windows:
; Olemme ehdottomasti reaaliajassa.
; Poista maskoitavat keskeytykset käytöstä

; Poista ei-maskettavat keskeytykset (NMI) käytöstä

sisään al, 70h
tai al, 80h
ulos 70h al

; Avaa linja A20

sisään al, 92h
tai al, 2
ulos 92h al

; Vaihda suojattuun tilaan

mov eax,cr0
tai al, 1
mov cr0,eax

; Nyt olemme suojatussa tilassa
; pieni kaksoissykli

mov cx, 20

sykli:
mov kirves, cx
mov cx, 0fffh
silmukka $
mov cx, ax
silmukka sykli

; Vaihda reaalitilaan

mov eax,cr0
ja al, 0feh
mov cr0,eax

; Sulje rivi A20

sisään al, 92h ;*
ja al, 0fdh ;*
ulos 92h, al ;*

; Ota käyttöön ei-maskoitavat keskeytykset (NMI)

sisään al, 70h ;*
ja al, 7fh ;*
ulos 70h, al ;*

; Ota maskoitavat keskeytykset käyttöön

sti ;*

; Olemme palanneet reaaliajassa

ret ; suorita ohjelma loppuun

; Virheilmoitukset

pm_msg: ;*
db "Virhe: käynnissä jo suojatussa tilassa!$" ;*
win_msg: ;*
db "Virhe: Microsoft Windows havaittu!$" ;*
Tämä esimerkki ei myöskään vielä näytä 32-bittisten komentojen toteutusta. Tätä varten sinun tulee myös tutustua seuraavan luvun materiaaliin. Lisäksi esimerkissä on seuraava haittapuoli: funktioita kutsutaan DOS (int 21h), joka alkaa jo olla ristiriidassa ohjelmamme riippumattomuuden kanssa käyttöjärjestelmästä MS-DOS. Jatkossa sinun on päästävä eroon käyttöjärjestelmän toimintojen käytöstä ja siirryttävä toimintojen käyttöön BIOS. Mutta toistaiseksi riittää, että rajoitamme itsemme tällaiseen koodiin.

Pelaan tällä hetkellä x86 Assemblerilla parantaakseni matalan tason ohjelmointitaitojani. Minulla on tällä hetkellä pieni ongelma 32-bittisessä suojatussa tilassa olevaan osoitejärjestelmään.

Tilanne on tämä:

Minulla on ladattu ohjelma 0x7e0:ssa, joka kytkee CPU:n suojattuun tilaan ja hyppää koodissa olevaan asianmukaiseen etikettiin:

[...] koodi CPU:n kytkemiseksi suojatussa tilassa [...] jmp ProtectedMode [...] bittiä 32 ProtectedMode: .halt: hlt jmp .halt

Toistaiseksi kaikki toimii loistavasti. "Jmp ProtectedMode" toimii ilman nimenomaista kaukohypyä esihakujonon tyhjentämiseksi, koska tämä ohjelma ladataan offsetissa 0 (org 0 alussa), jolloin koodisegmentti pakotetaan osoittamaan oikeaan paikkaan.

Tämänhetkinen ongelmani on, että "ProtectedMode"-pikakuvakkeessa haluan siirtyä toiseen ohjelmaan, joka on ladattu 0x8000:sta (tarkastin tämän muistivedolla, lataustoiminto toimi oikein ja ohjelma latautui oikein 0x8000 asti).

Koska CPU on nyt ProtectedModessa RealModen sijaan, osoitusmalli on erilainen. ProtectedMode käyttää kuvaajia etsiäkseen perusosoitteen ja rajan kuvaustaulukosta lisätäkseen annetun siirtymän ja saadakseen fyysisen osoitteen (kuten ymmärrän sen). Siksi GDT oli asetettava ennen ProtectedMode-tilaan siirtymistä.

Omani näyttää tältä:

%ifndef __GDT_INC_INCLUDED__ %define __GDT_INC_INCLUDED__ ;**************************************** ;* Global Descriptor Table (GDT) * ;*********************************** NULL_DESC: dd 0 ; nollakuvaaja dd 0 CODE_DESC: dw 0xFFFF ; raja matala dw 0 ; perusmatala db 0 ; pohja keskimmäinen db 10011010b ; pääsy db 11001111b ; rakeisuus db 0; peruskorkea DATA_DESC: dw 0xFFFF ; datakuvaaja dw 0 ; raja matala db 0 ; perusmatala db 10010010b ; pääsy db 11001111b ; rakeisuus db 0; peruskorkea gdtr: Raja dw 24 ; GDT-pohjan pituus dd NULL_DESC; GDT %endif ;__GDT_INC_INCLUDED__

ja ladataan GDT-rekisteriin kautta

lgdt

En vieläkään ymmärrä, kuinka voin nyt vaihtaa fyysiseen osoitteeseen 0x8000 ProtectedModessa GDT:tä käyttämällä?

Ensimmäiset ajatukseni oli valita koodikuvaaja (CODE_DESC), jonka pitäisi osoittaa 0x7e00 (nykyiset ohjelmat ladattiin) ja käyttää 0x8000:n (512 tavua) saamiseksi tarvittavaa siirtymää, jolloin tuloksena on hyppykomento:

jmp CODE_DESC:0x200

Mutta se ei toimi.

jmp 0x7e0:0x200

ei sekään toimi...

Onko sinulla aavistustakaan, mitä minulta puuttuu? Ehkä en ymmärtänyt jotain merkittävää 32-bittisessä ProtectedMode-osoitejärjestelmässä ja GDT:n käytössä.

Täysi koodi:

Bitit 16 org 0 ; ladattu offsetilla 0000 (fys-adr: 0x7e00) jmp Start Start: xor ax, ax mov ax, cs mov ds, ax ; päivitä datasegmentti cli ; tyhjennä keskeytykset lgdt ; lataa GDT GDTR:stä (katso gdt_32.inc) kutsu OpenA20Gate ; avaa A20-portin kutsu EnablePMode; hyppää ProtectedMode-tilaan ;****************** ;* Avaa A20-portin * ;******************* OpenA20Gate: sisään al, 0x93; kytkin A20-portti nopean A20-portin 92 tai al, 2 kautta; aseta A20 porttibitti 1 ja al, ~1 ; tyhjennä INIT_NOW bit out 0x92, al ret ;********************************** ;* Ottaa suojatun tilan käyttöön * ;**** **** ******************** OtaPMode käyttöön: mov eax, cr0 tai eax, 1 mov cr0, eax jmp ProtectedMode ; tämä toimii (hyppää nimikkeeseen ja pysähtyy) ;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; => ei toimi ;jmp 08h:ProtectedMode , => ei toimi ;**************** ;* tietokentät * ;* &sisältää * ;******** ******* %include "gdt_32.inc" ;****************** ;* Suojattu tila * ;************ ******* bittiä 32 ProtectedMode: ;tässä haluan hypätä fyysiseen osoitteeseen 0x8000 (elf64 asm-ohjelma) .halt: hlt jmp .halt

11