[OS] miniOS-4(2)

✔️ check_command: 부분이어서 설명합니다.
I am explaining this because it relates to the check_command: section.

— 입력된 글자가 아예 없으면 프롬프트 라벨로 이동합니다.
If no text has been entered, the focus moves to the prompt label.

— cmp cx, 0 입력된글자가 0개인 경우 promt로 점프합니다.
cmp cx, 0: If the number of entered characters is zero, the program jumps to the prompt.

    cmp cx, 0
    je prompt

— help명령어 / help command

1) 소스 포인터 레지스터(SI)에 사용자가 키보드로 입력한 문자열이 담긴 버퍼(cmd_buffer)의 시작 주소를 넣습니다.
Load the starting address of the buffer (cmd_buffer)—which contains the string entered by the user via the keyboard—into the source pointer register (SI).

mov si, cmd_buffer

2) 목적지 포인터 레지스터(DI)에 cmd_help변수의 시작 주소를 넣습니다.
Load the starting address of the cmd_help variable into the destination pointer register (DI).

mov di, cmd_help

3)cmd_buffer의 주소값과 cmd_help의 주소값을 비교합니다.
Compare the address of cmd_buffer with the address of cmd_help.

call compare_string

4)같으면 do_help로 점프합니다.
If they match, it jumps to do_help.

je do_help 

5)compare_string 함수 / compare_string function

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

5-1) 값의 비교 루틴 / Value comparison routine

1.si에 입력 문자 위치 저장: 사용자가 입력한 문자열 버퍼(cmd_buffer)의 시작 주소를 si에 넣습니다.
Store the input character location in SI: Load the starting address of the user-input string buffer (cmd_buffer) into SI.

✅ si(sourcd index)레지스터를 사용하지 않고 다른 레지스터를 사용해도 되지만 
그럼에도 불구하고 si를 굳이 선택해서 쓴 이유는 나중에 코드를 lodsb 형태로 업그레이드하기 편하게 만들기 위해서입니다.
You could use a different register instead of the SI (Source Index) register, but the reason I specifically chose SI is to make it easier to upgrade the code to use the `lodsb` instruction later.

lodsb 명령어는 CPU가 무조건 si 레지스터가 가리키는 곳에서 값을 읽어오도록 하는 명령어 입니다.
The `lodsb` instruction causes the CPU to unconditionally read a value from the memory location pointed to by the `si` register.

2.di에 비교 대상 주소 저장: 비교할 명령어 변수(cmd_help)의 시작 주소를 di에 넣습니다.
Store the address of the comparison target in DI: Load the starting address of the command variable to be compared (cmd_help) into DI.

3.al과 bl로 값 불러오기:si가 가리키는 위치의 값(입력한 첫 글자)을 al로 가져옵니다.
Loading values ​​into AL and BL: The value at the location pointed to by SI (the first character entered) is loaded into AL.

4.di가 가리키는 위치의 값(정답 첫 글자)을 bl로 가져옵니다.
Load the value at the location pointed to by di (the first character of the correct answer) into bl.

5.cmp al, bl로 진짜 비교: 두 레지스터에 담긴 순수한 데이터(글자)를 비교합니다.
A true comparison using `cmp al, bl`: This compares the raw data (characters) contained in the two registers.

5-2) 값이 서로 다르면 탈출하기
Exit if the values ​​are different.

5-2-1.jne는 Jump if Not Equal의 약자로 바로 윗줄에 있는 cmp al, bl 연산 결과 두 값이 서로 다를 때 .not_equal 레이블로 점프(이동)하라는 명령어입니다.
jne stands for “Jump if Not Equal”; it is an instruction that jumps (moves) to the .not_equal label if the two values ​​differ, based on the result of the cmp al, bl operation performed in the line immediately preceding it.

jne .not_equal

5-3) al레지스터를 1로 셋팅하고 cmp로 비교결과 0이 아니면 저장된 메인로직(do_help)로 이동합니다.
Set the AL register to 1, and if the comparison result from the cmp instruction is non-zero, jump to the stored main logic (do_help).

1을 셋팅하는 이유는 1로 초기화하지 않으면 기존의 값이 유지되고 있기 때문에 프로그램 오동작 방지를 위해서 값을 명확히 셋팅합니다.
The reason for setting the value to 1 is to explicitly initialize it; without doing so, the existing value would remain, potentially causing the program to malfunction.

