|
Bajarilishi kerak bo'lgan vazifa
|
bet | 56/64 | Sana | 13.05.2024 | Hajmi | 183,36 Kb. | | #230077 |
Bog'liq Системное программирование, практикаBajarilishi kerak bo'lgan vazifa:
Interrupt shlyuzi yordamida faqat apparat klaviatura uzilishi bilan ishlov beradigan dastur yozing.
Amalga oshirish tartibi:
Buni amalga oshirish uchun siz IDT ni yaratishingiz, uning manzilini LIDT buyrug'i bilan yuklashingiz va IDTR registrida mavjud bo'lgan narsalarni haqiqiy rejimda yuklashni unutmang - manzil 0 va o'lcham 4 * 256, haqiqiy rejimni kesish vektoriga mos keladi. stol.
; pm2.asm
; Himoyalangan muhitda apparat uzilishlarini qayta ishlashni namoyish qiluvchi dastur; rejimi, 32-bitli himoyalangan rejimga o'tadi va terish imkonini beradi; 1 dan + gacha bo'lgan tugmalar yordamida matn. Backspace tugmasini bosish avvalgisini o'chiradi; belgisi, Esc tugmasini bosish - dasturdan chiqadi.;; TASMni tuzish:; tasm /m /D_TASM_ pm2.asm
; (yoki 3.x versiyalari uchun tasm /m pm2.asm etarli)
; tlink /x /3 pm2.obj; WASM kompilyatsiyasi:; wasm /D pm2.asm; wlink fayli pm2.obj shakli DOS;; Turli assemblerlar 32-bitli ofsetni yozishdagi o'zgarishlar; 16 bitli o'zgaruvchiga segment: ifdef _TASM_so equ small offset ; TASM 4.xelseso equ ofset; WASMendif; MASM uchun, ehtimol, siz o'zgartiradigan qo'shimcha kod qo'shishingiz kerak bo'ladi; IDTda ishlatiladigan ofsetlar
.386r
RM_seg segmenti umumiy "KOD" uchun 16farz qiling cs:RM_seg,ds:PM_seg,ss:stack_segstart:; aniq screenmov ax, 3int 10h; segment registrlarini tayyorlash push PM_segpop ds; biz allaqachon PMmov eax,cr0test al,1jz no_V86 da ekanligimizni tekshiring; hisobot va exitmov dx, shuning uchun v86_msgerr_exit:mov ah,9int 21hmov ah,4Chint 21h; Balki Windows 95 PE = O?no_V86:mov ax,1600hint 2Fhtest al,aljz no_windows; hisobot va exitmov dx, shuning uchun win_msgjmp qisqa err_exit; shuning uchun biz aniq real rejimdamiz
no_windows:
; barcha foydalanilgan segment deskriptorlari uchun hisoblash asoslarixor eax,eaxmov ax,RM_segshl eax,4mov word ptr GDT_16bitCS+2,ax ; 16bitCS bazasi RM_segshr eax,16mov bayt ptr GDT_16bitCS+4,almov ax,PM_segshl eax,4mov word ptr GDT_32bitCS+2,ax bo'ladi; barcha 32bit* ning asosi mov word ptr GDT_32bitSS+2,ax bo'ladi; PM_segmov word ptr GDT_32bitDS+2,axshr eax,16mov bayt ptr GDT_32bitCS+4,almov bayt ptr GDT_32bitSS+4,almov bayt ptr GDT_32bitDS+4,al; chiziqli manzilni hisoblash GDTxor eax,eaxmov ax,PM_segshl eax,4push eaxadd eax,ofset GDTmov dword ptr gdtr+2,eax; yuk GDTlgdt fword ptr gdtr; chiziqli manzilni hisoblash IDTpop eaxadd eax,ofset IDTmov dword ptr idtr+2,eax; yuk IDTlidt fword ptr idtr; agar biz 32 bitli xotira bilan ishlamoqchi bo'lsak, A20in al,92hor al,2out 92h,al ochishga arziydi; uzilishlarni o'chirish, cli; shu jumladan NMI, al,70hor al,80hout 70h,al; PMmov eax,cr0or al,1mov cr0,eax ga o‘ting
; SEL_32bitCS ni CS
db 66hdb 0EAhdd ofset PM_entrydw SEL_32bitCSRM_return ga yuklang:; RMmov eax,cr0va al,0FEhmov cr0,eax ga o‘ting; navbatni tiklash va CS ni haqiqiy raqam bilan yuklash db 0EAhdw $+4dw RM_seg; registrlarni real modemov ax,PM_segmov ds,axmov es,axmov ax,stack_segmov bx,stack_lmov ss,axmov sp,bx da ishlash uchun sozlash; real modemov uchun IDTR yuklash ax,PM_segmov ds,axlidt fword ptr idtr_real; ruxsat berish NMIin al,70hand al,07FHout 70h,al; uzilishlarni yoqish; va exitmov ah,4Chint 21hRM_seg tugaydi
; 32-bitli
PM_seg segmenti umumiy "CODE" uchun 32assume cs:PM_seg; GDI va IDT jadvallari mos kelishi kerak, shuning uchun biz ularni joylashtiramiz; segmentGDT yorlig'ining boshida bytedb 8 dup(0); Baza = 0GDT_flatDS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0 bo'lgan 32-bitli 4GB segment; RM_seg GDT_16bitCS db 0FFh,0FFh,0,0,0,10011010b,0,0
bazasi bilan 16 bitli 64 kilobayt kodli segment
; PM_segGDT_32bitCS db 0FFh,0FFh,0,0,0,10011010b,11001111b,0 bazasiga ega 32 bitli 4 gigabaytlik kod segmenti; PM_segGDT_32bitDS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0 bazasi bilan 32 bitli 4 gigabaytlik ma'lumotlar segmenti; 32-bitli 4 GB ma'lumotlar segmenti stack_segGDT_32bitSS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0gdt_size = $ - GDTgdtr dw gdt_size-1 ; GDTdd chegarasi? ; GDT chiziqli manzili; selektorlar uchun nomlarSEL_flatDS equ 001000bSEL_16bitCS equ 010000bSEL_32bitCS equ 011000bSEL_32bitDS equ 100000bSEL_32bitSS equ 101000b
; uzilish deskriptor jadvali IDT
IDT yorliq bayti; bu deskriptorlarning barchasi 0Eh tipidagi - 32 bitli uzilish eshigi; INT 00 - 07dw 8 dup(so int_handler,SEL_32bitCS,8E00h,0); INT 08 (irq0)dw shunday irq0_7_handler,SEL_32bitCS,8E00h,0; INT 09 (irq1)dw shunday irq1_handler,SEL_32bitCS,8E00h,0; INT 0Ah - 0Fh (IRQ2 - IRQ8)dw 6 dup(shuning uchun irq0_7_handler,SEL_32bitCS,8E00h,0); INT 10h - 6Fhdw 97 dup(so int_handler,SEL_32bitCS,8E00h,0); INT 70h - 78h (IRQ8 - IRQ15)dw 8 dup(shuning uchun irq8_15_handler,SEL_32bitCS,8E00h,0); INT 79h - FFhdw 135 dup(so int_handler,SEL_32bitCS,8E00h,0)idt_size = $ - IDT ; hajmi IDTidtr dw idt_size-1 ; IDTdd chegarasi? ; IDT boshlanishining chiziqli manzili; IDTR registrining mazmuni real modeidtr_real dw 3FFh,0,0
; ishga tushirilganda xato xabarlari
v86_msg db "Protsessor V86 rejimida - siz PM$ ga o'ta olmaysiz" win_msg db "Dastur Windows ostida ishlayapti - 0$ jiringlashiga o'ta olmaysiz"
; 0E skanerlash kodlarini ASCII scan2ascii db 0,1Bh,'1','2','3','4','5','6','7','8','9' ga aylantirish uchun jadval ,
'0′,'-','=',8screen_addr dd 0 ; ekrandagi joriy holati
; 32-bitli himoyalangan rejimga kirish nuqtasi
PM_entry:
; 32-bitli stek va boshqa registrlarni oʻrnatish
mov ax,SEL_flatDSmov ds,axmov es,axmov ax,SEL_32bitSSmov ebx,stack_lmov ss,axmov esp,ebx; uzilishlarni yoqish; va jmp qisqa $ abadiy tsiklini kiriting
; oddiy uzilish ishlovchisi
int_handler:iretd; apparat uzilishi ishlovchisi IRQ0 - IRQ7irq0_7_handler: push eaxmov al,20hout 20h,alpop eaxiretd; apparat uzilishi ishlov beruvchisi IRQ8 - IRQ15irq8_15_handler: push eaxmov al,20hout 0A1h,alpop eaxiretd; IRQ1 ishlov beruvchisi - klaviatura uzilishi irq1_handler: push eax ; bu apparat uzilishi - save registerspush ebxpush espush dsin al,60h ; bosilgan tugmaning skanerlash kodini o'qing, cmp al,0Eh ; agar u maksimal ja skip_translate dan katta bo'lsa; biz xizmat ko'rsatamiz - ishlov bermang,cmp al,1 ; agar u Esc bo'lsa, je esc_pressed ; real rejimga kiring,mov bx,SEL_32bitDS ; else:mov ds,bx ; DS:EBX - skanerlash kodini ebx, ofset scan2ascii ni tarjima qilish uchun jadval; ASCIIxlatb da; convertmov bx,SEL_flatDSmov es,bx ; ES:EBX - joriy
mov ebx manzili,screen_addr ; ekran pozitsiyalari,
cmp al,8 ; agar Backspace bosilmasa, bs_pressedmov es:[ebx+0B8000h],al ; ekranga belgi yuborish, dword ptr screen_addr,2 qo‘shish; joylashuv manzilini 2 ga oshiring, jmp qisqa skip_translatebs_pressed: ; aks holda:mov al,' ' ; draw spacesub ebx,2 ; oldingi belgi pozitsiyasidamov es:[ebx+0B8000h],almov screen_addr,ebx ; va oldingi characterskip_translate manzilini saqlang: ; joriy sifatida; klaviaturada al,61hor al,80hout 61h,al; Interrupt controllermov al,20hout 20h,al uchun EOI yuborish; registrlarni tiklash va dspop espop ebxpop eaxiretddan chiqish; Escesc_pressed: bosilsa, boshqaruv IRQ1 ishlovchisidan bu yerga uzatiladi; klaviaturani yoqing, EOI yuboring va registrlarni tiklang, al,61hor al,80hout 61h,almov al,20hout 20h,alpop dspop espop ebxpop eax; real modeclidb 0EAhdd ofsetiga qaytish RM_returndw SEL_16bitCSPM_seg tugaydi
; Stak segmenti. Dasturning 16-bitli qismida 16-bit sifatida ishlatiladi va sifatida
; 32-bitli (SEL_32bitSS selektori orqali) 32-bit qismli stack_seg segmentida "STACK"
stack_start db 100h dup(?)
stack_l = $ - stack_start ; ishga tushirish uchun stek uzunligi ESPstack_seg endsend start
|
| |