Што е заштитен режим и со што доаѓа? Префрлување на процесорите на Интел во заштитен режим Префрлување на режим заштитен од асемблер

rPUME OEDEMSHOPZP RETETSCHB CHOPCHSH NPZH PVTBDPCHBFSH CHBU OPCHSHCHN CHSHCHRKHULPN UCHPEK TBUUSCHMLY.

yFBL, LBL CHSH RPNOIFE, CH TEBMSHOPN TETSYNE TBVPFSH RTPGEUUPTB OBN DPUFHREO CHUEZP MYYSH 1 NEZBVBKF BDTEUOPZP RTPUFTBOUFCHBP RTPUFTBOUFCHB YSH 640 LYMPVBKF). fBL LFP Y VSHMP PE CHTENEOB RETCHSCHI RTPGEUUPTPCH CHTPDE 8086, OP RPUFEREOOP PVIENB PRETBFYCHOPK RBNSFY UFBMP OE ICHBFBFSH. h FP CE CHTENS FTEVPCHBMPUSH UPITBOYFSH RPMOHA PVTBFOKHA UPCHNEUFYNPUFSH, YUFPVSHCH 16-TBTSDOSH PRETBGYPOOSCH UYUFENSCH CHTPDE DOS UNPZMOPFSHBSH rПФПНХ VSHHM CHCHEDIO OPCHSHCHK TETSYN TBVPFSCH RTPGEUUPTB - ЪBEYEEЈOOOSCHK TETSYN. rPUME RETEIPDB CH OEZP DMS BDTEUBGYY YURPMSH'HEFUS OE 16, B 32 YMY DBCE 64 VYFB, B UEZNEOFSHCH UFBTPN RPOINBOY YUYUEBAF. fBLCE DPVBCHMSAFUS ЪBEIFOSCH NEIBOINSHCH (YNEOOOP RPFPNH ЪBEEYEYOOOSCHK TETSYN), YuFPVSH SDTP pu VSHMP YЪPMYTPCHBOOP PF RTYMPTSEOYK Y NPZMP YNY UCHPVPDOP HRTBCHMSFSH. lFP OEPVIPDYNP MAVPK RPMOPGEOOOPK NOPZPBBDBUOPK UYUFEN.

ЗА FPZP, UFP DPVBCHMSEFUS CH TEBMSHOPN TETSYNE ЗА RTPGEUUPTBI, LPFPTSHCHE RPDDETSYCHBAF 32-VYFOSCHK BDTEU (i386 Y CHCHYE) - DPVBCHMSCHMSAFTUSHOPTBI, : EAX, EBX, ECX, EDX, ESP, EBP, EIP, ESI, EDI, ЕЗНАМЕ. lBL NPTsOP DPZBDBFSHUS, LFP 32-VYFOSCH CHETUY PVSHYUOSCHI TEZYUFTPCH TEBMSHOPZP TETSINB (LYNEOY TEZYUFTB DPVBCHMSEFUS RTYUFBCHLB "E"). CHUE LFY 32-VYFOSCH TEZYUFTSH LTPNE EIP DPUFHROSCH Y CH TEBMSHOPN TETSYNE, OP CH FBLPN UMHYUBE VHDHF ЪBOINBFSH ОКОЛКУ 1 VBKF VPMSHYE (LOYMSHEGYBFUSHBOSV). ЗА RTPGEUUPTE NMPPTSE 286 FY LPNBODSCH VHDHF OELPTTELFOSCH. nsch NPTSEN, OBRTYNET, OBRYUBFSH mov eax, 0x12345678 Y RPUME bFPZP CH AX VHDEF 0x5678, RPFPNH YuFP ON LBL VSH SCHMSEFUS "PLOPN" CH NMBDIKHATYBOPZU MBDIBS YBUFSH AX). TEZYUFTB-PFPVTBTTSEOYS UFBTYEK YUBUFY 32-VYFOSHI TEZYUFTPC OE UHEEUFCHHEF - NPTsOP EЈ YICHMEYUSH FPMSHLP U RPNPESH BTYZHNEFYLY (UBRTYCHEBOKYPET, RPNPESHA shr eax, 16, FPZDB CH AX VHDEF UFBTYBS RPMPCHYOB, OP UPDETTSYNPE NMBDYI VYF VHDEF KHFETSOP) . YuFP IBTBLFETOP, CH ЪBEEYEOOOPN TETSYNE OBPVPTPF, LPNBODSCH TBVPFSCH U 16-VYFOSHNY TEZYUFTBNY (OP OE 8-VYFOSHCHNY) FTEVHAF RTEZHYHBUTSHYLUT CHB TBBB VPMSHYE, CH ЪBEEYEOOOPN TETSYNE VSCHUFTEE CHSHRPMOSAFUS Y BOYNBAF NEOSHIE NEUFB YNEOOOP LPNBODSCH 32 - VYFOPK BTYZHNEFILY.