.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

5-4) al레지스터의 값은 이미 0이므로 이전에 저장된 메인로직 do_help로 이동합니다.
Since the value of the AL register is already 0, the execution jumps to the previously stored main logic, do_help.

zero flag란 비교값이 0과 같으면 cpu 내부의zero flag란 값이 1이 됩니다.
The zero flag is a CPU flag that is set to 1 when the comparison value is equal to 0.

.equal:
    cmp al, 0           ; Zero Flag를 1로 만들어 '같음'을 알림 (AL이 0이므로)
                        ; Set Zero Flag to 1 to notify 'Equal' (Since AL is 0)
    ret

6) do_clear 함수 / do_clear function

6-1.16비트 바이오스는 화면을 지우는 기능이 없어서 화면을 밀어 올리는 방식을 사용합니다. 아래는 스크롤 업 기능 선택입니다.
Since the 16-bit BIOS lacks a screen-clearing function, it uses a method of shifting the screen upward. Shown below is the selection for the scroll-up function.

    mov ah, 0x06        ; 스크롤 업 기능
                        ; Scroll up function

6-2. 몇 줄을 올릴지 지정하지 않고 0을 지정하면 무한대로 화면을 위로 밀어올립니다.
If you specify 0 instead of a specific number of lines, the screen scrolls upward indefinitely.

    mov al, 0           ; 0 = 화면 전체 지우기
                        ; 0 = Clear entire screen

6-3. 빈공간에 CLI기본 색상인 바탕색과 글자색을 지정합니다.
Specify the default CLI background and text colors for the empty space.

이 부분이 없다면 bh에 이전에 다른 값이 들어있다면 화면에 다른 색상이 나타 날 수 있습니다.
Without this part, if bh already contains a different value, a different color might appear on the screen.

그래서 색상을 확실히 지정하는 안전장치 입니다.
So, it serves as a safeguard to explicitly specify the color.

    mov bh, 0x07        ; 바탕색 검정, 글자색 흰색
                        ; Background black, Foreground white

6-4.지우고 싶은 화면의 네모난 영역(범위)을 지정합니다.
Select the rectangular area (range) on the screen that you want to erase.

옛날 모니터의 텍스트 모드는 기본적으로 가로 80칸(0~79), 세로 25칸(0~24)의 글자판으로 이루어져 있습니다. 따라서 (0,0)부터 (24,79)까지 지정했다는 것은 모니터 전체 화면을 꽉 차게 지정했다는 뜻입니다.
The text mode of older monitors essentially consists of a character grid with 80 columns (0–79) and 25 rows (0–24). Therefore, specifying the range from (0, 0) to (24, 79) means designating the entire screen area.

mov ch, 0           ; 좌상단 행 (Top-left Row)
mov cl, 0           ; 좌상단 열 (Top-left Column)
mov dh, 24          ; 우하단 행 (Bottom-right row)
mov dl, 79          ; 우하단 열 (Bottom-right column)

6-5.바이오스 실행 / Run BIOS

int 0x10            

6-6.커서 위치 변경기능을 지정을 설정합니다.
Configure the cursor position change function.

mov ah, 0x02       

6-7.페이지 번호 지정,0번 비디오 페이지를 지정합니다.
Page number assignment: Specifies video page 0.

 mov bh, 0

6-8.커서를 이동할 목적지 주소를 지정합니다. (0,0)은 모니터 화면의 맨 왼쪽 위 구석을 의미합니다.
Specify the destination address for moving the cursor. (0,0) refers to the top-left corner of the monitor screen.

mov dh,0은 첫번째 행을 의미하고 mov dl,0은 좌측 첫번째 열을 의미합니다.
mov dh, 0 refers to the first row, and mov dl, 0 refers to the first column on the left.

mov dh, 0           
mov dl, 0           

6-9.promt라벨로 점프합니다.
Jump to the ‘prompt’ label.

jmp prompt

✔️ 나머지 코드는 변수설정부분과 초기화 부분입니다.
The remaining code consists of the variable declarations and the initialization section.

; ----------------------------------------------------
; 데이터 및 변수 선언 영역 (전역 변수)
; 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

Leave a Reply