اینکه کل برنامتونو اینجا درخواست کنید که براتون بنویسن ایده جالبی نیست و باعث میشه تا از یاد گیری و تحقیق عقب بمونید.
بهرحال
برای انجام یه همچین پروژه ای شما نیاز به یه سری اطلاعات دارید که اول به اونا می پردازیم:
1- سیستم به موقع بوت شدن یک سکتور یعنی 512 بایت که در مورد هارد MBR یا همون master boot Record و در مورد فلاپی هم که تنها بوت سکتور فلاپی هست رو به آدرس 0000:7C00 بارگذاری کرده و بعد به اون آدرس jump می کند از این لحظه به بعد کنترل کامپیوتر را برنامه شما یا هر OS دیگری در دست می گیرد.
2- باید توجه داشته باشید که زمانی که تازه سیستم میخواد بالا بیاد DOS ای وجود ندارد که بتوانید از سرویسهای آن استفاده کنید و تنها امکانات BIOS و پورت ها رو دارید که ازشون استفاده کنید.
3- بهتره برنامه اصلی شما EXE نباشه و به جای اون از فایل COM استفاده کنید چون از اولین دستور میشه نوشت رو بوت سکتور.
4- لحظه ای که کنترل CPU دست برنامه شما میاد شما نمی دونید SS و SP چه وضعیتی دارن بنابراین باید فورا اونارو به یه جای امن Init بکنید.
5- شما نباید table بوت سکتور رو که از آفست 3 تا 3C هست رو تخریب کنید چون در این صورت سیستم عامل قادر به خواندن از روی اون فلاپی نخواهد بود.
ما برای انجام این پروژه دو تا برنامه خیلی کوچک نیاز داریم که یکی برنامه بوت سکتور و دیگری برنامه ای که بتوانیم به کمک آن برنامه اول را در بوت سکتور فلاپی بنویسیم. پس از برنامه اول شروع میکنیم.
برنامه اول
.286C
CDS SEGMENT
ASSUME CS:CDS , DS:CDS , ES:CDS , SS:CDS
ORG 100h
BEGIN:
JMP MAIN
BOOTTABLE DB 3Ch DUP (?)
MAIN PROC NEAR
XOR AX,AX
CLI
MOV SS,AX ; SET SS:SP
MOV SP,7C00h ;
STI ;
MOV AH,03h ; Function No
MOV BL,00h ; Page Number
INT 10h
; Now
MOV AH,13h ; AH=13h (Bios Video Interrupt Function No)
MOV AL,01 ; AL=03h (String is chars only, attribite in BL
MOV BH,00h ; BH=00h (Video Page Number)
MOV BL,07 ; BL=07h (String Attribute)
; DH and DL are ready due to previous bios call for getting cursor pos
MOV CX,29 ; String Length
MOV BP,OFFSET SAMPLE_STR
; we know our program will load to 0000:7C00h not 100h
; so correct the compiler offset
ADD BP,7B00h
PUSH CS
POP ES
INT 10h
MOV AH,00h ; Wait For Input Func No
INT 16h ; Bios keyboard Service
; we JMP FFFF:0000 for reboot system but in opcode
; because assembler will not accept far jumps
DB 0EAh,00h,00,0FFh,0FFh ; for reboot system
MAIN ENDP
SAMPLE_STR DB ' Press any key to Reboot...',7
CDS ENDS
END BEGIN
فرض بر این گرفته شده از TurboAssembler برای اجرای برنامه استفاده می کنیم. همانطور که میبینید فضایی در ابتدای برنامه به طول 3C برای Boot Table در نظر گرفته شده اولین کار Stack را در 0000:7c00 مقدار دهی می کنیم تا مطمئن شویم به هنگام استفاده از Stack احتمال Overwrite شدن Stack روی کد برنامه وجود ندارد.
ما تابع 13 از وقفه شماره 10 bios را برای چاپ رشته استفاده خواهیم کرد و ناچار هستیم Position مکان نما را نیز به عنوان ورودی در DHو DL به آن پاس کنیم بنابراین Position را با استفاده از تابع شماره 3 می خوانیم. این تابع Position را در DH و DL قرار میدهد تابع 13 هم از همین رجیستر ورودی می گیرد بنابر این حداقل تا فراخوانی بعدی کاری با DX نداریم و سایر Register ها را مقدار دهی می کنیم. اگر در مورد وقفه ها Reference نداشتید میتوانید از برنامه بسیار ارزشمند HelpPC که ضمیمه شده کمک بگیرید. عدد 7 در آخر رشته کاراکتر چاپی نیست و وقتی سعی کنیم با استفاده از bios آن را چاپ کنیم سیستم Beep ایجاد خواهد کرد. پس از مقدار دهی ورودیهای تابع چاپ رشته و فراخوانی آن از تابع صفر وقفه 16 استفاده میکنیم تا منتظر فشرده شدن کلید توسط User به هنگام فراخوانی وقفه بمانیم.پس از آن با دستور JMP به آدرس FFFF:0000 کامپیوتر را Reset میکنیم.
برنامه دوم
.286C
CDS SEGMENT PARA 'CODE'
ASSUME CS:CDS , DS:CDS , ES:CDS , SS:CDS
ORG 100h
BEGIN:
JMP MAIN
TRYCNTR db 0
FNAME1 DB 'BOOTPROG.COM',0
STR1 DB 'Error : Cant make program system disk.$'
MAIN PROC NEAR
MOV AX,201h ;
MOV BX,OFFSET BUF ;
MOV CX,0001h ; Read Boot sector to buffer
XOR DX,DX ;
INT 13h ;
JNC CNTCODE1
INC TRYCNTR
CMP TRYCNTR,3
JZ ERROR
JMP MAIN
CNTCODE1:
MOV TRYCNTR,0
MOV AX,3D00h ;
MOV DX,OFFSET FNAME1 ; Open Program Boot Sector
INT 21h ; File
JC ERROR
MOV BX,AX ;
MOV AH,3Fh ; Read Program Boot Sector
MOV CX,137 ; to buffer+512
MOV DX,OFFSET BUF+512 ;
INT 21h ;
JC ERROR
MOV AH,3Eh ;
INT 21h ; Close File
MOV SI,OFFSET BUF+2 ;
MOV DI,OFFSET BUF+514 ; Copy Boot Setor Table
MOV CX,3Ch ; to Program Boot Sector
CLD ; Table
REP MOVSB ;
WRITEBOOTSEC:
MOV AX,301h ;
MOV BX,OFFSET BUF+512; Write Orginal Boot
MOV CX,0001h ; Sector to :
XOR DX,DX ; Track 0 Sector 1
INT 13h ;
JNC CODECNT2
INC TRYCNTR
CMP TRYCNTR,3
JZ ERROR
JMP WRITEBOOTSEC
CODECNT2:
RET
ERROR:
MOV AH,9
MOV DX,OFFSET STR1
INT 21h
RET
MAIN ENDP
BUF:
CDS ENDS
END BEGIN
این برنامه با استفاده از وقفه شماره 13 بوت سکتر فلاپی را به انتهای کد برنامه Load می کند و سپس برنامه بوت سکتور خودمان(همان برنامه اول که نوشته شد) را بلافاصله پس از آن Load می کند. 137 طول برنامه بوت سکتور خودمان است که مستقیما برای مختصر بودن برنامه در کد نوشتیم و پس از Copy کردن table اصلی بوت سکتور در ناحیه ای از برنامه که برای همین منظور رزرو کرده بودیم آن را در بوت سکتور می نویسد. در عملیات خواندن و نوشتن سکتور ها در فلاپی نباید کمتر از 3 بار Retry داشته باشیم چون در توابع bios تا 3 بار Error امری طبیعی است.
در آخر لازم به ذکر است TurboAssembler جهت کمپایل برنامه HelpPC به عنون یک Reference عالی و Source و نسخه کمپایل شده برنامه ها ارائه شده است.