<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Mohammadasdi</title>
        <link>https://virgool.io/feed/@Mohammadasdi</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-04-14 12:27:05</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/3270165/avatar/9X3LmP.png?height=120&amp;width=120</url>
            <title>Mohammadasdi</title>
            <link>https://virgool.io/@Mohammadasdi</link>
        </image>

                    <item>
                <title>ساخت یک سیستم عامل ساده با اسمبلی - پارت 03</title>
                <link>https://virgool.io/@Mohammadasdi/%D8%B3%D8%A7%D8%AE%D8%AA-%DB%8C%DA%A9-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D8%B9%D8%A7%D9%85%D9%84-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%BE%D8%A7%D8%B1%D8%AA-03-cnaincw2gc3x</link>
                <description>خب خب، اومدیم به پارت سوم، تا الان موفق شدیم سیستم عاملمون رو با fat16 اوکی کنیم تا بشه روی فلش بوتش کرد.RufusDiskmgrمن از اون پارت دوم یکمی کار کردم روش و تونستم root region رو هم اوکی کنم.در کل اینجوری شد فایل build.asm:format binary as &#039;img&#039;
use16

org 0x0000

FLOPPY_SIZE equ 2 * 80 * 18 * 512

include &#039;src/fat.asm&#039;
include &#039;boot.asm&#039;

display &#039;=========== InousOS ============&#039;, 0x0d, 0x0a
display &#039;  - Master Boot Record (MBR) has been created.&#039;, 0x0d, 0x0a

rb (RESERVED_SECTORS-1) * BYTES_PER_SECTOR

; ========== FAT Region ==========
clusters_size = BYTES_PER_SECTOR * SECTORS_PER_CLUSTER

macro fat_init list_file {
    repeat NUMBER_FAT_COPIES
        current_pos = $

        db MEDIA_DESCRIPTOR, 0xff       ; FAT_ENTRY1
        dw 0xffff                       ; FAT_ENTRY2

        irps file_name, list_file \{
            display &#039;  - FAT entry &#039;, %+47, &quot; has been created for file &#039;&quot;, file_name, &quot;&#039;.&quot;, 0x0d, 0x0a

            virtual at 0
                file file_name
                file_size = $
            end virtual

            file_clusters = (file_size + clusters_size - 1) / clusters_size

            if file_clusters = 0
                dw 0xffff
            else
                repeat file_clusters
                    if file_clusters = %
                        dw 0xffff
                    else
                        dw (% + 2)
                    end if
                end repeat
            end if
        \}

        rb (SECTORS_PER_FAT * BYTES_PER_SECTOR) - ($-current_pos)
    end repeat
}

fat_init &#039;build/kernel.bin&#039;

display &#039;  - FAT area has been initialized.&#039;, 0x0d, 0x0a
; ======== END FAT Region ========

; ========== ROOT Region =========
macro drive_init drive_name {
    DRIVE_NAME                      db drive_name
    ATTRIBUTE                       db 0x08
    RESERVED                        db 0x00
    CREATION                        db 0x00
    CREATION_TIME                   dw 0x0000
    CREATION_DATE                   dw 0x0021
    LAST_ACCESS_DATE                dw 0x0021
    RESERVED_FAT32                  dw 0x0000
    LAST_WRITE_TIME                 dw 0x0000
    LAST_WRITE_DATE                 dw 0x0021
    STARTING_CLUSTER                dw 0x0000
    DRIVE_SIZE                      dd 0x00000000
}

macro root_entry file_name {
    local FILE_NAME, FILE_EXT, ATTRIBUTE, \
          RESERVED, CREATION, CREATION_TIME, \
          CREATION_DATE, LAST_ACCESS_DATE, \
          RESERVED_FAT32, LAST_WRITE_TIME, \
          LAST_WRITE_DATE, STARTING_CLUSTER, DRIVE_SIZE

    virtual at 0
        file file_name
        file_size = $
    end virtual

    FILE_NAME                       db &#039;KERNEL  &#039;
    FILE_EXT                        db &#039;INU&#039;
    ATTRIBUTE                       db 0x20
    RESERVED                        db 0x00
    CREATION                        db 0x00
    CREATION_TIME                   dw 0x0000
    CREATION_DATE                   dw 0x0021
    LAST_ACCESS_DATE                dw 0x0021
    RESERVED_FAT32                  dw 0x0000
    LAST_WRITE_TIME                 dw 0x0000
    LAST_WRITE_DATE                 dw 0x0021
    STARTING_CLUSTER                dw 0x0003
    DRIVE_SIZE                      dd file_size
}

