๐๏ธ help,clear์ด ์ธ์ version์ ํ์ธ ํ ์ ์๋ ๋ช
๋ น์ด๋ฅผ ์ถ๊ฐํด ๋ด
๋๋ค.
Let’s add a command to check the version, in addition to help and clear.
๐๏ธ ๊ธฐ์กด ์ฝ๋์์ ์ถ๊ฐ๋๊ฑฐ๋ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์ค๋ช
ํฉ๋๋ค.๋๋จธ์ง๋ ์ด์ ๊ณผ ๋์ผํฉ๋๋ค.
Only the parts added to or modified from the existing code are explained here; the rest remains the same.
๐๏ธ ์ปดํ์ผ ํ ํ์ผ์ boot.asm๊ณผ sector2.asm ๋๊ฐ์
๋๋ค.
The files to be compiled are boot.asm and sector2.asm.
๐๏ธ boot.asm๊ธฐ์กด๊ณผ ๋์ผํ๊ธฐ ๋๋ฌธ์ ์ค๋ช
์ ์๋ตํฉ๋๋ค.
I will skip the explanation for boot.asm, as it remains the same as before.
๐๏ธ ์ ์ฒด์ฝ๋ / Full code
[org 0x8000]
bits 16
start:
; ์ฐ์ปด ๋ฉ์์ง ์ถ๋ ฅ
; Print welcome message
mov si, msg_welcome
call print_string
; ํ๋กฌํํธ(miniOS> )๋ฅผ ์ถ๋ ฅํ๊ณ ์
๋ ฅ์ ์ค๋นํ๋ ๊ณณ
; The place to print the prompt (miniOS> ) and prepare for input
prompt:
mov si, msg_prompt
call print_string
; ์
๋ ฅ ๋ฒํผ๋ฅผ ๊ฐ๋ฆฌํฌ ํฌ์ธํฐ(DI)๋ฅผ ๋ฒํผ์ ์์ ์ฃผ์๋ก ์ด๊ธฐํ
; Initialize the pointer (DI) pointing to the input buffer with the starting address of the buffer
mov di, cmd_buffer
mov cx, 0 ; ์
๋ ฅ๋ ๊ธ์ ์๋ฅผ ์ธ๊ธฐ ์ํ ์นด์ดํฐ
; Counter to count the number of entered characters
; ํค๋ณด๋ ์
๋ ฅ์ ํ ๊ธ์์ฉ ๋ฐ๋ ๋ฃจํ
; A loop that receives keyboard input character by character
key_loop:
mov ah, 0x00
int 0x16 ; ํค๋ณด๋ ์
๋ ฅ ๋ฐ๊ธฐ (AL์ ASCII ์ฝ๋ ์ ์ฅ)
; Get keyboard input (Store ASCII code in AL)
; ์ํฐ ํค(13)๋ฅผ ๋๋ ๋์ง ํ์ธ
; Check if the Enter key (13) was pressed
cmp al, 13
je check_command
; ๋ฐฑ์คํ์ด์ค ํค(8) ์ฒ๋ฆฌ (๊ธ์ ์ง์ฐ๊ธฐ)
; Process Backspace key (8) (Erase character)
cmp al, 8
je backspace
; ๋ฒํผ ๋์นจ ๋ฐฉ์ง (์ต๋ 15๊ธ์๋ง ์
๋ ฅ ๊ฐ๋ฅ)
; Prevent buffer overflow (Max 15 characters allowed)
cmp cx, 15
je key_loop
; ํ๋ฉด์ ๊ธ์ ์ถ๋ ฅ (์์ฝ)
; Output character to screen (Echo)
mov ah, 0x0e
int 0x10
; ์
๋ ฅ๋ฐ์ ๋ฌธ์๋ฅผ ๋ฒํผ์ ์ ์ฅํ๊ณ ํฌ์ธํฐ(DI) ์ด๋
; Save the received character to the buffer and move the pointer (DI)
mov [di], al
inc di
inc cx ; ๊ธ์ ์ ์ฆ๊ฐ
; Increment character count
jmp key_loop
; ๋ฐฑ์คํ์ด์ค ์ฒ๋ฆฌ ๋ฃจํด
; Backspace processing routine
backspace:
cmp cx, 0 ; ์
๋ ฅ๋ ๊ธ์๊ฐ ์์ผ๋ฉด ๋ฌด์
; Ignore if no characters are entered
je key_loop
; ํ๋ฉด์์ ๊ธ์ ์ง์ฐ๊ธฐ (์ผ์ชฝ ์ด๋ -> ๊ณต๋ฐฑ ์ถ๋ ฅ -> ๋ค์ ์ผ์ชฝ ์ด๋)
; Erase character from screen (Move left -> Output space -> Move left again)
mov ah, 0x0e
mov al, 8
int 0x10
mov al, ' '
int 0x10
mov al, 8
int 0x10
dec di ; ๋ฒํผ ํฌ์ธํฐ 1 ๊ฐ์
; Decrement buffer pointer by 1
dec cx ; ๊ธ์ ์ 1 ๊ฐ์
; Decrement character count by 1
jmp key_loop
; ์ํฐ๋ฅผ ์ณค์ ๋ ์
๋ ฅ๋ ๋ช
๋ น์ด๋ฅผ ๋น๊ตํ๋ ๊ณณ
; The place to compare the entered command when Enter is pressed
check_command:
; ๋ฌธ์์ด์ ๋์ ํ์ํ๊ธฐ ์ํด ๋ฒํผ์ ํ์ฌ ์์น์ 0(Null) ์ฝ์
; Insert 0 (Null) at the current location of the buffer to mark the end of the string
mov byte [di], 0
; ์ค๋ฐ๊ฟ ์ถ๋ ฅ
; Output newline
call print_newline
; ์
๋ ฅ๋ ๊ธ์๊ฐ ์์ ์์ผ๋ฉด ๊ทธ๋ฅ ๋ค์ ํ๋กฌํํธ๋ก
; If no characters are entered at all, just go to the next prompt
cmp cx, 0
je prompt
; 1. 'help' ๋ช
๋ น์ด ๋น๊ต
; 1. Compare 'help' command
mov si, cmd_buffer
mov di, cmd_help
call compare_string
je do_help ; ๊ฐ์ผ๋ฉด do_help๋ก ์ ํ
; If equal, jump to do_help
; 2. 'clear' ๋ช
๋ น์ด ๋น๊ต
; 2. Compare 'clear' command
mov si, cmd_buffer
mov di, cmd_clear
call compare_string
je do_clear ; ๊ฐ์ผ๋ฉด do_clear๋ก ์ ํ
; If equal, jump to do_clear
; ----------------------------------------------------
; ๐ [์ถ๊ฐ๋ ๋ถ๋ถ /] 3. 'version' ๋ช
๋ น์ด ๋น๊ต
; [ Added Part ] 3. 'version' Command Comparison
; ----------------------------------------------------
mov si, cmd_buffer
mov di, cmd_version
call compare_string
je do_version ; ๊ฐ์ผ๋ฉด do_version์ผ๋ก ์ ํ
; If equal, jump to do_version
; ----------------------------------------------------
; ์ผ์นํ๋ ๋ช
๋ น์ด๊ฐ ์์ผ๋ฉด ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ
; If no matching command is found, print error message
mov si, msg_unknown
call print_string
jmp prompt
; [๋ช
๋ น์ด ์ฒ๋ฆฌ] help ๊ตฌํ
; [Command Processing] Implement help
do_help:
mov si, msg_help_text
call print_string
jmp prompt
; [๋ช
๋ น์ด ์ฒ๋ฆฌ] clear ๊ตฌํ
; [Command Processing] Implement clear
do_clear:
; BIOS ํ๋ฉด ์คํฌ๋กค ๊ธฐ๋ฅ์ ์ด์ฉํด ํ๋ฉด ์ง์ฐ๊ธฐ
; Clear screen using BIOS screen scroll function
mov ah, 0x06 ; ์คํฌ๋กค ์
๊ธฐ๋ฅ
; Scroll up function
mov al, 0 ; 0 = ํ๋ฉด ์ ์ฒด ์ง์ฐ๊ธฐ
; 0 = Clear entire screen
mov bh, 0x07 ; ๋ฐํ์ ๊ฒ์ , ๊ธ์์ ํฐ์
; Background black, Foreground white
mov ch, 0 ; ์ข์๋จ ํ
; Upper left row
mov cl, 0 ; ์ข์๋จ ์ด
; Upper left column
mov dh, 24 ; ์ฐํ๋จ ํ
; Lower right row
mov dl, 79 ; ์ฐํ๋จ ์ด
; Lower right column
int 0x10
; ์ปค์๋ฅผ ๋งจ ์ ์ข์๋จ(0,0)์ผ๋ก ์ด๋
; Move cursor to the top-left corner (0,0)
mov ah, 0x02
mov bh, 0
mov dh, 0
mov dl, 0
int 0x10
jmp prompt
; ----------------------------------------------------
; ๐ [์ถ๊ฐ๋ ๋ถ๋ถ] [๋ช
๋ น์ด ์ฒ๋ฆฌ] version ๊ตฌํ
; [Added Part] [Instruction processing] version implementation
; ----------------------------------------------------
do_version:
mov si, msg_version_text
call print_string
jmp prompt
; ----------------------------------------------------
; [ํจ์] ๋ ๋ฌธ์์ด์ด ๊ฐ์์ง ๋น๊ต (SI์ DI ์ฃผ์์ ๋ฌธ์์ด ๋น๊ต)
; [Function] Compare if two strings are equal (Compare strings at SI and DI addresses)
compare_string:
.loop:
mov al, [si]
mov bl, [di]
cmp al, bl ; ๋ ๊ธ์๊ฐ ๊ฐ์์ง ๋น๊ต
; Compare if two characters are equal
jne .not_equal ; ๋ค๋ฅด๋ฉด ํ์ถ
; If not equal, escape
cmp al, 0 ; ๋ฌธ์์ด์ด ๋๋ฌ๋์ง ํ์ธ (๋ ๋ค 0์ธ ์ํฉ)
; Check if the string ended (Both are 0 case)
je .equal ; ๋๋ฌ์ผ๋ฉด ์๋ฒฝํ ์ผ์น
; If ended, perfect match
inc si
inc di
jmp .loop
.not_equal:
clc ; Carry Flag ํด๋ฆฌ์ด (๊ฐ์ง ์์ ํ์, ์ต์ง flag ์ธํ
์ฉ์ผ๋ก cmp ํ์ฉ)
; Clear Carry Flag (Indicate not equal, use cmp for forced flag setting)
mov al, 1
cmp al, 0 ; Zero Flag๋ฅผ 0์ผ๋ก ๋ง๋ค์ด '๋ค๋ฆ'์ ์๋ฆผ
; Set Zero Flag to 0 to notify 'Not Equal'
ret
.equal:
cmp al, 0 ; Zero Flag๋ฅผ 1๋ก ๋ง๋ค์ด '๊ฐ์'์ ์๋ฆผ (AL์ด 0์ด๋ฏ๋ก)
; Set Zero Flag to 1 to notify 'Equal' (Since AL is 0)
ret
; [ํจ์] ๋ฌธ์์ด ์ถ๋ ฅ
; [Function] Print string
print_string:
lodsb
cmp al, 0
je .done
mov ah, 0x0e
int 0x10
jmp print_string
.done:
ret
; [ํจ์] ์ค๋ฐ๊ฟ ์ถ๋ ฅ
; [Function] Print newline
print_newline:
mov ah, 0x0e
mov al, 13
int 0x10
mov al, 10
int 0x10
ret
; ----------------------------------------------------
; ๋ฐ์ดํฐ ๋ฐ ๋ณ์ ์ ์ธ ์์ญ (์ ์ญ ๋ณ์)
; Data and variable declaration area (Global variables)
; ----------------------------------------------------
msg_welcome db '3. Hello from Sector 2! miniOS Shell Started.', 13, 10, 0
msg_prompt db 'miniOS> ', 0
msg_unknown db 'Unknown command! Type "help".', 13, 10, 0
; ๐ [์์ ๋ ๋ถ๋ถ] help ํ
์คํธ ๋ชฉ๋ก์ version ๋ช
์
; [Modified] Specified the version in the help text list.
msg_help_text db 'Available commands: help, clear, version', 13, 10, 0
; ----------------------------------------------------
; ๐ [์ถ๊ฐ๋ ๋ถ๋ถ ] version ์ถ๋ ฅ์ฉ ๋ณ์ ์ ์ธ
; [Added Part] Variable declaration for version output
; ----------------------------------------------------
msg_version_text db 'miniOS version 1.0.0 (Compiled in 2026)', 13, 10, 0
; ----------------------------------------------------
; ๋น๊ตํ ๋ช
๋ น์ด ๊ธฐ์ค ๋ฌธ์์ด (์์)
; Reference command strings for comparison (Constants)
cmd_help db 'help', 0
cmd_clear db 'clear', 0
; ----------------------------------------------------
; ๐ [ ์ถ๊ฐ๋ ๋ถ๋ถ ] ๋น๊ตํ ๋ช
๋ น์ด ๊ธฐ์ค ๋ณ์ ์ ์ธ
; [ Added Part ] Declare a variable to serve as the basis for the command comparison.
; ----------------------------------------------------
cmd_version db 'version', 0
; ----------------------------------------------------
; ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ธ์๋ค์ ๋ด์ '๋น ๋ณ์ ๊ณต๊ฐ' (๋ฒํผ)
; 'Empty variable space' to hold characters entered by the user (Buffer)
; 16๋ฐ์ดํธ ํฌ๊ธฐ๋งํผ ๊ณต๊ฐ์ ๋ฏธ๋ฆฌ ํ๋ณดํด ๋ก๋๋ค.
; Pre-allocate space of 16 bytes.
cmd_buffer times 16 db 0
; 512๋ฐ์ดํธ ํฌ๊ธฐ ๋ง์ถ๊ธฐ
; Fill up to 512 bytes
times 512 - ($ - $$) db 0
๐๏ธ ๋น๋ / build
# 1๋ฒ ์นํฐ ์ปดํ์ผ
# Sector 1 Compilation
# nasm -f bin boot.asm -o boot.bin
# 1. 2๋ฒ ์นํฐ ์๋ก ์ปดํ์ผ
# 1. Recompile Sector 2
nasm -f bin sector2.asm -o sector2.bin
# 2. ํฉ์น๊ธฐ ๋ฐ 1.44MB ์ด๋ฏธ์ง ๊ท๊ฒฉํ
# 2. Merging and Standardizing to 1.44MB Image Format
cat boot.bin sector2.bin > temp.bin
dd if=temp.bin of=os.img bs=512 count=2880 conv=sync
# 3. QEMU ๋ถํ
์์ ๊ฐ์ ์ง์ ์คํ
# 3. Running QEMU with a Forced Boot Order
qemu-system-x86_64 -drive file=os.img,format=raw,if=floppy -boot a