fBLCE, FERTSH KH OBU O 2 UEZNEOFOSCHI TEZYUFTB VPMSHYE - GS Y FS. tBVPFB U OYNY RPMOPUFSHHA BOBMPZYUOB DS Y ES Y CHSH NPTSEFE YI UCHPVPDOP YURPMSHЪPCHBFSH CH TEBMSHOPN TETSINE. PFMYUYE FPMSHLP CH FPN, YuFP OILBLYE LPNBODSCH YI SCHOPE OPDTBHNECHBAF (DS YURPMSH'HEFUS RP KHNPMYUBOYA RTBLFYUEULY CHUENY LPNBODBNY Y OELPFPTCNYGNYGPFTPLETP CHNY PRETTBGYSNY) Y OBDP SCHOP KHLBYSCHBFSH, YuFP CHSH IPFYFE PVTBEBFSHUS YUETE OYI. oBRTYNET, mov секира,.

rPNYNP bFPZP TBUYYTEOYS TEZYUFTPC, DPVBCHMSAFUS OPCHCHCHE HRTBCHMSAEYE TEZYUFTSH (TBOSHYE CHMYSM ЗА TETSYN TBVPFSH RTPGEUUPTB FPMSHLP2CR40,CS) eUFSH Y DTHZYE (OBRTYNET, PFMBDPUOSCH TEZYUFTSHCH), OP SING OBU UEKUB OE YOFETEUHAF. yNEOOOP U RPNPESHA LFYI TEZYUFTPC RTPYCHPDYFUS RETELMAYUEOYE RTPGEUUPTB CH ЪBEEYEЈOOOSCHK TETSYN Y OBUFTPKLB OPCHSHHI ZHKHOLGYK CHTPDE UFTBOYTUBOPYKY. пее DPUFHROSCH CH TEBMSHOPN TETSINE.

h ЪBEEYEЈOOPN TETSYNE RPOSFYE WEZNEOFB YЪNEOSEFUS. FERETSH LFP OE RTPUFP VBPCHSHCHK BDTEU, B OPNET BMENEOFB (DEULTYRFPTB UEZNEOFB) CH UREGYBMSHOPK FBVMYGE. fBVMYGB DEULTYRFPTPCH UEZNEOFPCH UPЪDBЈFUS PRETBGYPOOPK UYUFENPK Y NPTSEF UPDETSBFSH OEPVIPDYNPE LPMYUEUFCHP PRYUBOIK UEZNEOFPCH ЪBEEYETEJOOPZP. LBTSDSCHK BMENEOF FBVMYGSH ЪBOYNBEF 8 VBKF Y CH UREGYBMSHOPN ZHTNBFE PRYUSCHCHBEF VBPCHSHCHK BDTEU UEZNEOFB, TBNET, RTBCHB DPUFHRB Y F. D.

UEZNEOFSH ЪBEEEYEOOOPZP TETSYNB DEMSFUS ABOUT DCHB FIRB - UEZNEOFSH LPDB Y UEZNEOFSH DBOOSCHI (ABOUT UBNPN DEM EUFSH EE CHUSLYE TSS Y LDT, OP RPLBNOSHPCEPTY). h CS NPTsOP ЪБЗТХЦБФШ FПМШЛП OPNETB DEULTYRFPTCH, PRYUBOOSCHI LBL UEZNEOF LPDB, h PUFBMSHOSHE UEZNEOFOSHE TEZYUFTSH NPTsOP ЪBZTHBSHFSHBSHOFSH . chBTSOBS TBJOYGB CH FPN, YuFP UEZNEOF LPDB NPTsOP FPMSHLP YUYFBFSH Y YURPMOSFSH, B UEZNEOF DBOOSHI FPMSHLP YUYFBFSH Y RYUBFSH. l UYUBUFSHA, UEZNEOFSH NPZKhF RETELTSHCHBFSHUS CH RBNSFY, RPFPNH NPTsOP UPJDBFSH DCHB DEULTYRFPTB, UUSHMBAEYEUS ЗА PDYO Y FPF TSE TEZFYPOPYPOSB N, B DTHZPK DPUFKHROSCHN DMS ЪBRYUY.

oEUNPFTS ЗА RPDDETSLH UEZNEOFBGYY, POB UYFBEFUS KHUFBTECHYEK. OH Windows, OH Linux OE YURPMSHJHAF EЈ CH RPMOPC NETE, B ЗА PFMYUOSCHI PF x86 BTIYFELFHTSCH (OBRTYNET, ARM) POB CHCHUE PFUHFUFCHHEF. dMS TBZTBOYUEOYS DPUFKHRB L RBNSFY YURPMSH'HEFUS ZPTBJDP VPMEE ZYVLYK NEIBOYN UFTBOYUOPK BDTEUBGYY, LPFPTSCHK NSCH TBUUNPFTYN DBMEE. YuFPVSH YЪVBCHYFSHUS PF UEZNEOFBGYY PU RTPUFP PRYUSCHCHBEF FBVMYGH YЪ DCHHI DEULTYRFPTPCH, KH LBTSDPZP YЪ LPFPTSCHI VBPCHSHCHK BDTEU 0 BDTEUBNTLUKTBS ENPK RBNSFY CH 32-VYFOPN TETSYNE). h FBLPN UMKHYUBE ZPCHPTSF, YuFP NSCH CHLMAYUYUMY TETSYN MYOEKOSCHI BDTEUPCH - UNEEOOYE UPPFCHEFUFCHHEF ZHIYYUUEULPNH BDTEUKH. lFP PYUEOSH HDPVOP Y S RPKDH RP FPNH TSE RKhFY. OE UMEDHEF RSCHFBFSHUS YURPMSHЪPCHBFSH UEZNEOFBGYA CH UCHPEK PRETBGYPOOPK YUYUFENE - LFP UYMSHOP HUMPTSOSEF LPD SDTB, SJSHLY CHSHUPLPZP HTPCHTYPEK,+YBRTTY, NEOFBGYA (FP EUFSH CHCH UNPTSEFE RPMOPGEOOOP RTPZTBNNYTPCHBFSH FPMSHLP ЗА асемблерот) Y, OBLPOEG, CHCH OE UNPTSEFE RETEOUFY UYUFENKH ЗА DTHZHA BTIYFELFHTH, RPFPNKH YuFP x86 EDYOUFCHEOOBS, LPFPTBS KHNEEF LFPF NEIBOYN (Y FP, Ch 64-VYFOPN TETSYNE RPMS VBPCHPZP YSH YOZHPTNBGYS P RTBCHBI DPUFHRB).

lBL S HCE ULBBM, FBVMYGB DEULTYRFPTPCH UEZNEOFPCH ZHTNYTHHEFUS UBNPK PRETBGYPOOPK UYUFENPK. YuFPVSH KHLBBBFSH RTPGEUUPTH, ZDE POB OBIPDFUS YURPMSH'HEFUS UREGYBMSHOBS LPNBODB - lgdt (Глобална табела со опис на оптоварување). pOB RTOYNBEF 6-VBKFPCHHA RETENEOOKHA CH RBNSFY. RETCCHHE EЈ 16 VYF UPDETSBF TBNET FBVMYGSHCH VBKFBI (FBLYN PVTBBPN, NBLUINBMSHOPE LPMYUUEUFCHP DEULTYRFPTPCH - 65536 / 8 = 8192), - RPUMEDYCH2CHKYKE DTEU CH RBNSFY UBNPK FBVMYGSHCH (FP EUFSH VE KHYUFB CHUEI UEZNEOFPC). yNEEF UNSHUM CHSTTBCHOSFSH OBYUBMP FBVMYGSHCH ОКОЛУ 16 VBKF, RPFPNKH YuFP LFP KHMKHYUYBEF ULPTPUFSH DPUFHRB L E Ј MENEOFBN. RETCHSHCHK BMENEOF FBVMYGSHCHUEZDB DPMTSEO VSCHFSH TBCHEO OKHMA Y MAVPE YURPMSHЪPCHBOIE OHMECHPZP UEMELFPTB(HLBBBFEMSH ЗА BMENEOF FBVMYGSH DEULTYRFPTPCH CH UEZNEOFOPN TEZYUFTE OBSCCHBEFUS FBL) RTYCHPDYF L PYYVLE. ъOBYUIF VPMEE-NEOOEE TBVPFPURPUPVOBS FBVMYGB DEULTYRFPTPCH DPMTSOB UPDETSBFSH IPFS VSH FTY DEULTYRFPTB - RHUFPK, DEULTYRFPT LPDB, DEULTYRFPT DBOSCHI.

OH YFP EEЈ UFPYF TBUULBЪBFSH, RTETSDE, YUEN NSCH RPRTPVKHEN RETEKFY CH ЪBEEYEЈOOOSCHK TETSYN? rPTsBMKhK, EEЈ UFPYF KHRPNSOKhFSH RTP KhTPCHOY DPUFKHRB. LPD SDTB UYUFENSH Y LPD RTYMPTSEOYK PFDEMEOSCH DTHZ PF DTHZB U FPK GEMSHA, YuFPVSH SDTP NPZMP RPMOPUFSHA KHRTBCHMSFSH RTPGEUTPTPN, B RTYMPTSEOYS OECHNECHBHBSHFSDY OBU NOPZPЪBDBUOBS pu). lPD YURPMOSEFUS U PRTEDEMOOOSCHN KHTCHOEN RTYCHYMEZYK. h x86 YI GEMSHCHI 4 YFKHLY - PF 0 DP 3. oKHMECHPK KHTPCHEOSH UBNSCHK RTYCHYMEZYTPCHBOOSCHK (NPTSEF CHSHCHRPMOSFSH MAVSHCH LPNBODSCH Y NEOSFSH TETSYMEZYTPCHBOOSCHK), "RTBCHOSCHK." lBL Y CH UMHYUBE U UEZNEOFBGYEK, TBTBVPFYUYLY x86 RETEVPTEYMY U ZHKHOLGYPOBMPN Y CHUE pu YURPMSHJHAF MYYSH DCHB KHTPCHOS YYUEFSHCHTI CHPNPTHTPSOSCHITS F FPMSHLP YI. x LBTSDPZP UEZNEOFB CH EZP DEULTYRFPTE KHLBBO DPL (ниво на привилегија на дескриптор)- HTPCHEOSH DPUFHRB OEPVIPDYNSCHK DMS DBOOZP UEZNEOFB. OERTYCHYMEZYTPCHBOOSCHK LPD OE NPTsEF RPMKHYUFSH DPUFHR L UEZNEOFH U HTPCHOEN DPUFKHRB 0, B RTYCHYMEZYTPCHBOOSCHK LPD NPTsEF RPMKHYUFSH DPUFHR LP CHUENBN.