macro root_init list_file {
    irps file_name, list_file \{
        root_entry file_name
    \}
}

drive_init VOLUME_LABEL
root_init &#039;build/kernel.bin&#039;
root_init &#039;build/kernel.bin&#039;
; ======= END ROOT Region ========

rb FLOPPY_SIZE - ($-$$) - 1
db 0

display 0x0d, 0x0aیکمی جاها نیازمند تعریف متغیر و ایناس، و یکمی کار داره برای data region.فایل buildx.bat هم دادیم به هوش مصنوعی ( خودم زیاد batch script بلد نیستم ) و اینو داد:@echo off
setlocal enabledelayedexpansion

set SRC_DIR=src
set BUILD_DIR=build
set DIST_DIR=dist

if not exist %BUILD_DIR% mkdir %BUILD_DIR%
if not exist %DIST_DIR% mkdir %DIST_DIR%

for %%F in (%SRC_DIR%\*.asm) do (
    fasm %%F %BUILD_DIR%\%%~nF.bin
    if errorlevel 1 (
        pause
        exit /b 1
    )
)

fasm build.asm %DIST_DIR%\inous.img
if errorlevel 1 pauseدر کل گفتم بهش یک ساختار Make استاندارد بهش بده و اینو داد، تمام فایل هارو اسمبل میکنه در اخر هم سر هم میکنه.حالا من اینارو خودم اوکی میکنم، اومدم روی یک مبحث تمرکز کنم، بوت لودر ما باید کرنل رو لود کنه چون فایل سیستم داریم، میتونیم دو مدل ادرس دهی کنیم، یکیش اینه از مستقیم بپریم روی کرنل، یکیشم اینه که توی فایل سیستم دنبال کرنل بگردیم😐😂 خب راه حل دوم احمقانه اس! چون نمیتونیم که توی 512 بایت بیایم کرنل رو سرچ کنیم و منتظر بمونیم.حالا توی جلسه بعدی مستقیم میریم کد نویسی اسمبلی، تا الان هر چی بوده مبانی و مباحث ساخت سیستم عامل بوده که باید بلد باشین شما، الان میخوایم درباره‌ی درایور ها حرف بزنیم.ما میتونیم از وقفه های بایوس استفاده کنیم برای کیبورد و موس و یک پولینگ بزنیم که دیلی میده و زیاد جالب نمیشه، مثلا هر بار باید چک کنیم موس حرکت کرده؟ کجا حرکت کرده؟ کیبورد چیکار کرده؟ همچنین وقفه ها در حالت عادی کندن چون هر بار میرن به جدول ivt و دسترسی به همین جدول از طریق رم هست که سیکل پردازنده رو بالا میبره و در نتیجه کنده.ما اینجا باید درایور های سیستم عامل رو بنویسیم، چون لود کردن کرنل از بوت زیاد کار سختی نیست اول میریم درایور ها رو چک کنیم و بنویسیم. و اولم میریم سراغ کیبورد. کیبورد و موس یک پورت PS/2 دارن که ما با اون کار میکنیم و حرف میزنیم.PS/2 jacks for keyboard and mouseاصلا فکر نکنید کار سختیه، کل کدایی که قراره برای درایور کیبورد بنویسیم کمتر از 1 کیلوبایته:چون سیستم ما اموزشیه فقط پورت PS/2 ساپورت کنیم کافیه، شاید 2 یا 3 تا دیگه اضافی کنیم، بتونیم تقریبا کل سیستمارو ساپورت کنیم.فقط تنها کار سختش تبدیل اسکن کد به کاراکتره! چون ما مثلا اگه این کارو نکنیم اگه A رو بزنیم مثلا 1 رو چاپ میکنه😂 خب ما برنامه نویس های اسمبلی از if, elif, else و اینا بدمون میاد، و حال نداریم اینجوری بزنیم مثلا:if scancode == 0x1c:
    print(&#039;A&#039;)
elif scancode == 0x32:
    print(&#039;B&#039;)
elif scancode == 0x21:
    print(&#039;C&#039;)چون اینجوری نزدیک 300 تا باید if بزنیم، خب اینکه توی اسمبلی از 1 کیلوبایت بیشتر میشه که!یک چیزی داریم تو اسمبلی، مثل بلوک ترجمه میمونه، بهش یک چیزی میدی بهت یک چیز دیگه میده. مثلا اینجوریه:scancode = 0x1c

trans = bytes.maketrans(bytes(range(0xff)), b&#039;ABC........&#039;)
print(bytes.translate(scancode, trans))اینجوری فقط دو سه تا if دیگه میخوایم که برای کلید های ویژه هستن.قبلش باید مفهوم IRQ رو بدونین، خلاصش اینه که سخت افزار مثلا موس یا کیبورد وقتی بخواد به پردازنده بگه: &quot;داداش، فلانی کلید A من رو زد&quot;، میره در خونه رو میزنه، پردازنده در رو باز میکنه میبینه: عه این کیبورده، بعد به کیبورد میگه چیکارم داشتی، کیبورد هم میگه کلید A من رو زد.اما قبل ترش میومدن از پولینگ استفاده میکردن، یعنی هر بار که پردازنده بخواد کاری انجام بده، به کیبورد زنگ میزنه و میگه خبری هست یا نه؟ کیبورد هم میگه نه یا اره.یکجورایی مثل وب سوکت و http polling هست.درایور ها معمولا با IRQ نوشته میشن، سیستم عامل های مدرن هم همینجورین، مثلا:مثلا IRQ 1 مربوط به کیبورد هستIRQ 12 هم برای ماوسالان اگه بخوایم فنی تر بیان کنیم، میگیم اگه ما کلید A رو توی کیبورد بزنیم، مدار کیبورد اون رو میاد مثلا به 0x1c تبدیل میکنه، بعد با IRQ درخواست وقفه سخت افزاری میده به سی پی یو، بعد سی پی یو میره، به جدول ivt که مپ شده به IRQ و جامپ میکنه روی درایور. درایور هم میاد از کیبورد داده دریافت میکنه، مثلا اینارو:اسکن کد مربوط به یک کاراکتروضعیت فشار دادن کلید یا ول کردن کلیدهمچنین وضعیت کلید های ویژه مثل sleep، vol-up و ...بعد درایور میاد داده رو یکسری عملیات روش انجام میده و میفرسته به درایور گرافیک، اون هم میاد مثلا شکل کرسر موس رو روی مانیتور رسم میکنه، به همین راحتی!نکته: هر IRQ به یک ivt خاص وصل شده، مثلا IRQ 1 وصل شده به INT 9.کلا 15 تا IRQ داریم، بقیه چیزا مثل اسپیکر و پرینتر و ... بدون IRQ هستند، یادتونه در پارت اول گفتیم دستگاه های ورودی فقط میتونن IRQ به پردازنده بفرستن، بقیه چیزا رو فقط پردازنده به دستگاه ها میفرسته.حالا اگه بریم ته ماجرا، 32 تا وقفه اول رو اینتل رزرو کرده، بعد بایوس، اومده پورت های مثل IRQ 1 رو وصل کرده به int 9 ( مثلا خیلی خفنه 😂 )، اینجوری وقفه های خود سی پی یو با بایوس بهم میریزه و کلی مشکل پیش میاد ( دستش درد نکنه ).باید ما اول بیایم مپینگ IRQ به IVT رو درستش کنیم، مثلا IRQ 1 رو بجای 9 بکنیمش مثلا 20 ( در هگزادسیمال 32، اخرین وقفه رزرو خود اینتل 31 هست ) به بالا و اینجوری مشکل ها برطرف میشه.از جلسه بعدی بصورت عملی ساخت سیستم عامل رو شروع میکنیم و ساخت درایور های پایه و چیزای پایه و همه چیز.</description>
                <category>Mohammadasdi</category>
                <author>Mohammadasdi</author>
                <pubDate>Sat, 07 Feb 2026 19:48:04 +0330</pubDate>
            </item>
                    <item>
                <title>نوشتن یک سیستم عامل ساده با اسمبلی - پارت 02</title>
                <link>https://virgool.io/@Mohammadasdi/%D9%86%D9%88%D8%B4%D8%AA%D9%86-%DB%8C%DA%A9-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D8%B9%D8%A7%D9%85%D9%84-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%BE%D8%A7%D8%B1%D8%AA-02-p77uxtihhd6n</link>
                <description>اینو دارم دقیقا 7 دقیقه و 25 ثانیه و 15 میلی ثانیه بعد از پارت اول مینویسم😎😂 (ولی فردا یا پس فرداش منتشر میشه)چونکه سیستم عاملمون قراره با قابلیت دیباگ و اینا باشه باید بیایم یک فایل سیستم بسازیم و بندازیم توی کدامون.اگه از فایل سیستم استفاده نکنیم، برنامه هایی مثل rufus نمیتونن بخوننش و نمیتونن کپی کنن روی یو اس بی.چند تا فایل سیستم بود مثل Fat و exFat و Refs و Ntfs و من تصمیم گرفتم از Fat16 استفاده کنم که بهترین انتخاب برای 16 بیتیه، چون محاسباتش 16 بیتیه.اون نوار کوچیک سبزه 512 بایت بوت ماست که قراره توش داده های fat رو بریزیم.گفته بودم بایوس میاد 512 بایت اول رو میخونه، توی بوت سکتور میایم داده های fat16 رو میریزیم و یک مدیریت فایل خیلی بهینه و کوچیک که قراره بره کرنل رو از مسیر خاصی لود کنه.مثلا مسیرمون کرنلمون این باشه:X:/Inous/kernel.sysاون 512 بایت میاد میره توی پوشه Inous و فایل kernel.sys رو میندازه تو رم و بعد جامپ میکنه روش!اگه فایل سیستم رو نزنیم، مثل این میمونه توی شهر لس انجلس با یک نقشه کاغذی مسیریابی کنی. باید ادرس کرنل رو بصورت CHS و همچنین سایز رو بدیم تا بیاد اونو لود کنه. حالا دردسر LBA به CHS هم به کنار.وقتی داده هارو بریزیم از 512 بایت، فقط 448 بایت خالص باقی میمونهسه بایت اول که قراره جامپ کنه به اون 448 بایت باقی و فاصله شون دیتا هایی هست که ما باید پر کنیمشون که تقریبا میشن 59 بایت داده، چونکه ما بصورت 16 بیتی داریم به قبل از 255 جامپ میکنیم، دو بایت میشه جامپمون، اون یکی رو باید با nop پر کنیم، در اخر هم کد جادویی بوت 0xaa55 رو میزاریم.پس این میشه فایل جدید boot.asm:use16

org 0x7c00

jmp boot

nop

BOOT_SIZE equ 512

BPB Fat16

boot:
cli
hlt

rb BOOT_SIZE - ($-$$) - 2
dw 0xaa55اینم فایل جدید به اسم fat.asm:use16

OEMID                           equ &#039;INOUS   &#039;
BYTES_PER_SECTOR                equ 512
SECTORS_PER_CLUSTER             equ 1
RESERVED_SECTORS                equ 1
NUMBER_FAT_COPIES               equ 2
NUMBER_ROOT_ENTRIES             equ 512
SMALL_NUMBER_SECTORS            equ 2 * 80 * 18
MEDIA_DESCRIPTOR                equ 0xf0
SECTORS_PER_FAT                 equ 12
SECTORS_PER_TRACK               equ 18
NUMBER_HEADS                    equ 2
HIDDEN_SECTORS                  equ 0
LARGE_NUMBER_SECTORS            equ 0
DRIVE_NUMBER                    equ 0
RESERVED_NT                     equ 0
EXT_BOOT_SIG                    equ 0x29 
VOLUME_SERIAL                   equ 0x57694123
VOLUME_LABEL                    equ &#039;LOCAL DISK &#039;
FILESYSTEM_TYPE                 equ &#039;FAT16   &#039;

struc Fat16 {
    .OEMID                                db OEMID
    .BYTES_PER_SECTOR                     dw BYTES_PER_SECTOR
    .SECTORS_PER_CLUSTER                  db SECTORS_PER_CLUSTER
    .RESERVED_SECTORS                     dw RESERVED_SECTORS
    .NUMBER_FAT_COPIES                    db NUMBER_FAT_COPIES
    .NUMBER_ROOT_ENTRIES                  dw NUMBER_ROOT_ENTRIES
    .SMALL_NUMBER_SECTORS                 dw SMALL_NUMBER_SECTORS
    .MEDIA_DESCRIPTOR                     db MEDIA_DESCRIPTOR
    .SECTORS_PER_FAT                      dw SECTORS_PER_FAT
    .SECTORS_PER_TRACK                    dw SECTORS_PER_TRACK
    .NUMBER_HEADS                         dw NUMBER_HEADS
    .HIDDEN_SECTORS                       dd HIDDEN_SECTORS
    .LARGE_NUMBER_SECTORS                 dd LARGE_NUMBER_SECTORS
    .DRIVE_NUMBER                         db DRIVE_NUMBER
    .RESERVED_NT                          db RESERVED_NT
    .EXT_BOOT_SIG                         db EXT_BOOT_SIG
    .VOLUME_SERIAL                        dd VOLUME_SERIAL
    .VOLUME_LABEL                         db VOLUME_LABEL
    .FILESYSTEM_TYPE                      db FILESYSTEM_TYPE
}برای ساختار داده fat16 یکدونه struc ساختیم که مثلا وقتی زدیم:BPB Fat16
mov bx, [BPB.BYTES_PER_SECTOR]به درستی کار کنه، و داده های خود بوت با داده های فت 16 با هم دیگه قاطی نشن، در اینجا BPB به معنی (BIOS Parameter Block ) هست، حالا میرسیم به قسمت سخت ماجرا، ما باید همزمان سه بخش از فلاپی رو کنترل کنیم، یکدونه خود FAT یکدونه هم Root Entry و اون یکی منطقه داده یا (Data Region) هست.در ساختار bpb ما اومدیم یکسری اطلاعات پایه رو اوکیش کردیم، دقت داشته باشید VOLUME_SERIAL باید 32 بیتی باشه و رندوم باشه، منم یک چیز رندوم زدم😅عجب!!!الان باید فایل kernel.asm رو اسمبل کنیم و بزاریمش توی سه ناحیه ای که گفتم، اینجا دیگه نمیشه از اسمبلی استفاده کرد، باید از زبان جمع و جور خود fasm در طول اسمبل استفاده کنیم.باید در اینجا کار با ویرچوال رو بلد باشین، چون:برای FAT باید سایز فایل رو بدونمبرای سایز فایل باید data رو include کنمولی data بعد از FAT میاد 😐و چون اسمبلر خطی میره جلو و seek نمیکنه باید از ویرچوال استفاده کنیم!پس ما اول بریم fat رو اوکی کنیم، خود fat دو کلستر رو رزرو کرده، که اونام 0 و 1 هستن.برای تنبل ها...اول میایم کرنل رو توی ویرچوال میزاریم و حجمشو حساب میکنیم و بعد یک حلقه ایجاد میکنیم و میگیم توش ایا این اخرین کلستر هست یا نه، اگه بود 0xffff میزاره، در غیر اینصورت میاد شماره کلستر بعدی رو میفرسته.پنج نوع معتبره، ولی فعلا فقط با سه تاشون کار داریممیایم فایل build.asm:format binary as &#039;img&#039;
use16

org 0x0000

FLOPPY_SIZE equ 2 * 80 * 18 * 512

include &#039;fat.asm&#039;
include &#039;boot.asm&#039;

org 0x7d00

; ========== FAT Region ==========
virtual at 0
    file_start:
        include &#039;kernel.asm&#039;
    file_end:
end virtual

clusters_size = BYTES_PER_SECTOR * SECTORS_PER_CLUSTER

rept NUMBER_FAT_COPIES i:1 {
    current_pos = $
    FAT#i#_ENTRY1:                      db 0xff, MEDIA_DESCRIPTOR
    FAT#i#_ENTRY2:                      dw 0xffff

    file_size = file_end - file_start
    file_clusters = (file_size + clusters_size - 1) / clusters_size

    if file_clusters = 0
        dw 0xffff
    else
        repeat file_clusters
            if file_clusters = %
                dw 0xffff
            else
                dw (% + 2)
            end if
        end repeat
    end if

    rb (SECTORS_PER_FAT * BYTES_PER_SECTOR) - ($-current_pos)
}
; ======== END FAT Region ========

rb FLOPPY_SIZE - ($-$$) - 1
db 0الان اومدیم فایل کرنل رو لود کردیم و کاراشو انجام دادیم البته فقط بخش fat، اخر سر میایم یک پیمایش لیستی برای بقیه فایل ها میزاریم. الان باید بریم root region.ساختار Dir Entriesتوی این ساختار فقط میشد 8 کاراکتر نام انتخاب کرد و 3 کاراکتر پسوند ( فقط حروف انگلیسی و اعداد و یکسری علامت )، بیشتر از اون نمیشد نام انتخاب کرد، اگه نام هم کوچیک بود و یا پسوند نداشت با space (0x20) میومدن پدینگ میزدن، اما بعدش یک ساختار دیگه هم بهش اضافه شد، به نام LFN ( Long File Name ) که میتونستی نام طولانی بزاری ( با پشتیبانی یونیکد ) که 13 کاراکتر یونیکد قبول میکنه! ( پسوند هم میتونه طولش متفاوت باشه).یعنی اگه گوشی قدیمی دارین، هر فایل بصورت دو نام ذخیره شده.LFN EntryOrdinal field که برای ترتیب و شمارش و دو تا فلگ هست.بقیش که معلومه غیر از check sum که میاد اولین کاراکتر نام (8.3) رو میندازه تو یک متغیر، بعد شیفت میده یکی به سمت راست و بعد کاراکتر بعدی رو اضافه میکنه، 8 بیت کم ارزش رو نگه میداره، بعد میره همینجوری تا کاراکتر اخر.بقیش رو چون خستم پارت بعدی میزارم، همینجوریشم این پارت به اندازه کافی عقب افتاده😂😅</description>
                <category>Mohammadasdi</category>
                <author>Mohammadasdi</author>
                <pubDate>Sat, 07 Feb 2026 13:19:21 +0330</pubDate>
            </item>
                    <item>
                <title>نوشتن یک سیستم عامل ساده با اسمبلی - پارت 01</title>
                <link>https://virgool.io/@Mohammadasdi/%D9%86%D9%88%D8%B4%D8%AA%D9%86-%DB%8C%DA%A9-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D8%B9%D8%A7%D9%85%D9%84-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%BE%D8%A7%D8%B1%D8%AA-01-xj0yspkxjgxu</link>
                <description>سلام! امروز میخوایم یک سیستم عامل بنویسیم ولی شاید نه اون سیستم عاملی که فکر میکنید، سیستم عامل ما قراره خیلی کوچیک و جمع و جور هست! البته برای شروع که نمیتونیم اسمشو سیستم عامل بزاریم، به هر حال!ما قراره برای خودمون یک چالش سخت رو انجام بدیم، بدون هیچ ابزاری و زبان برنامه نویسی و تنها با یک اسمبلر فسقلی یک سیستم عامل برای خودمون درست کنیم، طبیعتا اگه اسمبلی بلد نیستید، امیدوارم جلو تر از نرید تا حساب زده نشید ازش، و همین الان برید ببینید چیه و یادگیریشو شروع کنید! 🫠پیش نیازمون ایناس:یک کامپیوتر (زغالی در حد سیاه سوخته)یکدونه صندلی!یکدونه هم اسمبلر که من قراره از سینتکس اینتل و fasm استفاده کنم.اسمبلی هم باید بلد باشین.بریم سراغ کارمون (اصلا عاشق مقدمه طولانی نیستم!):کامپیوتر چند بخش داره:مادربردسی پی یوکیبوردماوسمانیتوراسپیکرغیر از مادربرد و سی پی یو 4 دستگاه کامل بیسیک داریم، هر کدوم از اینا از طریق مادربرد به پورت های سی پی یو وصل شدن، هر کدوم فقط میتونن با input یا output کار کنن، از بین اینا کیبورد و ماوس و یک سری دستگاه های خاص هر دو کار رو میتونن انجام بدن. بجای استفاده از input/output میایم از مخففش استفاده میکنیم که هستش I/Oمادربرد وقتی روشن بشه بایوس اجرا میشه (در سیستم های قدیمی یک ROM خوشگل داشتیم برای بایوس که فریم ور بایوس در اون نوشته شده بود و قابل ویرایش نبود، که در سیستم های جدید دیگه از ROM استفاده نمیکنه)، میاد هر چی دستگاه input که برای بخش ذخیره سازی هست رو میگرده (مثل: اکسترنال، اینترنال، یو اس بی، دی وی دی، فلاپی و ...) اگه قابل بوت باشه توی رم کپی میشه و جامپ میکنه روش.انصافا تاریک و ترسناکه!حالا چجوری چک میکنه قابل بوت باشه؟اگه توی حالت real mode باشه که میاد 1 سکتور از هارد یا فلاپی رو میگیره و دو بایت اخر (510 و 511) رو بصورت little-end دریافت میکنه و اگه برابر با 0xaa55 باشه، یعنی قابل بوت هست.حالا سوال اینه چرا 0xaa55؟ چرا مثلا 0x784a نباید باشه؟ دلیلش برای این بوده که اون قدیم قدیما میخواستن بد سکتور و اینارو تشخیص بدن، اومدن دو بیت متناوب رو بقل هم گذاشتن.0xaa = 0b10101010
0x55 = 0b01010101بقیه حالت هارو خودتون میتونید سرچ کنین توی گوگل، چون سیستم عامل ما برای شروع هست 16 بیتیه، که هنوز هم قدرتمنده.حالا کجای رم لود میکنه؟دقت کنین فقط سکتور اول رو توی رم لود میکنه، و بقیه سکتور هارو باید توی خود کد بوت لود کنین، از اونجایی که یک سکتور 512 بایته، یعنی 512 بایت جا داریم تا کدمونو توش جا بدیم! (کار خیلی راحتیه)بایوس بوت رو توی بخش 0000:7c00 یا 07c0:0000 لود میکنه.حالا بعضیا شاید بگن &quot;:&quot; دیگه چه سمیه!توی 16 بیت حافظه ها flat و صاف نبودن مثل 32 بیتی و 64 بیتی. چونکه ادرس باس 20 بیت بود و توی 16 بیت جا نمیشد اومدن این کارو کردن، که انصافا حداقل بعدش فهمیدن چه گندی زدن و در 32 بیتی به بعد درستش کردن (خداروشکر). این سمت چپیه که بهش میگن سگمنت (Segment) و سمت راستیه رو میگن بهش (Offset). دیگه بیشتر از بهتون اطلاعات نمیدم، برید خودتون سرچ کنین!😂😎چون واقعا زیاده و حداقل 10 تا مقاله میخواد یا بیشتر! و نمیشه همرو توضیح داد. بریم بخش بوت لودر سیستم عامل رو بزنیم: (اسم سیستم عاملی که من انتخاب کردم اینوس هست - Inous)روند کار اینجوریه که بوت میاد کرنل رو از یک حافظه مشخصی یا مسیر خاصی (اگه بیاین سیستم فایل رو بسازین، مثل fat16 و ...) لود میکنه، و قبل لودش هم اگه بخوایم پیشرفته بازی در بیاریم، میایم کرنل رو با یک الگوریتم صحت سنجی مثل crc-32 یا ... تست کنیم تا اگه مشکلی توی کرنل بود یک صفحه ارور بیاد که بگه kernel فایل خرابه! و نمیتونه لودش کنه!عصبیه!اول میایم یک پوشه میسازیم و توش چند فایل میسازیم که مهمن:build.asmboot.asmkernel.asmچیزای دیگه هم در حین اموزش میسازیم مثل:vars.asmtui.asmgui.asmmacros.asmutilities.asmsyscalls.asmو اینا.توی build.asm میایم کار build رو انجام میدیم، این فایل قراره تمام فایل های سیستم عاملو تبدیل به یک فلاپی کنه برامون!اول از همه یک کد کوچیک batch میزنیم به اسم buildx.batو توش این کدو میزنیم:@echo off

fasm build.asm inous.img

pauseبعد میریم فایل build.asm:format binary as &#039;img&#039;
use16

org 0x0000

FLOPPY_SIZE equ 2 * 80 * 18 * 512

include &#039;boot.asm&#039;
include &#039;kernel.asm&#039;

rb FLOPPY_SIZE - ($-$$) - 1
db 0بعد میریم فایل boot.asm:use16

org 0x7c00

mov al, &#039;!&#039;
mov ah, 0x0e
int 0x10

cli
hltبوت لودر رو ساده نوشتم، چون هم خستم هم نمیخوام مقاله بزرگ بشه و حوصله خوندش رو نداشته باشین. بعد این مستقیم میریم پارت 2.</description>
                <category>Mohammadasdi</category>
                <author>Mohammadasdi</author>
                <pubDate>Wed, 04 Feb 2026 20:26:14 +0330</pubDate>
            </item>
            </channel>
</rss>