<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Mohammadasdi</title><link>https://virgool.ir/feed/@Mohammadasdi</link><description></description><language>fa</language><pubDate>2026-11-12 06:06:32</pubDate><image><url>https://files.virgool.ir/upload/users/3270165/avatar/9X3LmP.png</url><title>Mohammadasdi</title><link>https://virgool.ir/@Mohammadasdi</link></image><item><title>ساخت یک سیستم عامل ساده با اسمبلی - پارت 03</title><link>https://virgool.ir/@Mohammadasdi/ساخت-یک-سیستم-عامل-ساده-با-اسمبلی-پارت-03-cnaincw2gc3x</link><description>خب خب، اومدیم به پارت سوم، تا الان موفق شدیم سیستم عاملمون رو با fat16 اوکی کنیم تا بشه روی فلش بوتش کرد.RufusDiskmgrمن از اون پارت دوم یکمی کار کردم روش و تونستم root region رو هم اوکی کنم.در کل اینجوری شد فایل build.asm:format binary as &#39;img&#39;&#xA;use16&#xA;&#xA;org 0x0000&#xA;&#xA;FLOPPY_SIZE equ 2 * 80 * 18 * 512&#xA;&#xA;include &#39;src/fat.asm&#39;&#xA;include &#39;boot.asm&#39;&#xA;&#xA;display &#39;=========== InousOS ============&#39;, 0x0d, 0x0a&#xA;display &#39;  - Master Boot Record (MBR) has been created.&#39;, 0x0d, 0x0a&#xA;&#xA;rb (RESERVED_SECTORS-1) * BYTES_PER_SECTOR&#xA;&#xA;; ========== FAT Region ==========&#xA;clusters_size = BYTES_PER_SECTOR * SECTORS_PER_CLUSTER&#xA;&#xA;macro fat_init list_file {&#xA;    repeat NUMBER_FAT_COPIES&#xA;        current_pos = $&#xA;&#xA;        db MEDIA_DESCRIPTOR, 0xff       ; FAT_ENTRY1&#xA;        dw 0xffff                       ; FAT_ENTRY2&#xA;&#xA;        irps file_name, list_file \{&#xA;            display &#39;  - FAT entry &#39;, %+47, &#34; has been created for file &#39;&#34;, file_name, &#34;&#39;.&#34;, 0x0d, 0x0a&#xA;&#xA;            virtual at 0&#xA;                file file_name&#xA;                file_size = $&#xA;            end virtual&#xA;&#xA;            file_clusters = (file_size + clusters_size - 1) / clusters_size&#xA;&#xA;            if file_clusters = 0&#xA;                dw 0xffff&#xA;            else&#xA;                repeat file_clusters&#xA;                    if file_clusters = %&#xA;                        dw 0xffff&#xA;                    else&#xA;                        dw (% + 2)&#xA;                    end if&#xA;                end repeat&#xA;            end if&#xA;        \}&#xA;&#xA;        rb (SECTORS_PER_FAT * BYTES_PER_SECTOR) - ($-current_pos)&#xA;    end repeat&#xA;}&#xA;&#xA;fat_init &#39;build/kernel.bin&#39;&#xA;&#xA;display &#39;  - FAT area has been initialized.&#39;, 0x0d, 0x0a&#xA;; ======== END FAT Region ========&#xA;&#xA;; ========== ROOT Region =========&#xA;macro drive_init drive_name {&#xA;    DRIVE_NAME                      db drive_name&#xA;    ATTRIBUTE                       db 0x08&#xA;    RESERVED                        db 0x00&#xA;    CREATION                        db 0x00&#xA;    CREATION_TIME                   dw 0x0000&#xA;    CREATION_DATE                   dw 0x0021&#xA;    LAST_ACCESS_DATE                dw 0x0021&#xA;    RESERVED_FAT32                  dw 0x0000&#xA;    LAST_WRITE_TIME                 dw 0x0000&#xA;    LAST_WRITE_DATE                 dw 0x0021&#xA;    STARTING_CLUSTER                dw 0x0000&#xA;    DRIVE_SIZE                      dd 0x00000000&#xA;}&#xA;&#xA;macro root_entry file_name {&#xA;    local FILE_NAME, FILE_EXT, ATTRIBUTE, \&#xA;          RESERVED, CREATION, CREATION_TIME, \&#xA;          CREATION_DATE, LAST_ACCESS_DATE, \&#xA;          RESERVED_FAT32, LAST_WRITE_TIME, \&#xA;          LAST_WRITE_DATE, STARTING_CLUSTER, DRIVE_SIZE&#xA;&#xA;    virtual at 0&#xA;        file file_name&#xA;        file_size = $&#xA;    end virtual&#xA;&#xA;    FILE_NAME                       db &#39;KERNEL  &#39;&#xA;    FILE_EXT                        db &#39;INU&#39;&#xA;    ATTRIBUTE                       db 0x20&#xA;    RESERVED                        db 0x00&#xA;    CREATION                        db 0x00&#xA;    CREATION_TIME                   dw 0x0000&#xA;    CREATION_DATE                   dw 0x0021&#xA;    LAST_ACCESS_DATE                dw 0x0021&#xA;    RESERVED_FAT32                  dw 0x0000&#xA;    LAST_WRITE_TIME                 dw 0x0000&#xA;    LAST_WRITE_DATE                 dw 0x0021&#xA;    STARTING_CLUSTER                dw 0x0003&#xA;    DRIVE_SIZE                      dd file_size&#xA;}&#xA;&#xA;macro root_init list_file {&#xA;    irps file_name, list_file \{&#xA;        root_entry file_name&#xA;    \}&#xA;}&#xA;&#xA;drive_init VOLUME_LABEL&#xA;root_init &#39;build/kernel.bin&#39;&#xA;root_init &#39;build/kernel.bin&#39;&#xA;; ======= END ROOT Region ========&#xA;&#xA;rb FLOPPY_SIZE - ($-$$) - 1&#xA;db 0&#xA;&#xA;display 0x0d, 0x0aیکمی جاها نیازمند تعریف متغیر و ایناس، و یکمی کار داره برای data region.فایل buildx.bat هم دادیم به هوش مصنوعی ( خودم زیاد batch script بلد نیستم ) و اینو داد:@echo off&#xA;setlocal enabledelayedexpansion&#xA;&#xA;set SRC_DIR=src&#xA;set BUILD_DIR=build&#xA;set DIST_DIR=dist&#xA;&#xA;if not exist %BUILD_DIR% mkdir %BUILD_DIR%&#xA;if not exist %DIST_DIR% mkdir %DIST_DIR%&#xA;&#xA;for %%F in (%SRC_DIR%\*.asm) do (&#xA;    fasm %%F %BUILD_DIR%\%%~nF.bin&#xA;    if errorlevel 1 (&#xA;        pause&#xA;        exit /b 1&#xA;    )&#xA;)&#xA;&#xA;fasm build.asm %DIST_DIR%\inous.img&#xA;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:&#xA;    print(&#39;A&#39;)&#xA;elif scancode == 0x32:&#xA;    print(&#39;B&#39;)&#xA;elif scancode == 0x21:&#xA;    print(&#39;C&#39;)چون اینجوری نزدیک 300 تا باید if بزنیم، خب اینکه توی اسمبلی از 1 کیلوبایت بیشتر میشه که!یک چیزی داریم تو اسمبلی، مثل بلوک ترجمه میمونه، بهش یک چیزی میدی بهت یک چیز دیگه میده. مثلا اینجوریه:scancode = 0x1c&#xA;&#xA;trans = bytes.maketrans(bytes(range(0xff)), b&#39;ABC........&#39;)&#xA;print(bytes.translate(scancode, trans))اینجوری فقط دو سه تا if دیگه میخوایم که برای کلید های ویژه هستن.قبلش باید مفهوم IRQ رو بدونین، خلاصش اینه که سخت افزار مثلا موس یا کیبورد وقتی بخواد به پردازنده بگه: &#34;داداش، فلانی کلید A من رو زد&#34;، میره در خونه رو میزنه، پردازنده در رو باز میکنه میبینه: عه این کیبورده، بعد به کیبورد میگه چیکارم داشتی، کیبورد هم میگه کلید 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 20:48:04 +0330</pubDate></item><item><title>نوشتن یک سیستم عامل ساده با اسمبلی - پارت 02</title><link>https://virgool.ir/@Mohammadasdi/نوشتن-یک-سیستم-عامل-ساده-با-اسمبلی-پارت-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&#xA;&#xA;org 0x7c00&#xA;&#xA;jmp boot&#xA;&#xA;nop&#xA;&#xA;BOOT_SIZE equ 512&#xA;&#xA;BPB Fat16&#xA;&#xA;boot:&#xA;cli&#xA;hlt&#xA;&#xA;rb BOOT_SIZE - ($-$$) - 2&#xA;dw 0xaa55اینم فایل جدید به اسم fat.asm:use16&#xA;&#xA;OEMID                           equ &#39;INOUS   &#39;&#xA;BYTES_PER_SECTOR                equ 512&#xA;SECTORS_PER_CLUSTER             equ 1&#xA;RESERVED_SECTORS                equ 1&#xA;NUMBER_FAT_COPIES               equ 2&#xA;NUMBER_ROOT_ENTRIES             equ 512&#xA;SMALL_NUMBER_SECTORS            equ 2 * 80 * 18&#xA;MEDIA_DESCRIPTOR                equ 0xf0&#xA;SECTORS_PER_FAT                 equ 12&#xA;SECTORS_PER_TRACK               equ 18&#xA;NUMBER_HEADS                    equ 2&#xA;HIDDEN_SECTORS                  equ 0&#xA;LARGE_NUMBER_SECTORS            equ 0&#xA;DRIVE_NUMBER                    equ 0&#xA;RESERVED_NT                     equ 0&#xA;EXT_BOOT_SIG                    equ 0x29 &#xA;VOLUME_SERIAL                   equ 0x57694123&#xA;VOLUME_LABEL                    equ &#39;LOCAL DISK &#39;&#xA;FILESYSTEM_TYPE                 equ &#39;FAT16   &#39;&#xA;&#xA;struc Fat16 {&#xA;    .OEMID                                db OEMID&#xA;    .BYTES_PER_SECTOR                     dw BYTES_PER_SECTOR&#xA;    .SECTORS_PER_CLUSTER                  db SECTORS_PER_CLUSTER&#xA;    .RESERVED_SECTORS                     dw RESERVED_SECTORS&#xA;    .NUMBER_FAT_COPIES                    db NUMBER_FAT_COPIES&#xA;    .NUMBER_ROOT_ENTRIES                  dw NUMBER_ROOT_ENTRIES&#xA;    .SMALL_NUMBER_SECTORS                 dw SMALL_NUMBER_SECTORS&#xA;    .MEDIA_DESCRIPTOR                     db MEDIA_DESCRIPTOR&#xA;    .SECTORS_PER_FAT                      dw SECTORS_PER_FAT&#xA;    .SECTORS_PER_TRACK                    dw SECTORS_PER_TRACK&#xA;    .NUMBER_HEADS                         dw NUMBER_HEADS&#xA;    .HIDDEN_SECTORS                       dd HIDDEN_SECTORS&#xA;    .LARGE_NUMBER_SECTORS                 dd LARGE_NUMBER_SECTORS&#xA;    .DRIVE_NUMBER                         db DRIVE_NUMBER&#xA;    .RESERVED_NT                          db RESERVED_NT&#xA;    .EXT_BOOT_SIG                         db EXT_BOOT_SIG&#xA;    .VOLUME_SERIAL                        dd VOLUME_SERIAL&#xA;    .VOLUME_LABEL                         db VOLUME_LABEL&#xA;    .FILESYSTEM_TYPE                      db FILESYSTEM_TYPE&#xA;}برای ساختار داده fat16 یکدونه struc ساختیم که مثلا وقتی زدیم:BPB Fat16&#xA;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 &#39;img&#39;&#xA;use16&#xA;&#xA;org 0x0000&#xA;&#xA;FLOPPY_SIZE equ 2 * 80 * 18 * 512&#xA;&#xA;include &#39;fat.asm&#39;&#xA;include &#39;boot.asm&#39;&#xA;&#xA;org 0x7d00&#xA;&#xA;; ========== FAT Region ==========&#xA;virtual at 0&#xA;    file_start:&#xA;        include &#39;kernel.asm&#39;&#xA;    file_end:&#xA;end virtual&#xA;&#xA;clusters_size = BYTES_PER_SECTOR * SECTORS_PER_CLUSTER&#xA;&#xA;rept NUMBER_FAT_COPIES i:1 {&#xA;    current_pos = $&#xA;    FAT#i#_ENTRY1:                      db 0xff, MEDIA_DESCRIPTOR&#xA;    FAT#i#_ENTRY2:                      dw 0xffff&#xA;&#xA;    file_size = file_end - file_start&#xA;    file_clusters = (file_size + clusters_size - 1) / clusters_size&#xA;&#xA;    if file_clusters = 0&#xA;        dw 0xffff&#xA;    else&#xA;        repeat file_clusters&#xA;            if file_clusters = %&#xA;                dw 0xffff&#xA;            else&#xA;                dw (% + 2)&#xA;            end if&#xA;        end repeat&#xA;    end if&#xA;&#xA;    rb (SECTORS_PER_FAT * BYTES_PER_SECTOR) - ($-current_pos)&#xA;}&#xA;; ======== END FAT Region ========&#xA;&#xA;rb FLOPPY_SIZE - ($-$$) - 1&#xA;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 14:19:21 +0330</pubDate></item><item><title>نوشتن یک سیستم عامل ساده با اسمبلی - پارت 01</title><link>https://virgool.ir/@Mohammadasdi/نوشتن-یک-سیستم-عامل-ساده-با-اسمبلی-پارت-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&#xA;0x55 = 0b01010101بقیه حالت هارو خودتون میتونید سرچ کنین توی گوگل، چون سیستم عامل ما برای شروع هست 16 بیتیه، که هنوز هم قدرتمنده.حالا کجای رم لود میکنه؟دقت کنین فقط سکتور اول رو توی رم لود میکنه، و بقیه سکتور هارو باید توی خود کد بوت لود کنین، از اونجایی که یک سکتور 512 بایته، یعنی 512 بایت جا داریم تا کدمونو توش جا بدیم! (کار خیلی راحتیه)بایوس بوت رو توی بخش 0000:7c00 یا 07c0:0000 لود میکنه.حالا بعضیا شاید بگن &#34;:&#34; دیگه چه سمیه!توی 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&#xA;&#xA;fasm build.asm inous.img&#xA;&#xA;pauseبعد میریم فایل build.asm:format binary as &#39;img&#39;&#xA;use16&#xA;&#xA;org 0x0000&#xA;&#xA;FLOPPY_SIZE equ 2 * 80 * 18 * 512&#xA;&#xA;include &#39;boot.asm&#39;&#xA;include &#39;kernel.asm&#39;&#xA;&#xA;rb FLOPPY_SIZE - ($-$$) - 1&#xA;db 0بعد میریم فایل boot.asm:use16&#xA;&#xA;org 0x7c00&#xA;&#xA;mov al, &#39;!&#39;&#xA;mov ah, 0x0e&#xA;int 0x10&#xA;&#xA;cli&#xA;hltبوت لودر رو ساده نوشتم، چون هم خستم هم نمیخوام مقاله بزرگ بشه و حوصله خوندش رو نداشته باشین. بعد این مستقیم میریم پارت 2.</description><category>Mohammadasdi</category><author>Mohammadasdi</author><pubDate>Wed, 04 Feb 2026 21:26:14 +0330</pubDate></item></channel></rss>