๐๏ธ ์ฝ๋์ค๋ช / Code Explanation
โ๏ธ cmd_buffer์ ์
๋ ค๋ ๋ด์ฉ๊ณผ cmd_version์ ๋ด์ฉ๊ณผ ๋น๊ตํด์ ์ผ์นํ๋ฉด(compare_string) do_version์ผ๋ก ์ ํํฉ๋๋ค.
The content entered into cmd_buffer is compared with the content of cmd_version; if they match (via compare_string), the execution jumps to do_version.
mov si, cmd_buffer
mov di, cmd_version
call compare_string
je do_version ; ๊ฐ์ผ๋ฉด do_version์ผ๋ก ์ ํ
; If equal, jump to do_version
cmd_version db 'version', 0
โ๏ธ ํ๋ฉด์ ์ค์ ๋ก ๋ฒ์ ์ ํ์ํฉ๋๋ค.
It actually displays the version on the screen.
— si๋ ์ง์คํฐ์ msg_version_text ๋ณ์๋ฅผ ์
๋ ฅํฉ๋๋ค.
Load the msg_version_text variable into the si register.
— print_stringํจ์๋ฅผ ์คํํด์ํ๋ฉด์ ๋ฒ์ ์ ์ถ๋ ฅํฉ๋๋ค.
Execute the print_string function to display the version on the screen.
— prompt๋ผ๋ฒจ๋ก ์ ํํฉ๋๋ค.
Jump to the prompt label.
do_version:
mov si, msg_version_text
call print_string
jmp prompt
msg_version_text db 'miniOS version 1.0.0 (Compiled in 2026)', 13, 10, 0
โ๏ธ ์๋๋ help๋ช
๋ น์ด๋ฅผ ์คํํ ๋ ์ฌ์ฉ๊ฐ๋ฅํ ๋ช
๋ น์ด๋ก version์ ์ถ๊ฐํ์ต๋๋ค.
The ‘version’ command has been added to the list of available commands shown when running the ‘help’ command.
msg_help_text db 'Available commands: help, clear, version', 13, 10, 0