[OS] miniOS-4(1)

๐Ÿ‘‰๏ธ ์ด๋ฒˆ์—๋Š” ๊ฐ„๋‹จํ•œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์‰˜์„ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค.
Now, let’s create a shell that can accept and execute simple commands.

๐Ÿ‘‰๏ธ boot.asm์€ ๊ธฐ์กด ์ฝ”๋“œ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
boot.asm is the same as the existing code.

๐Ÿ‘‰๏ธ ์ „์ฒดํŒŒ์ผ์€ boot.asm๊ณผ sector2.asm์ž…๋‹ˆ๋‹ค.
The complete files are boot.asm and sector2.asm.

๐Ÿ‘‰๏ธ ์ „์ฒด์ฝ”๋“œ / Full Code(secotor2.asm)

[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

    ; ์ผ์น˜ํ•˜๋Š” ๋ช…๋ น์–ด๊ฐ€ ์—†์œผ๋ฉด ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
    ; 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

; [ํ•จ์ˆ˜] ๋‘ ๋ฌธ์ž์—ด์ด ๊ฐ™์€์ง€ ๋น„๊ต (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
msg_help_text db 'Available commands: help, clear', 13, 10, 0

; ๋น„๊ตํ•  ๋ช…๋ น์–ด ๊ธฐ์ค€ ๋ฌธ์ž์—ด (์ƒ์ˆ˜)
; Reference command strings for comparison (Constants)
cmd_help      db 'help', 0
cmd_clear     db 'clear', 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

๐Ÿ‘‰๏ธ ์ฝ”๋“œ์„ค๋ช…(sector2.asm)

โœ”๏ธ boot.asm ์ฝ”๋“œ์„ค๋ช…์€ ์ด์ „๊ณผ ๊ฐ™์•„์„œ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.
I will skip the explanation of the boot.asm code, as it is the same as before.

โœ”๏ธ ๋ฉ”์„ธ์ง€ ์ถœ๋ ฅ๋“ฑ ์ด์ „๊ณผ ๊ตฌ์กฐ๊ฐ™์€ ๋ถ€๋ถ„์˜ ์„ค๋ช…์€ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.
Explanations regarding aspects where the structure remains the same as beforeโ€”such as message outputโ€”are omitted.

โœ”๏ธ ์ €์žฅํ•  ๋ชฉ์ ์ง€ ์ฃผ์†Œ ์ง€์ •(prompt:)
Specify destination address to save (prompt:)

— DI (Destination Index) ๋ ˆ์ง€์Šคํ„ฐ๋Š” CPU๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ‘์ €์žฅ(๊ธฐ๋ก)’ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ํฌ์ธํ„ฐ(ํ™”์‚ดํ‘œ) ๋ ˆ์ง€์Šคํ„ฐ์ž…๋‹ˆ๋‹ค.
The DI (Destination Index) register is a representative pointer register primarily used by the CPU when storing (writing) data to memory.

— cmd_buffer:
์ถœ๋ฐœ์ (0x8000)์—์„œ ์ฝ”๋“œ ๊ธธ์ด๋งŒํผ ๋’ค๋กœ ๋–จ์–ด์ง„ ๋ฒ„ํผ ์ „์šฉ ๋ฐฉ ๋ฒˆํ˜ธ(์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ)์ž…๋‹ˆ๋‹ค.
This is the buffer-specific room number (actual memory address) located a distance equal to the code length behind the starting point (0x8000).

— ์•„๋ž˜์—์„œ mov [di], al ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
Below, it is used like this: mov [di], al.

mov di, cmd_buffer

โœ”๏ธ ์ž…๋ ฅํ•œ ๊ธ€์ž ์ˆ˜ ์„ธ๋Š” ์นด์šดํ„ฐ
Counter that counts the number of characters entered

mov cx, 0 

โœ”๏ธ ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์„ ํ•œ ๊ธ€์ž์”ฉ ๋ฐ›๋Š” ๋ฃจํ”„(key_loop:)
A loop that accepts keyboard input one character at a time (key_loop:)

— ํ‚ค๋ณด๋“œ ์ž…๋ ฅ ์ฝ๊ธฐ ๊ธฐ๋Šฅ ์„ ํƒ (๋ฐ”์ด์˜ค์Šค ์„œ๋น„์Šค ์ธํ„ฐ๋ŸฝํŠธ)
Select Keyboard Input Read Function (BIOS Service Interrupt)

 mov ah, 0x00

— ์ธํ„ฐ๋ŸฝํŠธ ์‹คํ–‰
Interrupt execution

— AH = 0x00 ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  BIOS ํ‚ค๋ณด๋“œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ตœ์ข… ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
Finally, the BIOS keyboard interrupt is called with AH = 0x00.

— ํ™”๋ฉด ์ถœ๋ ฅ(int 0x10), ๋””์Šคํฌ ์ฝ๊ธฐ(int 0x13), ํ‚ค๋ณด๋“œ ์ž…๋ ฅ(int 0x16)
Screen output (int 0x10), disk read (int 0x13), keyboard input (int 0x16)

— ์‚ฌ์šฉ์ž์ž…๋ ฅ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๋ธ”๋กœํ‚น ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
It enters a blocking state to receive user input.

int 0x16

— ์—”ํ„ฐํ‚ค๊ฐ€ ์ž…๋ ฅ๋˜๋ฉด check_command๋ผ๋ฒจ์„ ์‹คํ–‰ ํ•ฉ๋‹ˆ๋‹ค.
When the Enter key is pressed, the check_command label is executed.

    cmp al, 13
    je check_command

— ๋ฐฑ์ŠคํŽ˜์ด์Šค ํ‚ค๋ฅผ ์ž…๋ ฅ์‹œ backspace๋ผ๋ฒจ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
Pressing the Backspace key executes the ‘backspace’ label.

    cmp al, 8
    je backspace

— ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€ ๊ธฐ๋Šฅ ์ž…๋‹ˆ๋‹ค.
This is a buffer overflow prevention feature.

— ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ๋ฅผ ํ•œ ๊ธ€์ž์”ฉ ์น  ๋•Œ๋งˆ๋‹ค inc cx ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ๋ฒ„ํผ์— ์Œ“์ธ ๊ธ€์ž ์ˆ˜๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
Each time the user types a character, the inc cx instruction tracks the number of characters accumulated in the current buffer.

— cmp (Compare) ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด “ํ˜„์žฌ ๊ธ€์ž ์ˆ˜(CX)๊ฐ€ 15์™€ ๊ฐ™์€์ง€” ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
The cmp (Compare) instruction is used to compare whether the current character count (CX) is equal to 15.

— cmd_buffer์˜ ํฌ๊ธฐ๋Š” 16๋ฐ”์ดํŠธ์ด๋ฉฐ ๋งˆ์ง€๋ง‰์— ์ข…๋ฃŒํ‘œ์‹œ ์‹ ํ˜ธ 0์ด๋“ค์–ด๊ฐ€๋ฏ€๋กœ ๊ธ€์ž์ˆ˜๋ฅผ 15๋ฐ”์ดํŠธ๊นŒ์ง€๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
The size of cmd_buffer is 16 bytes; since a null terminator (0) is placed at the end, the character count is limited to 15 bytes.

— 15์ž๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด key_loop๋ผ๋ฒจ๋กœ ์ ํ”„ํ•ฉ๋‹ˆ๋‹ค.
If it exceeds 15 characters, it jumps to the key_loop label.

— ์ถ”๊ฐ€ ์ž…๋ ฅํ•˜๋ฉด ํ™”๋ฉด์ƒ์—๋Š” ๊ณ„์† ๊ฐ™์€์ž๋ฆฌ์— ์ปค์„œ๊ฐ€ ์žˆ๊ณ  ๋ณ€ํ™”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
If you enter more input, the cursor remains in the same position on the screen, and there is no change.

    cmp cx, 15
    je key_loop

— ํ™”๋ฉด์— ๊ธ€์ž๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
It outputs text to the screen.

    mov ah, 0x0e
    int 0x10

— ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๋ฅธ ๊ธ€์ž๊ฐ€ ์ €์žฅ๋œ al๋ ˆ์ง€์Šคํ„ฐ์˜ ๋‚ด์šฉ์„ cmd_buffer์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
The contents of the AL register, which holds the character pressed by the user, are stored in cmd_buffer.

mov [di], al

— ๋‹ค์Œ ์ €์žฅ ์œ„์น˜๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
Navigate to the following save location.

— inc (Increment): ๊ฐ’์„ 1 ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค.
inc (Increment): An instruction that increments a value by 1.

— DI ๋ ˆ์ง€์Šคํ„ฐ์— ๋“ค์–ด์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ์ˆซ์ž๋ฅผ 1 ๋Š˜๋ ค์ค๋‹ˆ๋‹ค. (์˜ˆ: 0x8064 โž” 0x8065)
Increments the memory address value stored in the DI register by 1. (e.g., 0x8064 โž” 0x8065)

— ์ฃผ์†Œ๋ฅผ 1 ๋Š˜๋ ค์ฃผ์–ด์•ผ ๋‹ค์Œ๋ฒˆ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ƒˆ๋กœ์šด ํ‚ค๋ฅผ ๋ˆ„๋ฅผ ๋•Œ, ๋ฐฉ๊ธˆ ์“ด ๊ธ€์ž ์œ„์— ๊ฒน์ณ ์“ฐ์ง€ ์•Š๊ณ  ๊ทธ ๋ฐ”๋กœ ์˜† ์นธ(๋‹ค์Œ ๋ฐ”์ดํŠธ)์— ์ƒˆ ๊ธ€์ž๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
This is because the address must be incremented by 1 so that the next time the user presses a key, the new character can be stored in the adjacent cell (the next byte) instead of overwriting the character just written.

inc di 

— ๊ธ€์ž ์ˆ˜๋ฅผ ์„ธ๋Š” ์นด์šดํ„ฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.
Increments the character count.

inc cx

— ์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์‹ค์ œ ๋ฉ”์ธ ๋กœ์ง์ž…๋‹ˆ๋‹ค.
This covers the actual main logic.


โœ”๏ธ ๋ฐฑ์ŠคํŽ˜์ด์Šค ์ฒ˜๋ฆฌ๋ฃจํ‹ด(backspace:)
Backspace handling routine (backspace:)

— ์ž…๋ ฅ๋œ ๊ธ€์ž๊ฐ€ 0์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ๋œ ๊ธ€์ž๊ฐ€ ์—†๋Š”๋ฐ ๋ฐฑ์ŠคํŽ˜์ด์Šค ํ‚ค๋ฅผ ๋ˆ„๋ฅธ๊ฒฝ์šฐ key_loop๋ผ๋ฒจ(ํ‚ค๋ณด๋“œ ์ž…๋ ฅ๋ฐ›๊ธฐ)๋กœ ์ ํ”„ํ•ฉ๋‹ˆ๋‹ค.
It checks whether the input string is empty. If the Backspace key is pressed when there is no input, it jumps to the key_loop label (to receive keyboard input).

cmp cx, 0 
je key_loop

— ํ™”๋ฉด์—์„œ ๊ธ€์ž๋ฅผ ์ง€์šฐ๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
This is the part where text is erased from the screen.

— ์ปดํ“จํ„ฐ ๋‚ด๋ถ€์˜ ํ™”๋ฉด ์ œ์–ด ์‹œ์Šคํ…œ(BIOS)์—๋Š” ‘๋ฐฉ๊ธˆ ์“ด ๊ธ€์ž๋ฅผ ์ง€์šฐ๋Š” ํŽธ๋ฆฌํ•œ ์‚ญ์ œ ๊ธฐ๋Šฅ’์ด ๋”ฐ๋กœ ์—†์Šต๋‹ˆ๋‹ค. ์˜ค์ง ์ƒˆ๋กœ์šด ๊ธ€์ž๋ฅผ ์œ„์— ๋ฎ์–ด์“ฐ๋Š” ๊ธฐ๋Šฅ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.
The screen control system (BIOS) inside the computer does not have a dedicated, convenient delete function for erasing the characters just written; it only has a function to overwrite them with new characters.

— ๋”ฐ๋ผ์„œ ๊ธ€์ž๋ฅผ ์ง€์šฐ๋ ค๋ฉด “์ง€์šฐ๊ณ  ์‹ถ์€ ์œ„์น˜๋กœ ์ปค์„œ๋ฅผ ์˜ฎ๊ธด ๋’ค, ‘๊ณต๋ฐฑ(์ŠคํŽ˜์ด์Šค๋ฐ”)’ ๋ฌธ์ž๋ฅผ ๊ฐ•์ œ๋กœ ๋ฎ์–ด์จ์„œ ๊ธ€์ž๋ฅผ ์•ˆ ๋ณด์ด๊ฒŒ ๊ฐ€๋ฆฝ๋‹ˆ๋‹ค.
Therefore, to erase a character, move the cursor to the desired position and overwrite the character with a space (using the spacebar) to hide it from view.

— ๋ฐ”์ด์˜ค์Šค ํ…”๋ ˆ๊ทธ๋ž˜ํ”„ ๊ธฐ๋Šฅ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
Select the BIOS Telegraph function.

mov ah, 0x0e

— al๋ ˆ์ง€์Šคํ„ฐ์— 8์„ ๋Œ€์ž…ํ•ฉ๋‹ˆ๋‹ค.ASCII ์ฝ”๋“œ 8๋ฒˆ์€ ‘๋ฐฑ์ŠคํŽ˜์ด์Šค(Backspace)’ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค.
Assign 8 to the AL register. ASCII code 8 represents the ‘Backspace’ character.

— int 0x10๋กœ BIOS ๋น„๋””์˜ค ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.(๊ธฐ๋Šฅ ์‹คํ–‰)
Executes the BIOS video interrupt using int 0x10 (executes the function).

mov al, 8
int 0x10

— ํ˜„์žฌ์œ„์น˜๋ฅผ ๊ณต๋ฐฑ์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.
Changes the current location to a blank space.

 mov al, ' '
 int 0x10

— ์™ผ์ชฝ์œผ๋กœ ์ปค์„œ๋ฅผ ํ•œ์นธ ์˜ฎ๊น๋‹ˆ๋‹ค.
Moves the cursor one space to the left.

mov al, 8
int 0x10

— ๋ฒ„ํผ๋ฉ”๋ชจ๋ฆฌ(di)๋ฅผ 1 ๊ฐ์†Œํ•˜๊ณ , ๊ธ€์ž์ˆ˜ ์นด์šดํ„ฐ๋ฅผ 1๊ฐ์†Œํ•ฉ๋‹ˆ๋‹ค.
Decrement the buffer memory (di) by 1 and decrement the character count counter by 1.

— key_loop๋ผ๋ฒจ๋กœ ์ ํ”„ํ•ฉ๋‹ˆ๋‹ค.
Jump to the key_loop label.

 dec di              
 dec cx  
 jmp key_loop           

โœ”๏ธ ์—”ํ„ฐ๋ฅผ ์ณค์„ ๋•Œ ์ž…๋ ฅ๋œ ๋ช…๋ น์–ด๋ฅผ ๋น„๊ตํ•˜๋Š” ๊ณณ
The place where the entered command is compared when the Enter key is pressed.

— ํ˜„์žฌ ์œ„์น˜์— 0์„ ์ž…๋ ฅํ•ด์„œ ๋ช…๋ น์–ด์˜ ๋์ž„์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
Enter 0 at the current position to indicate the end of the command.

— DI ์ฃผ์†Œ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์— ๋”ฑ 1๋ฐ”์ดํŠธ ํฌ๊ธฐ๋งŒํผ๋งŒ 0์„ ๋Œ€์ž…ํ•˜๋ผ๋Š” ํฌ๊ธฐ ์ง€์ • ํ‚ค์›Œ๋“œ ์ž…๋‹ˆ๋‹ค.
This is a size-specifying keyword that instructs to assign a zero value of exactly one byte in size to the location pointed to by the DI register.

byte: 1๋ฐ”์ดํŠธ ํฌ๊ธฐ (8๋น„ํŠธ) / 1-byte size (8 bits) โž” mov byte [di],

word: 2๋ฐ”์ดํŠธ ํฌ๊ธฐ (16๋น„ํŠธ) / 2-byte size (16-bit) โž” mov word [di], 0

dword: 4๋ฐ”์ดํŠธ ํฌ๊ธฐ / 4-byte size (32๋น„ํŠธ/32 bit, Double Word) โž” mov dword [di], 0

mov byte [di], 0

— ์ค„ ๋ฐ”๊ฟˆ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
Performs a line break.

call print_newline

— ์•„๋ž˜์— print_newline:๋ผ๋ฒจ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
There is a print_newline: label below.

— mov ah, 0x0e :
ํ…”๋ ˆํƒ€์ดํ”„ ๋ฐฉ์‹ ์ถœ๋ ฅ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
Configures teletype-style output.

— mov al, 13 & int 0x10
ํ˜„์žฌ ์œ„์น˜ํ•œ ์ค„์˜ ๋งจ ์™ผ์ชฝ(์ฒซ ๋ฒˆ์งธ ์นธ)์œผ๋กœ ์ด๋™ ํ•ฉ๋‹ˆ๋‹ค.(์ผ€๋ฆฌ์ง€๋ฆฌํ„ด,\r)
Moves to the leftmost position (the first cell) of the current line (Carriage Return, \r).

–mov al, 10 & int 0x10 :
์ปค์„œ๋ฅผ ํ•œ ์ค„ ์•„๋ž˜๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.(๋ผ์ธํ”ผ๋“œ,\n)
Moves the cursor down one line (Line Feed, \n).

— ref
์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋˜ ๋ฉ”์ธ ๋กœ์ง์˜ ์ž๋ฆฌ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
Navigate to the location in the main logic where this function was called.

print_newline:
    mov ah, 0x0e
    mov al, 13
    int 0x10
    mov al, 10
    int 0x10
    ret

๐Ÿ‘‰๐Ÿป ์Šคํฌ๋ฆฐ ์ƒท / ScreenShot

โœ… ๋‚˜๋จธ์ง€ ์„ค๋ช…์€ ๋‹ค์Œ ํฌ์ŠคํŠธ์—์„œ์ด์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.
I will continue with the rest of the explanation in the next post.

Leave a Reply