uEMELFPT UEZNEOFB, LPFPTSCHK UPDETSYFUS CH UEZNEOFOPN TEZYUFTE, SCHMSEFUS OE RTPUFP OPNETPN BMENEOFB CH FBVMYGE, OP Y KHLBBBFEMEN FEMEN KHTChUPDEBFOSH TYCHYMEZYK (PF 0 DP 3), B HCE UFBTYYE OPNET UBNPK FBVMYGSHCH. fBLYN PVTBBN UEMELFPT = (YODELU_DEULTYRFPTB shl 2) + RPL. RPL- Барано ниво на привилегија - ЪBRTBYCHBENSCHK HTPCHEOSH RTYCHYMEZYK. rTY LFPN RPL DPMTSEO VSHFSH VPMSHYE YMY TBCHEO NBLUINBMSHOPNKH YЪ DPL Y CPL (Тековно ниво на привилегии). CPL TBCHEO RPL UEMELFPTB CH CS. fBLYN PVTBBPN LPD OE NPTSEF RPMKHYUFSH DPUFKHRB L UEZNEOFBN, KH LPFPTSCHI KHTPCHEOSH DPUFKHRB CH YUYUMPCHPN CHYDE OITSE, YUEN X OEZP UBNPZP. s, CHETPSFOP, PRYUBM DPUFBFPYuOP ЪBRKHFBOOP, OP CHRPMOE NPTsOP PVPKFYUSH RPL = DPL, LBL NSCH Y RPUFHRIN.

rPLB NSCH RYYEN FPMSHLP SDTP, NSCH VHDEN TBVPFBFSH CH OHMECHPN LPMSHGE ЪBEIFSHCH (FBL EEЈ OBSCHCHBAF KHTPCHOY RTYCHYMEZYK), ЈУФПВШ ЈНЕФШ РПМОШФХРРРБТ.

UEZNEOFBGYS OBNOE OHTSOB, RPPFPNH S OE VHDH PUFBOBCHMYCHBFSHUS RPLB YuFP ЗА ZHTNBFE DEULTYRFPTB, B DBN ZPFPCHSHCHE OBYEOYS. eUMY YOFETEUOP, NPTSEFE RPYUYFBFSH UFH UFBFSHA . tBUUNPFTYN RTPUFEKYK LPD RETEIPDB CH ЪBEEYEYOOOSCHK TETSYN.

; ъBRHUL 32-TBTSDOPZP SDTB.start32: ; CHCHCHPDYN HCHEDPNMEOYE P ЪBRHULE 32-VYFOPZP SDTB mov si, start32_msg повик write_str ; ъБЗТХХЪН ЪБУУЭОЭ Ч GDTR lgdt ; ъBRTEFYN RTETSCHCHBOYS cli; RETEKDEN CH ЪBEEYEЈOOOSCHK TETSYN mov eax, cr0 или eax, 1 mov cr0, eax ; РЕТЕКДЕН ЗА 32-ВИФОШЧК ЛПД jmp 8:старт32; fBVMYGB DEULTYRFPTPCH UEZNEOFPPCH DMS 32-VYFOPZP SDTB порамни 16 gdt32: dq 0 ; NULL - 0 dq 0x00CF9A000000FFFF ; ШИФРА - 8 dq 0x00CF92000000FFFF ; ПОДАТОЦИ - 16 gdtr32: dw $ - gdt32 - 1 dd gdt32 ; 32-VYFOSHCHK LPD use32 start32: ; oBUFTPYN UEZNEOFOSH TEZYUFTSHY UFEL mov eax, 16 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax movzx esp, sp ; CHCHPDYN UINCHPM ЗА BLTB mov byte, "!" ; ъБЧТЭТІІе jmp $

ьFPF LPD UMEDHEF DPRYUBFSH L OBYENH OBYUBMSHOPNH ЪBZTHYUYLH.

RETED RETEIPDPN CH ЪBEEYEЈOOOSCHK TETSYN OEPVIPDYNP ЪBRTEFIFYFSH RTYEN BRRBTBFOSCHI RTETSCHCHBOYK (LMBCHYBFKHTB, NSHCHYSH, FBKNET YTHZIE KHUFTEFIFYFYFSH), BЈFUS OE X DEM, B UCHPY PVTBVPFYUYLY NSCH EEЈ OE OBRYUBMY, RPFPNKH RETCHPE TSE RTETSCHCHBOIE PVTKHYYF UYUFENKH.

oERPUTEDUFCHOOOP RETEIPD CH ЪBEEYEЈOOOSCHK TETSYN PUHEEUFCHMSEF KHUFBOPCHLB OHMECHPZP VYFB CH CR0. ynEOOP LFP NSCH Y DEMBEN (RTSNPK DPUFHR L CR0,2,3,4 OECHPNPTSEO FBL TSE LBL Y LUEZNEOFOSCHN TEZYUFTBN, RPFPNH YURPMSHJKHEN EAX). oEUNPFTS ЗА FP, YuFP NSCH HCE RETEYMY CH ЪBEEYEOOOSCHK TETSYN, LPD RTDPDPMTSBEF YURPMOSFSHUS RP-RTETSOENH 16-VYFOSHCHK. dMS PLPOYUBFEMSHOPZP RETEIPDB OBN OHTSOP PVOPCHYFSH UPDETSYNPE UEZNEOFOSCHI TEZYUFTPC. DYTELFYCHB BUUENVMETB користи32 ZPCHPTYF ENKH, YuFP DBMSHOEKYK LPD CHSHRPMOSEFUS CH ЪBEEYEOOOPN TETSYNE Y OEPVIPDYNP RETELMAYUIFSHUS CH TETSIN ZEOETBPZPOGPODYY УРПМШ'ХЕФУС РП КХНПМЈУБОЈА) .

lPNBODB movzx TBUYYTSEF CHFPTPK BTZKHNEOF DP RETCHPZP. h UNSHUME, YuFP JЪ 16 VYFOPZP OBYUEOYS SP RPMHYUBEFUS 32-VYFOPE. UFBTYYE VYFSH PVOHMSAFUS (NBMP MY, YuFP FBN VShchMP DP OBU). rTEDRPUMEDOSS LPNBODB DENPOUFTYTHEF OBN CHPNPTSOPUFY ЪBEEYEЈOOOPZP TETSYNB - NSCH PVTBEBENUS RP BVUPMAFOPNH 32-VYFOPNH BDTEUKH L CHYDEPFEPLUBTECHPCHN !" CH RTBCHSHCHK OYTSOYK KHZPM ЛБОБОБ (FELUFPCHSHCHK BLTBO YNEEF TBTEYEOYE 80 x 25 UYNCHPMPCH, LBTSDSCHK UYNCHPM ЪBOINBEF CH RBNSFY DCHB VBKFPZKFHBCHBTY DCHB VBKFPZKHBCHBTYE).

nsch VPMSHYE OE NPTSEN PVTBEBFSHUS L UETCHYUBN BIOS, FERETSH RTYYMP CHTENS OBN UFBFSH RPMOPUFSHA UBNPUFPSFEMSHOSCHNY Y UBNYN HRTBCHMSFSH CHUEN PVPTHDPHBOYEN. RETEBZTHTSBFSHUS Y TsDBFSH OBTSBFYS ЗА LMBCHYYH NSCH RPLB OE KHNEEN, RPFPNH RTPUFP UBCHYUBEN U RPNPESH LPNBODSCH jmp $ (RETEIPD BOUT FH CEPBULYPULYHN).

h OBYEN boot.cfg LPNBODH S64 RPLB ЪBNEOYN ЗА S32. FERETSH, EUMY CHU CHU RTBCHYMSHOP UDEMBMY, OBY ЪBZTHYUYL VKhDEF ЪBCHETYBFSH UCHPA TBVPFKH CHCHCHPDPN CHPULMYGBFEMSHOPZPЈЈОBLB Ch KHZTHYUYL VKhDEF ЪBCHETYBFSH UCHPA TBVPFKH CHCHCHPDPN CHPULMYGBFEMSHOPZPЈЈОBLB Ch KHZTHYUYL LBOBYE. lFP FPMSHLP OBYBMP. nsch OBLPOEG-FP RTBLFYUEULY KHYMY YY TEBMSHOPZP TETSYNB (OBOUT UBNPN DEM FBN EEЈ PUFBMPUSH OENOPZP DEM) CH ЪBEEYEЈOOSHCHK. rPULPMSHLH OBZTHYUYL CHSHRPMOSEFUS CH OHMECHPN UEZNEOFE TEBMSHOPZP TETSINB, CHUE UNEEEOYS UPPFCHEFUFCHHAF ZHJYUEULYN BDTEUBN Y RTY RETEEIPDESHOPZP TETSINB, P RETEUUYFSHCHBFSH.

h ЪBCHETYEOYE CHSHCHRKHULB, RPTSBMKHK, DPVBCHMA RPUMEDOYK YFTYI - RTPCHETLH, YuFP RTPGEUUPT RPDDETSYCHBEF ЪBEEYEOOOSCHK TETSIN. UHFSH RTPCHETLY CH FPN, YuFP OE CHUE VYFSH ЗНАМЕЊА NPTsOP YYNEOIFSH RTPZTBNNOP. ФП ЕУФШ ТЕЗЈУФТ ОЕ УПЧУЕН 16-ВЈФОШЧК. ЗА OPCHSHCHI RTPGEUUPTBBI DPUFKHROP DMS YЪNEOOYS VPMSHYE VYF Y LFP NPTsOP PVOBTHTSYFSH. TBVETYFE LPD OITSE UBNY, ULBTSKH FPMSHLP, YuFP LPNBODB pushf RPNEEBEF TEZYUFT ZHMBZPCH CH UFEL, B popf CHSHCHFBMLYCHBEF UPDETTSYNPE UFELB PE ЗНАМЕЊА. fBLYN PVTBUPN EZP NPTsOP NEOSFSH GEMYLPN, BOE PFDEMSHOSCHNY LPNBODBNY. ChPF RPMOSCHK LPD OBEZP ЪBZТХЪУЛБ:

Орг 0x7C00 jmp подигање ; ъБЗПМПЧПЛ 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 ? ; ъБЗПМПЧПЛ ЖБКМБ виртуелен на 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 ? крај виртуелен ; dBOOSHE OBYUBMSHOPZP ЪБЗТХЪУЛБ етикета сектор_по_збор за песна на $$ етикета head_count бајт на $$ + 2 ознака disk_id бајт на $$ + 3 reboot_msg db "Притиснете кое било копче...",13,10,0 bootbind",0boot_name. ; hCHCHPD UFTPLAY DS:SI ЗА BLTB write_str: push si mov ah, 0x0E @: lodsb test al, al jz @f int 0x10 jmp @b @: pop si ret ; Грешка во lTYFYUEULBS PYYVLB: pop si call write_str ; RETEЪБЗТХЛБ рестартирање: mov si, reboot_msg повик write_str xor ah, ah int 0x16 jmp 0xFFFF:0 ; ъБЗТХЛБ UELFPTB DX:AX CH VHJET ES:DI load_sector: push dx add ax, word adc dx, word cmp byte, 0xFF je .use_EDD push bx cx si div mov cl, dl inc cl div mov dhch, ahmov 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: повик грешка db "DISK ERROR",13,10 ,0 @: pop si cx bx dx ret .use_EDD: push si mov byte, 0x10 mov byte, 0 mov word, 1 mov , di push es pop word mov , ax mov , dx mov збор, 0 mov збор, 0 mov ah , 0x42 mov dl, mov si, 0x600 int 0x13 jc .error pop si dx ret ; rPYUL ZHBKMB U YNEOEN DS:SI CH LBFBMPZE DX:AX find_file: push cx dx di .find: cmp ax, -1 jne @f cmp dx, -1 jne @f .not_found: повик грешка db "НЕ НАЈДЕНА",13, 10.0 @: mov di, f_info повик 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 .пронајден mov ax, збор mov dx, збор jmp .find . најден: pop di dx cx ret ; ъБЗТХЛБ FELHEEZP ZHBKMB CH RBNSFSH RP BDTEUKH BX:0. lPMYUEUFCHP ЪБЗТХЦЕОШИ UELFPTPCH CHPCHTBEBEFUS CH AX load_file_data: push bx cx dx si di mov ax, збор mov dx, збор .load_list: cmp ax, -1 jne @f cmp dx, -1 jned @f cmp dx, -1 jned 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 ; fPULB CHIPDB CH OBYUBMSHOSHCHK ЪBZTHYUYL подигање: ; oBUFTPYN UEZNEOFOSHE TEZYUFTSH jmp 0:@f @: mov ax, cs mov ds, ax mov es, ax ; oBUFTPYN UFEL mov ss, ax mov sp, $$ ; TBTEYIN RTETSCHCHBOYS sti; ъBRPNOYN OPNET ЪБЗТХЪПУОПЗП ДУЛБ mov, dl; prtedemyn RBTBNEFTSH ЪБЗТХЪПУОПЗП ДУЛБ mov ah, 0x41 mov bx, 0x55AA int 0x13 jc @f mov бајт, 0xFF jmp .disk_detected @: mov ah, 0x41 mov bx, di. грешка во c dh mov , dh и cx, 111111b mov , cx .disk_detected: ; ъБЗТХЪН РТПДПМЦЭОЕ ОБИБМШОПЗП ъБЗТХЪУЛБ mov si, boot_file_name mov ax, word mov dx, word call find_file mov bx, 0x7E00 / 16 call load_file_data ; RETEIPDYN ЗА RTDDPMCEOYE jmp boot2; rKHUFPE RTPUFTBOUFCHP Y UYZOBFKHTB rb 510 - ($ - $$) db 0x55.0xAA ; dPRPMOYFEMSHOSH DBOOSH ЪБЗТХЪУЛБ load_msg_preffix db "Се вчитува "", 0 load_msg_suffix db "". ... ..",13,10,0 ; tБВЪВЪОЕУФТПЛИ DS:SI RP UYNCHPMH UMEYB split_file_name: push si @: lodsb cmp al, "/" je @f test al, al jz @f jmp @b @: mov byte, 0 mov ax, si pop si ret ; write_str pop si push si bp mov dx, word mov ax, word @: push ax call split_file_name mov bp, ax pop ax call find_file test byte, 1 jz @f mov si, bp mov dx, word mov ax, word jmp @b @ : call load_file_data mov si, ok_msg call write_str pop bp si ret ; rTPDPMTSEOYE OBYUBMSHOPZP ЪБЗТХЪУИЛБ boot2: ъБЗТХЪУИЛБ boot2: ; si, config_file_name mov bx, 0x100 0 / 16 call load_file ; CHSHRPMOYN ЪБЗТХЪПУОШК УЛТИРФ mov bx, 0x9000 / 16 mov bp, 0x6000 mov dx, 0x1000 .parse_line: mov si, dx .parse_char: lodsb тест al, al jz .config_end cmp al, 10 je .run_command 1_runj. команда : mov бајт, 0 xchg dx, si cmp бајт, 0 je .parse_line ; rHUFBS UFTPLB cmp бајт, "#" е .parse_line ; lPNNEOFBTYK cmp бајт, "L" е .load_file ; ъБЗТХЛБ ЖБКМБ cmp бајт, "S" je .start ; ъBRHUL SDTB; oEYCHEUFOBS LPNBODB mov al, mov [.cmd], al грешка повик db "Непозната команда за скрипта за подигање "" .cmd db ? db ""!",13,10,0 .config_end: ; rTY RTBCHYMSHOPN LPOZHYZHTBGYPOOPN ZHBKME NSCH OE DPMTSOSCH UADB RPRBUFSH; jmp рестартирање; ъБЗТХЛБ ЖБКМБ.load_file: push dx inc si call load_file push ax mov cx, 512 mul cx mov збор, ax mov збор, dx mov збор, 0 mov збор, 0 mov ax, bx mov cx, 16 mul cx mov збор, збор, dx mov збор, 0 mov збор, 0 pop ax shr ax, 9 - 4 add bx, ax add bp, 16 pop dx jmp .parse_line ; ъBRHUL SDTB.старт: ; rTPCHETYN, YuFP ЪBZTHTSEO IPFS VSC PDYO ZhBKM cmp bx, 0x9000 / 16 ja @f грешка на повик db "НЕ СЕ Вчитува кернел",13,10,0 @: ; ъBRPMOSEN RPUMEDOYK BMENEOF URYULB ZHBKMPCH xor ax, ax mov cx, 16 mov di, bp rep stosw ; RETEIPDYN L RTPGEDHTE YOYGYBMYBGYY SDTB DMS OKHTSOPK TBTSDOPUFY inc si cmp збор, "16" je .start16 cmp збор, "32" je .start32 ;cmp збор, "64" ;je start64 ; oEYCHEUFOBS TSTSDOPUFSH SDTB повик грешка db "Неважечки аргумент на командата за почеток",13,10,0 ; ъBRHUL 16-TBTSDOPZP SDTB.start16: mov si, start16_msg mov bx, 0x6000 mov dl, jmp 0x9000 ; ъBRHUL 32-TBTSDOPZP SDTB.start32: ; CHCHCHPDYN HCHEDPNMEOYE P ЪBRHULE 32-VYFOPZP SDTB mov si, start32_msg повик write_str ; rTPCHETYN, YuFP RTPGEUUPT OE IHTSE i386 mov ax, 0x7202 push ax popf pushf pop bx cmp ax, bx je @f повик грешка db "Потребно i386 или подобро",13,10,0 @: ; ъБЗТХХЪН ЪБУУЭОЭ Ч GDTR lgdt ; ъBRTEFYN RTETSCHCHBOYS cli; RETEKDEN CH ЪBEEYEЈOOOSCHK TETSYN mov eax, cr0 или eax, 1 mov cr0, eax ; РЕТЕКДЕН ЗА 32-ВИФОШЧК ЛПД jmp 8:старт32; fBVMYGB DEULTYRFPTPCH UEZNEOFPPCH DMS 32-VYFOPZP SDTB порамни 16 gdt32: dq 0 ; NULL - 0 dq 0x00CF9A000000FFFF ; ШИФРА - 8 dq 0x00CF92000000FFFF ; ПОДАТОЦИ - 16 gdtr32: dw $ - gdt32 - 1 dd gdt32 ; 32-VYFOSHCHK LPD use32 start32: ; oBUFTPYN UEZNEOFOSH TEZYUFTSHY UFEL mov eax, 16 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax movzx esp, sp ; hCHCHPDYN UINCHPM ЗА BLTB mov byte, "! ";

За да напишете оперативен систем, треба да разберете многу детали. Па да те просветлам малку (но да се договориме дека сам ќе ја прочиташ маната за да имаш за што да зборуваш).
Да бидам искрен, има еден тон материјали за ПМ на Интернет, а Ајли и Пехат малку зборуваа за овој режим, но сепак ме замолија да го опишам генерално. Сега накратко ќе ја опишам теоријата (всушност, Интел напиша мана специјално за ова), потоа ќе започнеме да пишуваме код.

Вовед во заштитен режим.
Значи, PM е значително различен од реалниот режим (RM) кој им е познат на сите уште од времето на DOS. Сега ќе треба да се навикнете: нема статични сегменти од 64 килобајти, нема табели со прекини во 1 килобајт, нема адреси на бази на сегменти во регистрите на сегменти, генерално, сосема нов свет.
Сега сегментите се опишани во Глобална табела со дескриптори (GDT). Оваа табела може да биде само во една копија. Таа е структура во меморијата. Не сегмент! Може да се наоѓа каде било во меморијата, но неговата адреса и лимит се запишани во регистарот GDTR. Еве ја нејзината структура:

Самата табела се состои од записи од следнава структура (патем, записот нула е празен. Ова е важно. Кога пристапувате до меморијата „опишана“ со нула дескриптор, ќе добиете #GP - General Protection Fault):
Ајде внимателно да ја разгледаме оваа структура.

1. Ограничување на сегментот:
Целта на ова поле е јасна од името, но има суптилност. Кучето е закопано во битот G (Granularity).
Ако не е поставена, тогаш меморијата се „брои“ во бајти. Во овој случај, големината на сегментот може да варира од 1 бајт до 1 мегабајт по големина на 1 бајт.
Ако го поставиме на 1, ќе се воведе адресирање на меморијата на страницата. Тогаш ќе можеме да адресираме од 4 килобајти до 4 гигабајти RAM меморија со промена на големината од 4 килобајти (големина на страницата). Општо земено, се претпочита адресирање на страницата (споредете (1MB+64Kb-16бајти) и 4GB). Ајде да зборуваме само за адресирање на сегменти во овој пост. Пејџинг заслужува посебна дискусија.

2. Основна адреса:
Овде ја означуваме физичката адреса на базата.

3.Впишете поле:
Комбинациите на битови го одредуваат типот на сегментот:

4. S (тип на дескриптор):
Документацијата на Интел вели дека ако овој бит не е поставен, тогаш овој дескриптор е за сегментот на системот, инаку - код или податоци. Под систем подразбираме LDT, TSS, Interrupt Gates и други слични на нив (повеќе за нив подоцна).

5. DPL (ниво на привилегија на дескриптор):
Привилегии на опишаниот сегмент. Сите ги знаат прстените.

6. P (присутен сегмент):
Ако овој бит е поставен, тогаш процесорот „знае“ дека сегментот е веќе во меморијата (иако би било подобро да се каже валиден). Ако вчитате избирач на дескриптор со непоставен P бит во сегментниот регистар, ќе се појави исклучок #NP (не е присутен). Во принцип, ќе го објаснам значењето на оваа раскошна фраза малку подоцна.

7.D/B:
Различно се толкува за сегменти од различни типови.
1. За сегменти на код:
32 или 16 битна ефективна должина на адресата и големина на операндот.
(1-32; 0-16);
2. За магацинот:
Покажувачот за стек е 32 или 16 бита. (1-32; 0-16);

8.Г:
Влијае на единиците (бајти, страници) во кои се мери границата на сегментот. Општо земено, Paging може да се овозможи кога се префрлате на PM со поставување на 31 бит од регистарот CR0.

Некои повеќе информации:
Претпоставуваме дека зборот Глобал не е џабе ставен. Значи има уште еден знак. Така е, исто така има Табела со локални дескриптори. Може да има голема разновидност од нив. На пример, тие можат да се користат при спроведување на задачи, итн. И тука LDTвеќе претставува сегмент! Затоа, навикнете се на фрази како „опишувач на сегменти на табела со локален дескриптор“.

Откако ќе ја опишеме табелата, треба да ја вчитаме во регистарот ГДТР. Ова не се прави со движење. ГДТРпополнети со командата lgdt fword (вредност). Односно, треба сами да ја креирате оваа структура и да ја вчитате во горенаведениот регистар. Сè уште има тимови кои работат со овој регистар, но ние галопираме низ Европа.

Уште една работа. Во PM, сегментните регистри не ги складираат основните адреси на сегментите (како во РМ), туку специјално обучените работи наречени селектори. Нивната структура е како што следува:

Овде Индекс е редниот број на дескрипторот во табелата.
TI покажува каде да се бара дескрипторот (во ГДТили LDT).

Сега, кога веќе е јасно како да се изгради табела, ајде да разговараме за тоа како да одиме до PM (забележете, ова може да се направи само од РМ). Во принцип... само треба да поставите бит 0 од контролниот регистар CR0. Иако лажам. Прво треба да ги оневозможите сите прекини ( NMI (Прекини што не се маскираат) вклучувајќи), отворете ја линијата за адреса А20(за да е достапно 32-битно адресирање), преземете ГДТР, и скокнете на ознаката - стартувајте.

Ајде да користиме подигнувач (можете да го користите KOLIBRI's), кој ќе го вчита нашиот код на адресата 1000h:0 (адресата на РМ, забележувам).
Овде нема да биде се така мазно како во тие мани кога ќе се префрлат на PM директно од подигачот. Сè е малку покомплицирано. Ама прво да ја погледнеме шифрата што ќе ја вчита подигнувачот (се пишуваме на FASM).

Форматирајте бинарно
xor секира, секира
cli ;реиницијализирај регистри на сегменти
mov ss,ax
xor sp,sp
сти
mov ax, 3
во 10ч

Jmp 1000h:r_start

Mov ax,1000h;реконфигурирајте ги регистрите
mov ds,ax
mov es,ax

Во ал, 0x92; овозможете A20
или ал, 2
надвор 0x92, ал

Lgdt fword ;вчитајте го регистарот GDTR
mov eax, cr0
или al,1;поставете бит 0
mov cr0,eax;вклучи PM

Jmp fword 08h:Startup32; скокај до PM

Порамнете 8 ;процесорот побрзо се справува со подредената плоча
GDT:
dq 0 ;празна
db 0FFh,0FFh,0,0,0.9Ah,0CFh,0 ;шифра
db 0FFh,0FFh,0,0,0,92h,0CFh,0;податоци
db 0FFh,0FFh,0,80h,0Bh,92h,40h,0 ;видео сегмент
означете GDT_SIZE на $-GDT
GDTR:
dw GDT_SIZE-1
dd GDT+10000h
; треба да ја запишете 32-битната адреса. Сега сме во сегментот 1000h, чија основа е 1000h*10h (по физичка адреса) => физичка адреса на GDTR (ознаки!) = 10000h (физичка адреса на основата на сегментот) + поместување

Виртуелна ;сега, всушност, го пополнуваме просторот до крајот на сегментот
rb 10000h-$;
крај виртуелен
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
употреба32
org $+10000h; еве зошто: во PM работиме со Flat сегменти, и ако го оставиме кодот;за PM пред org, тогаш;интрасегментната адреса нема да се совпаѓа со адресата Flat. Па еве го.

Startup32: ;влезна точка до PM
mov ax, 10h; тука ги туркаме избирачите. Често (! не заборавајте за серискиот број во
mov es,ax ;table) селекторот код сегмент - 08h. податоци - 10ч, видео сегмент - 18ч
mov ds,ax
mov fs,ax
mov ss,ax
mov esp,10000h;стак
mov секира, 18ч
mov gs,ax

Mov esi,hi_string ;ајде да покажеме дека успешно поминавме
повик печатење
jmp$

;ESI - адреса на линија
печати:
пушад
xor ebx, ebx
mov ah,07h;атрибут
става:
mov al,
mov, секира
инк ebx
тест ал, ал
jnz става
попад
рет
hi_string db „Добре дојдовте во PM, пријателе“, 0

Што направивме? Натоварувачот успешно не вчита на адреса 1000h:0, од ​​каде продолживме со извршувањето. Прво вклучено А20, ги оневозможи сите прекини, вчитани во ГДТРсоодветна вредност, скокна до влезната етикета. Забележувам дека скокнавме
jmp fword 08h:Startup32
Односно, 08h е избирач на дескриптор на код. Се навикнеш на него.

Сега како да се започне ова чудо. Лично, користам WinImage и VirtualBox. Го туркаме подигнувачот во секторот за подигање на флопи дискот и ја ставаме датотеката .bin во коренот. Го зачувуваме во .vfd, ја одредуваме патеката до сликата на флопи дискот во својствата на виртуелната машина, ја стартуваме и го гледаме резултатот.

Во следното издание ќе ги разгледаме прекините, грешките, замките, абортусите и како тие функционираат, се фатени и дебагирани. Да почнеме да зборуваме за архитектурата.

Извори на информации.
1) Би сакал веднаш да изразам благодарност до Phantom_84 aka egos што ми го посочи вистинскиот пат и ми помогна на самиот почеток. Без него ќе ми беше многу потешко да го сфатам тоа.

Сите процесори Интел, почнувајќи од i80286 и до и вклучувајќи ги последните, кога ќе се вклучи напојувањето (по почетното „ресетирање“) тие работат во режим на реална адреса (реален режим). Типично, реалниот режим се користи или како среден режим за префрлување на заштитен режим по иницијализирање на микропроцесорски систем или за побрзо извршување на програми напишани за микропроцесори 8086 , 80186 , но, во споредба со 8086 , 80186 , современите микропроцесори во реален режим имаат поширок сет на извршни инструкции и можност за обработка на 32-битни операнди.
Префрлувањето на процесорот во заштитен режим од реален режим се врши со вчитување во CR0(сл. 1) зборови со една вредност на битот PE ( Заштити Овозможи). За компатибилност со софтверот за 80286, битот PE може да се постави и со помош на инструкцијата LMSW. Пред префрлување, потребните табели со дескриптори мора да се иницијализираат во меморијата IDTИ ГДТ. Веднаш по овозможувањето заштитен режим, процесорот има CPL = 0.

Ориз. 1

За сите 32-битни процесори, се препорачува следнава низа чекори за да се префрлите на заштитен режим:
1. Оневозможете ги прекините што може да се маскираат со ресетирање на знамето IF и блокирајте ја појавата на прекини што не можат да се маскираат со надворешна логика. Програмскиот код за време на „преодниот период“ мора да гарантира отсуство на исклучоци и да не користи софтверски прекини. Ова барање е предизвикано од промена на механизмот за повикување на ракувачи со прекини.
2. Поставете на ГДТРосновна адреса ГДТ(ЛГДТ инструкции).
3. Инструкции MOV CROпоставете го знамето PE и ако е потребно управување со меморијата на страницата, тогаш знамето PG.
4. Веднаш по ова, командата меѓусегмент скок ( JMP Далеку) или јавете се ( ЈАВИ Далеку) да го исчистите редот од инструкции декодирани во реален режим и да извршите серијализација на процесорот. Ако страничењето е овозможено, тогаш шифрите на инструкциите MOV CROИ JMPили ПОВИКмора да биде на страница за која физичката адреса е иста со логичката адреса (за кодот на кој се пренесува контролата, ова барање не се наметнува).
5. Ако планирате да користите локална табела со дескриптори, инструкцијата LLDTизбирач на сегмент на оптоварување за LDTдо регистарот LDTR
6. Инструкции LTRвчитување на избирачот во регистарот на задачи ТССза задачата на почетниот заштитен режим.
7. Повторно вчитајте ги регистрите на сегменти (освен CS), чија содржина сè уште припаѓа на реалниот режим, или извршете транзиција или повикајте друга задача (во овој случај, регистрите ќе се вчитаат повторно автоматски). Неискористените сегментни регистри се вчитуваат со вредност на избирачот нула.
8. Инструкции LIDTвчитај во регистарот IDTRадреса и ограничување IDT— табели на дескриптори за прекини на заштитен режим.
9. Дозволете хардверски прекини што можат да се маскираат и не можат да се маскираат

Оваа статија дава вовед во развојот на програми кои работат во режим на заштитен процесор. Овде ќе бидат наведени главните задачи на која било програма што работи во заштитен режим и ќе бидат дадени нивните решенија. Во основа, програмите ќе бидат напишани на јазикот FASM.

Работни режими на процесорот Intel 80386

Со доаѓањето на процесорот Интел 80386се појави архитектура IA32. Претпоставуваше појава на нов режим на работа на процесорот - заштитен (" Заштитен режим").За компатибилност со претходните процесори во линијата Интел 80х86Процесорот 80386 не започна веднаш во заштитен режим, туку работеше во таканаречениот реален режим (“ Реален режим"). Покрај тоа, секој режим има еден или повеќе подмоди. Ајде да ги погледнеме.

Вистински режим

Процесорот е во овој режим веднаш по притискање на копчето „ Моќ"компјутер. Пристапот до меморијата во реален режим се врши со конструкцијата" сегмент: поместување", што ја опишува логичката адреса. Вредноста на сегментот, како и поместувањето, се движи од 0 пред 0FFFFh.

Бидејќи адресирањето може да се направи само во еден сегмент, максималната големина на сегментот е 64 килобајт Физичката адреса, која е поставена на магистралата за адреси на процесорот, се пресметува според формулата:

линеарна адреса = сегмент * 16 + поместување

Процесори во вистински режим 80186 И 8086 вредноста на сегментот се движеше од 0 пред 0F000h. Така, максималната изложена адреса на адресната магистрала е 0FFFFFh, што одговара на (2^20)-1 , т.е. 1 мегабајт.

Се разбира, на почетокот обемот на таквата меморија изгледаше колосален, но со текот на времето еден мегабајт стана недоволен. Со доаѓањето на процесорот 80286 стана достапен таканаречениот мемориски блок У.М.Б., почнувајќи од адресата 0FFFFh:0010hа завршува со адреса 0FFFFh:0FFFFh(65520 бајти над еден мегабајт). Сега можете повторно да го конфигурирате оперативниот систем MS-DOSтака што го зазема овој блок, ослободувајќи 64 килобајти во RAM меморијата.

Заштитен режим

Овој режим има комплексен дизајн во споредба со реалниот. Логичка адреса е претставена со конструкцијата " избирач: поместување„.Селекторот се движи од 0 пред 0FFFFh(всушност, има 4 пати помалку селектори - повеќе за ова во следните статии). Офсетот, за разлика од реалниот режим, е 32-битен, што ви овозможува да адресирате сегменти од 4 гигабајти. Логичката адреса се претвора во линеарна според следнава шема:

линеарна адреса = отсечка основа + поместување

Линеарната адреса последователно се става во адресната магистрала доколку режимот за адресирање на страницата не е овозможен. Во спротивно, линеарната адреса се претвора во физичка, па дури потоа се става во адресната магистрала. Покрај тоа, заштитениот режим ви овозможува да организирате виртуелна меморија, достигнувајќи големина до 64 терабајти и во зависност само од големината на хард дискот (на пример, истата датотека за страничење во Windowsимплементира виртуелна меморија). Речиси сите модерни оперативни системи работат во заштитен режим.

Мултитаскинг подрежим на заштитен режим

Овој режим ви овозможува да организирате мултитаскинг, односно можност за истовремено извршување на неколку задачи или мулти-кориснички систем.

Виртуелен режим 8086

Ова е исто така подрежим на заштитен режим кој ви овозможува да креирате виртуелна машина која делува како да е во реален режим, но всушност работи во заштитен режим.

Нереален режим

Ова е посебен под-режим на реален режим. Процесорот е во реален режим, но е адресиран до меморијата од страна на " избирач: поместување". На овој начин, достапна е меморија над 1 мегабајт. Во иднина ќе се разгледуваат заштитениот режим и неговите подмодови.

Прва програма: префрлете се на заштитен режим

Преминот во заштитен режим се врши со поставување на битот 0 регистрираат CR0. Преминот во реален режим се врши со ресетирање на истиот нулти бит. Размислете за програма што ја извршува оваа операција (јазик - Рамен склопувач):

употреба16 ; Користи 16-битни инструкции

org 100ч

Започнете:

; Ние сме во реален режим

mov eax, cr0 ; Читање на вредноста на регистарот CR0
илиал, 1 ; Поставете го нултиот бит
mov cr0, eax ; Напишете ја новата вредност CR0

; Ние сме во заштитен режим

mov eax, cr0 ; Читање на вредноста CR0
и al, 0feh ; Ресетирајте го нултиот бит на 0
mov cr0, eax ; Ајде да одиме во реален режим

; Ние сме во реален режим

рет ; Излезете од програмата

Сепак, оваа програма е целосно сурова бидејќи во неа не може да се имплементира looping. Ако пишувате команди како hltили jmp$, тогаш кога ќе се активира првиот прекин, компјутерот ќе се рестартира.

Во нашиот случај, командите се активираат доста брзо, но можно е во интервалот помеѓу извршувањето на која било команда во нашата програма, прекинот сепак да се активира, што ќе доведе до моментален неуспех и рестартирање. Затоа, треба да се грижите за прекините. Значи, да го погледнеме списокот повторно. Ова не може да се нарече прва програма (напротив, би отишла подалеку од нула), бидејќи не ги спроведува основните активности за префрлување на заштитен режим. За целосно да се префрлите на заштитен режим со минимални поставки, треба да ги извршите следните чекори:

1. проверете дали е можно да се префрлите на заштитен режим;

2. иницијализирај табели со дескриптори;

3. оневозможи прекини (и маскирани и не-маскирани);

4. отворена линија А20;

5. вчитување на регистри за контрола на меморијата;

7. мигрираат во 32-битен код сегмент со прескокнување на CS регистарот.

Но, доволно е првата програма да ги изврши чекорите 3, 4, 5. Потоа, лупингот нема да доведе до рестартирање на компјутерот. Ајде да погледнеме во секоја акција.

Оневозможувањето на прекините не спречува да се рестартираме. Прекините се поделени и на маскирачки и на немаскибилни. За да ги оневозможите прекините што можат да се маскираат, треба да го ресетирате знамето АКОрегистрираат ЕЗНАМЕтим кли, прекините се овозможени со командата сти. Прекините што не се маскираат се забранети на малку поинаков начин. Постојат два начини да го направите ова: програмирање на регистрите на контролорот за прекини (за овој метод ќе се дискутира малку подоцна) или промена на седмиот бит од портот 70 ч: ако битот е поставен, тогаш прекините се оневозможени, ако битот се ресетира, прекините може да се извршат.

Сега да се запрашаме која е функцијата на линијата А20, Па што е ова. Линија А20- една од 32 линии за адреси. Кога компјутерот ќе се подигне, линијата А20затворена. Ова резултира со генерирање на 20-битни адреси (односно, целиот адресен простор е еднаков на (2^20)=1 мегабајт). Ова е вклучено за компатибилност со процесорот. 8086 : на тој начин, обидувајќи се да запишете на линеарна адреса 12345678ч, ние всушност ќе го запишеме на 00045678ч, што може да доведе до сосема неочекувани резултати. Затоа, за целосно функционирање на 32-битна апликација, линијата А20мора да биде отворен. Ова се прави со поставување на битот 1 пристаниште 92ч, линија затворање А20- ресетирајте го овој бит.

Читателот веќе е запознаен со последната акција и таа повеќе не треба да му поставува прашања.

Значи, да го погледнеме списокот на нашата нова, прва програма, во која веќе се спроведува мал циклус. Линиите што се додадени на претходната листа се означени со ѕвездичка (*).

org 100ч

Започнете:

; Ние сме во реален режим

кли ;*

во al, 70h ;*
или al, 80h ;*
надвор 70 часот, ал ;*

; Отворете ја линијата А20

во al, 92h ;*
или al, 2 ;*
надвор 92h, al ;*

mov eax, cr0
илиал, 1
mov cr0, eax


; Мала двојна јамка

mov cx, 20 ;*

циклус: ;*
movсекира, cx ;*
mov cx, 0ffffh ;*
јамка $ ;*
mov cx, секира ;*
јамкациклус ;*

mov eax, cr0
и al, 0feh
mov cr0, eax

; Затворете ја линијата А20

во al, 92h ;*
и al, 0fdh ;*
надвор 92h, al ;*

во al, 70h ;*
и al, 7fh ;*
надвор 70 часот, ал ;*

сти ;*

рет ; комплетирајте ја програмата

Можете да бидете сигурни дека програмата работи со извршување на извршната датотека од чиста MS-DOS. Ако програмата излезе правилно, тогаш сè е во ред.

Сепак, може да се појават и следниве проблеми:

1. компјутерот замрзнува“;

2. компјутерот се рестартира.

Ова може да се случи поради следниве причини:

1. програмата се стартува во режим V86(виртуелен режим 8086 );

2. програмата се стартува во заштитен режим или под одреден оперативен систем.

Затоа, пред да стартувате која било програма што работи во заштитен режим, треба да проверите дали програмата може да продолжи да работи. Ова ќе се дискутира понатаму.

Проверка на можноста за префрлување во заштитен режим

Во претходното поглавје го имавме следниот проблем: програмата не препознава дека е во заштитен режим или режим V86, што доведува до замрзнување или рестартирање на системот. Ако се обидеме да ја извршиме програмата под оперативниот систем Windows, Тоа Windowsќе го фати обидот на програмата да се префрли на заштитен режим и ќе понуди да се рестартира во режим на емулација MS-DOS(за платформа 9x), или насилно прекинете ја програмата (платформа НТ).

Значи, за да провериме дали навистина сме во реален режим, треба да ги извршиме следните операции:

1. проверете го нултиот бит на регистарот CR0;

2. Проверете дали оперативниот систем Windows не е вчитан.

Првата операција се изведува со директно читање на регистарот CR0со понатамошна проверка на нултиот бит од регистарот EAX, секираили АЛ. Ако битот не е поставен, тогаш сме во реален режим. Во спротивно, понатамошното извршување на програмата станува бесмислено.

Второто дејство се врши со повикување на функцијата 1600чпрекинува 2fh. Оваа функција ви овозможува да ја добиете тековната верзија на оперативниот систем Windows. Ако по повикувањето на функцијата во регистарот АЛсодржи нула, тогаш оперативниот систем не е вчитан. Во спротивно, повторно, нема смисла нашата програма да продолжи понатаму.

Размислете за примерот на следната програма. Тоа е модификација на претходната програма, сите нови инструкции се означени со ѕвездичка (*).

Организација 100ч

Започнете:

; Поставете сегментни регистри

movсекира, cs ;*
mov ds, секира ;*

; Проверка дали навистина сме во реален режим

mov eax, cr0 ;* проверете дали има нула бит
тест al, 1 ;* регистар CR0
јз no_pm ;*

movах, 09h ;* DOS функција 09h
mov dx, pm_msg ;* излез на линија
инт 21 часот ;*
рет;* и излезете

no_pm:
; Проверка дали програмата работи под Windows

movсекира, 1600ч ;* 1600h мултиплексер функција
инт 2fh ;* прекинува - добијте верзија на Windows
тестал, ал ;* ако не 0 - грешка
јзнема_прозорци

; Прикажи порака за грешка

movах, 09 часот ;*
mov dx, win_msg ;*
инт 21 часот ;*
рет ;*

no_windows:
; Дефинитивно сме во реален режим
; Оневозможи прекини што можат да се маскираат

; Оневозможи прекини што не можат да се маскираат (NMI)

воАл, 70 ч
илиАл, 80ч
надвор 70 часот, ал

; Отворете ја линијата А20

воАл, 92 ч
илиал, 2
надвор 92ч, ал

; Префрлете се на заштитен режим

mov eax, cr0
илиал, 1
mov cr0, eax

; Сега сме во заштитен режим
; Мала двојна јамка

mov cx, 20

циклус:
movсекира, cx
mov cx, 0ffffh
јамка $
mov cx, секира
јамкациклус

; Префрлете се на вистински режим

mov eax, cr0
и al, 0feh
mov cr0, eax

; Затворете ја линијата А20

во al, 92h ;*
и al, 0fdh ;*
надвор 92h, al ;*

; Овозможи прекини што не се маскираат (NMI)

во al, 70h ;*
и al, 7fh ;*
надвор 70 часот, ал ;*

; Овозможи прекини што можат да се маскираат

сти ;*

; Се вративме во реален режим

рет ; комплетирајте ја програмата

; Пораки за грешка

pm_msg: ;*
db "Грешка: веќе работи во заштитен режим!$" ;*
win_msg: ;*
db „Грешка: откриен е Microsoft Windows!$“ ;*
Овој пример, исто така, сè уште не покажува имплементација на 32-битни команди. За да го направите ова, треба да се запознаете и со материјалот во следното поглавје. Покрај тоа, примерот го има следниот недостаток: се повикуваат функциите ДОС (инт 21ч), што веќе почнува да противречи на независноста на нашата програма од оперативниот систем MS-DOS. Во иднина, ќе треба да се ослободите од користењето на функциите на оперативниот систем и да се префрлите на користење на функции BIOS-от. Но, засега е доволно да се ограничиме на овој код.

Моментално играм со x86 Assember за да ги подобрам моите програмски вештини на ниско ниво. Моментално имам мал проблем со шемата за адресирање во 32-битен заштитен режим.

Ситуацијата е следна:

Имам програма вчитана на 0x7e0 што го префрла процесорот во заштитен режим и скока до соодветната ознака во кодот:

[...] код за префрлување на процесорот во заштитен режим [...] jmp ProtectedMode [...] битови 32 ProtectedMode: .halt: hlt jmp .halt

Досега се работи одлично. „Jmp ProtectedMode“ работи без експлицитен далечен скок за да ја исчисти редицата за претходно преземање, бидејќи оваа програма се вчитува со поместување 0 (org 0 на почетокот), принудувајќи го сегментот на кодот да покаже на вистинското место.

Мојот моментален проблем е што во кратенката „ProtectedMode“ сакам да одам на друга програма вчитана од 0x8000 (ова го тестирав со мемориски пад, функцијата за вчитување работеше правилно и програмата се вчита правилно до 0x8000).

Бидејќи процесорот сега е во ProtectedMode наместо во RealMode, шемата за адресирање е различна. ProtectedMode користи дескриптори за да ја побара основната адреса и ограничувањето во табелата со дескриптори за да го додаде даденото поместување и да ја добие физичката адреса (како што јас разбирам). Затоа, GDT мораше да се инсталира пред да може да се внесе ProtectedMode.

Моето изгледа вака:

%ifndef __GDT_INC_INCLUDED__ %define __GDT_INC_INCLUDED__ ;******************************** ;* Глобална табела со дескриптори (GDT) * ; ********************************* NULL_DESC: дд 0 ; нула дескриптор dd 0 CODE_DESC: dw 0xFFFF ; граница ниска dw 0 ; база ниска db 0 ; база среден db 10011010b ; пристап db 11001111b; грануларност db 0 ; основна висока DATA_DESC: dw 0xFFFF ; дескриптор на податоци dw 0 ; ограничување на ниско db 0 ; база ниска db 10010010b ; пристап db 11001111b; грануларност db 0 ; основна висока gdtr: Ограничување dw 24 ; должина на базата GDT dd NULL_DESC ; основа на GDT %endif ;__GDT_INC_INCLUDED__

и се вчита во регистарот GDT преку

Lgdt

Она што сè уште не го сфатив е како сега да одам на физичката адреса 0x8000 во ProtectedMode користејќи GDT?

Моите први мисли беа да изберам дескриптор на кодот (CODE_DESC) кој треба да покажува на 0x7e00 (се вчитани тековните програми) и да го искористам поместувањето потребно за да добиете 0x8000 (512 бајти), што резултира со команда за скок:

Jmp CODE_DESC: 0x200

Но, тоа не функционира.

Jmp 0x7e0:0x200

не работи ни...

Имате ли идеја што ми недостасува овде? Можеби пропуштив нешто важно за 32-битната шема за адресирање ProtectedMode и употребата на GDT.

Целосен код:

Битови 16 org 0 ; натоварено со офсет 0000 (phys addr: 0x7e00) jmp Почеток Старт: xor ax, ax mov ax, cs mov ds, ax ; ажурирање на податочниот сегмент cli ; јасни прекини lgdt ; вчитај го GDT од GDTR (види gdt_32.inc) повик OpenA20Gate ; отворете го повикот на портата A20 EnablePMode ; скока во ProtectedMode ;******************** ;* Ја отвора портата A20 * ;******************** OpenA20Gate: во al, 0x93; прекинувач A20 портата преку брза A20 порта 92 или al, 2 ; поставете A20 Gate bit 1 и al, ~1 ; исчистете го INIT_NOW 0x92, повторно ;**************************** ;* Овозможува заштитен режим * ;******** ****************** EnablePMode: mov eax, cr0 или eax, 1 mov cr0, eax jmp ProtectedMode ; ова функционира (прескокнува на ознака и запира) ;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; => не работи ;jmp 08h:ProtectedMode , => не работи ;**************** ;* полиња со податоци * ;* &вклучува * ;******** ******* %вклучи "gdt_32.inc" ;******************** ;* Заштитен режим * ;*********** * ***** битови 32 ProtectedMode: ;тука сакам да прескокнам на физичкиот додаток 0x8000 (програма elf64 asm) .halt: hlt jmp .halt

11