[OS]miniOS-2

๐Ÿ‘‰๐Ÿป ์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” ํ™”๋ฉด์— ‘X’๋Œ€์‹ ์— Hello miniOS!๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
The code below outputs “Hello miniOS!” to the screen instead of “X”.

๐Ÿ‘‰๐Ÿป boot.asm ์ „์ฒด ์ฝ”๋“œ / full code

; BIOS๊ฐ€ ์ด ์ฝ”๋“œ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ 0x7C00์— ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
; The BIOS loads this code into memory at 0x7C00.
[org 0x7c00]

; 16๋น„ํŠธ ๋ฆฌ์–ผ ๋ชจ๋“œ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
; Executes in 16-bit real mode.
bits 16

start:
    ; ๋ฐ์ดํ„ฐ ์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ ์ดˆ๊ธฐํ™”
    ; Initialize data segment register
    mov ax, 0
    mov ds, ax

    ; ๋ฌธ์ž์—ด์˜ ์‹œ์ž‘ ์ฃผ์†Œ๋ฅผ SI ๋ ˆ์ง€์Šคํ„ฐ์— ์ €์žฅ
    ; Store the starting address of the string in the SI register
    mov si, msg

; ๋ฌธ์ž์—ด์„ ํ•œ ๊ธ€์ž์”ฉ ์ฝ์–ด์™€ ์ถœ๋ ฅํ•˜๋Š” ๋ฃจํ”„
; A loop that reads and prints a string character by character
print_loop:
    ; SI๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฃผ์†Œ์—์„œ 1๋ฐ”์ดํŠธ๋ฅผ AL์— ๋กœ๋“œํ•˜๊ณ  SI๋ฅผ 1 ์ฆ๊ฐ€์‹œํ‚ด
    ; Load 1 byte from the address pointed to by SI into AL and increment SI by 1
    lodsb           

    ; ๊ฐ€์ ธ์˜จ ๋ฌธ์ž๊ฐ€ 0(๋ฌธ์ž์—ด์˜ ๋)์ธ์ง€ ํ™•์ธ
    ; Check if the retrieved character is 0 (end of string)
    cmp al, 0     

    ; 0์ด๋ฉด ๋ฌดํ•œ ๋ฃจํ”„๋กœ ์ด๋™ํ•˜์—ฌ ์ข…๋ฃŒ
    ; If 0, jump to the infinite loop and terminate.
    je hang         

    ; BIOS ํ…”๋ ˆํƒ€์ดํ”„ ์ถœ๋ ฅ ๊ธฐ๋Šฅ ์„ ํƒ
    ; Select BIOS teletype output function
    mov ah, 0x0e    

    ; BIOS ๋น„๋””์˜ค ์ธํ„ฐ๋ŸฝํŠธ ํ˜ธ์ถœํ•˜์—ฌ AL์˜ ๋ฌธ์ž ์ถœ๋ ฅ
    ; Call BIOS video interrupt to output the character in AL
    int 0x10       

    ; ๋‹ค์Œ ๊ธ€์ž ์ถœ๋ ฅ์„ ์œ„ํ•ด ๋ฃจํ”„ ๋ฐ˜๋ณต
    ; Loop to print the next character
    jmp print_loop  

; ํ˜„์žฌ ์œ„์น˜($)์—์„œ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.
; Waits in an infinite loop at the current location ($).
hang:
    jmp $

; ์ถœ๋ ฅํ•  ๋ฌธ์ž์—ด ์ •์˜ (๋์— 0์„ ๋ถ™์—ฌ ๋ฌธ์ž์—ด์˜ ๋์„ ํ‘œ์‹œ)
; Define the string to output (append 0 to mark the end of the string)
msg db 'Hello miniOS!', 0

; 512๋ฐ”์ดํŠธ ์ค‘ ๋นˆ ๊ณต๊ฐ„์„ ๋ชจ๋‘ 0์œผ๋กœ ์ฑ„์›๋‹ˆ๋‹ค.
; Fill all remaining space within the 512 bytes with zeros.
times 510 - ($ - $$) db 0

; ์ด ๋””์Šคํฌ๊ฐ€ ๋ถ€ํŒ… ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ฆฌ๋Š” ๋ถ€ํŠธ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์ €์žฅ
; Store the boot signature indicating that this disk is bootable.
dw 0xaa55

# 1. ์–ด์…ˆ๋ธ”๋ฆฌ์–ด ์ฝ”๋“œ๋ฅผ ์ˆœ์ˆ˜ํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ(.bin)๋กœ ์ปดํŒŒ์ผ
# Compile assembly code into a pure binary file (.bin)
nasm -f bin boot.asm -o boot.bin

# 2. QEMU ์—๋ฎฌ๋ ˆ์ดํ„ฐ์— ์ด ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋””์Šคํฌ๋กœ ๋„ฃ์–ด ๊ฐ€์ƒ ์ปดํ“จํ„ฐ ๋ถ€ํŒ…
# Put this binary on a disk and boot the virtual machine in the QEMU emulator
qemu-system-x86_64 -drive format=raw,file=boot.bin

๐Ÿ‘‰๐Ÿป ์ฝ”๋“œ์„ค๋ช… / Code description

โœ”๏ธ ๋ ˆ์ง€์Šคํ„ฐ ax,ds๋ฅผ 0 ์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ
Initialize registers ax and ds to 0.

    mov ax, 0
    mov ds, ax

— ๋ ˆ์ง€์Šคํ„ฐ(Register)๋Š” ๋ณ€์ˆ˜์™€ ๋น„์Šทํ•˜์ง€๋งŒ, CPU(์ปดํ“จํ„ฐ์˜ ๋‘๋‡Œ) ๋‚ด๋ถ€์— ์กด์žฌํ•˜๋Š” ‘์ดˆ๊ณ ์† ๋ฏธ๋‹ˆ ์ €์žฅ ๊ณต๊ฐ„’์ž…๋‹ˆ๋‹ค.(RAM์ด ์•„๋‹˜)
A register is similar to a variable, but it is a “high-speed mini-storage space” located inside the CPU (the brain of the computer)โ€”not in RAM.

— ax์™€ ds๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
The reasons for initializing ax and ds to zero are as follows.

1) ds์— ์“ฐ๋ ˆ๊ธฐ ๊ฐ’์ด ๋“ค์–ด ์žˆ์„ ์ˆ˜ ์žˆ์–ด์„œ 0์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค. ์“ฐ๋ ˆ๊ธฐ ๊ฐ’์ด ์žˆ์œผ๋ฉด ์ž˜๋ชป๋œ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
ds may contain garbage values, so it is initialized to zero; if garbage values โ€‹โ€‹are present, it would point to an invalid address.

2)์ฃผ์†Œ ๊ณ„์‚ฐ๊ณต์‹
Address calculation formula

์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ(ds)๊ฐ€ 0์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜์˜ ๋ฐ์ดํ„ฐํฌ๊ธฐ๊ฐ€ ์ฃผ์†Œ์œ„์น˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
Since the segment register (ds) is 0, the data size of the variable becomes the address location.

์ง„์งœ ์ฃผ์†Œ = (์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ ร— 16) + ๋ณ€์ˆ˜์˜ ์œ„์น˜(์˜คํ”„์…‹)
Actual address = (segment register ร— 16) + variable location (offset)

— ์•„๋ž˜์˜ ๐Ÿ““๋ถ€๋ถ„์€ ๋ณ€์ˆ˜,๋ ˆ์ง€์Šคํ„ฐ์— ๋Œ€ํ•œ ๊ฐœ๋… ๋ฐ ์šฉ๋„ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.
The section marked ๐Ÿ““ below explains the concepts and purposes of variables and registers.



๐Ÿ““ ๋ณ€์ˆ˜์™€ ๋ ˆ์ง€์Šคํ„ฐ์˜ ํ•ต์‹ฌ ์ฐจ์ด์ 
Key differences between variables and registers

1)์–ด์…ˆ๋ธ”๋Ÿฌ์—์„œ ๋ ˆ์ง€์Šคํ„ฐ์— ๋“ฑ๋กํ•˜๋Š”๊ฑด ๋ณ€์ˆ˜๋“ฑ๋ก๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
Registering a register in an assembler is similar to declaring a variable, but there are the following differences.

๊ตฌ๋ถ„ (Category)๋ณ€์ˆ˜ (Variable)๋ ˆ์ง€์Šคํ„ฐ (Register)
์œ„์น˜ / Location์ปดํ“จํ„ฐ์˜ ๋ฉ”๋ชจ๋ฆฌ(RAM)
Computer memory (RAM)
CPU ๋‚ด๋ถ€ ํ•˜๋“œ์›จ์–ด
Internal CPU hardware
๊ฐœ์ˆ˜ / Quantity๋ฉ”๋ชจ๋ฆฌ ์šฉ๋Ÿ‰์ด ํ—ˆ์šฉํ•˜๋Š” ํ•œ ๋ฌดํ•œ๋Œ€
Infinite as long as memory capacity allows
CPU ์„ค๊ณ„ ์‹œ ๊ณ ์ •๋จ (์ˆ˜์‹ญ ๊ฐœ ๋‚ด์™ธ)
Fixed during CPU design (around a few dozen)
์ด๋ฆ„ / Nameage, name ๋“ฑ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งˆ์Œ๋Œ€๋กœ ์ง€์Œ
Age, name, etc. are named arbitrarily by the developer
ax, bx, cx, ds ๋“ฑ ์ด๋ฏธ ์ •ํ•ด์ ธ ์žˆ์Œ
ax, bx, cx, ds, etc., are already defined.
์†๋„ / Speed๋น ๋ฆ„ / fast์ปดํ“จํ„ฐ์—์„œ ๊ฐ€์žฅ ๋น ๋ฆ„ (๋ฉ”๋ชจ๋ฆฌ๋ณด๋‹ค ์ˆ˜์‹ญ ๋ฐฐ)
Fastest in the computer (dozens of times faster than memory)

๐Ÿ““ ๋ ˆ์ง€์Šคํ„ฐ์˜ ์ข…๋ฅ˜ ๋ฐ ์šฉ๋„
Types and Uses of Registers

1-1) ์ผ๋ฐ˜ ๊ณ„์‚ฐ์šฉ ๊ณต๊ฐ„(๋ฒ”์šฉ ๋ ˆ์ง€์Šคํ„ฐ)
General-purpose calculation space (general-purpose registers)

AX (Accumulator - ๋ˆ„์‚ฐ๊ธฐ/์—ฐ์‚ฐ์šฉ)
AX (Accumulator - for accumulation/calculation)

-- ์ˆ˜ํ•™ ์—ฐ์‚ฐ(๋”ํ•˜๊ธฐ, ๊ณฑํ•˜๊ธฐ)์˜ ์ค‘์‹ฌ์ด์ž, ์ž…์ถœ๋ ฅ์˜ ๋Œ€๋ฆฌ์ธ์ž…๋‹ˆ๋‹ค.
It is the hub of mathematical operations (addition, multiplication) and the agent for input and output.

-- ์œ„ ์ฝ”๋“œ์—์„œ mov ah, 0x0e๋ฅผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ ah, al์ด ๋ฐ”๋กœ ์ด ax๋ฅผ ๋ฐ˜์”ฉ ์ชผ๊ฐœ์„œ ์“ฐ๋Š” ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. BIOS ๊ธฐ๋Šฅ์„ ํ˜ธ์ถœํ•  ๋•Œ ๋ฒˆํ˜ธํ‘œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
In the code above, the `ah` and `al` used with `mov ah, 0x0e` are the names for the two halves of the `ax` register; they serve as function identifiers when calling BIOS services.

BX (Base - ๊ธฐ์ค€ ์ฃผ์†Œ์šฉ)
BX (Base - for base address)

-- ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ • ์ฃผ์†Œ(์œ„์น˜)๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋‚˜์นจ๋ฐ˜ ์—ญํ• ์„ ์ž์ฃผ ํ•ฉ๋‹ˆ๋‹ค.
It often acts as a compass pointing to a specific memory address (or location).

CX (Counter - ๋ฐ˜๋ณต ํšŸ์ˆ˜์šฉ)
CX (Counter - for repetition count)

-- or๋ฌธ ๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ(Loop)์ด ๋ช‡ ๋ฒˆ ๋Œ์•˜๋Š”์ง€ ์„ธ๋Š” ๊ณ„์ˆ˜๊ธฐ์ž…๋‹ˆ๋‹ค. ๋ฃจํ”„ ๋ช…๋ น์–ด๋ฅผ ์“ฐ๋ฉด CPU๊ฐ€ ์ž๋™์œผ๋กœ cx ๊ฐ’์„ 1์”ฉ ๊นŽ์œผ๋ฉด์„œ 0์ด ๋  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.
It is a counter that tracks the number of iterations for loops, such as the `loop` instruction. When the `loop` instruction is used, the CPU automatically decrements the `CX` register by 1 in each iteration until it reaches zero.

DX (Data - ๋ฐ์ดํ„ฐ ํ™•์žฅ์šฉ)
DX (Data - for data expansion)

-- ax๋งŒ์œผ๋กœ ๋‹ด๊ธฐ ํž˜๋“  ๋„ˆ๋ฌด ํฐ ์ˆซ์ž๋ฅผ ๊ณฑํ•˜๊ฑฐ๋‚˜ ๋‚˜๋ˆŒ ๋•Œ ์„œ๋ธŒ ์ฃผ๋จธ๋‹ˆ๋กœ ๋•๊ฑฐ๋‚˜, ํ•˜๋“œ์›จ์–ด ์žฅ์น˜์™€ ์†Œํ†ตํ•  ๋•Œ ์”๋‹ˆ๋‹ค.
It is used to assist with multiplication or division involving numbers too large to fit into the `ax` register aloneโ€”acting as a secondary storageโ€”or when communicating with hardware devices.

1-2) ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์—ญ ๊ด€๋ฆฌ์šฉ ๊ณต๊ฐ„ (์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ)
Space for memory area management (segment registers)

DS๋Š” ์œ„ ๊ตฌ์—ญ๋“ค๊ณผ ์ข…๋ฅ˜๊ฐ€ ์•„์˜ˆ ๋‹ค๋ฅธ ์„ธ๊ทธ๋จผํŠธ(Segment) ๋ ˆ์ง€์Šคํ„ฐ์ž…๋‹ˆ๋‹ค. 16๋น„ํŠธ ์ปดํ“จํ„ฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋„ˆ๋ฌด ๋„“์–ด์„œ, ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ ๊ตฌ์—ญ์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
The DS is a segment register that belongs to a completely different category than the aforementioned areas. Because the memory space in 16-bit computers is so vast, memory is managed by dividing it into multiple sections.

DS (Data Segment) - ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ ์ธ๋ฑ์Šค์Šคํ‹ฐ์ปค / Index stickers for locating data

-- "์ง€๊ธˆ๋ถ€ํ„ฐ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜๋‚˜ ๋ฌธ์ž์—ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋Š” ๋ชจ๋‘ ์ด ์—ฌ๊ธฐ์—์„œ ์ฐพ์œผ๋ผ"๊ณ  ๊ธฐ์ค€์ ์„ ์žก๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
It serves as a reference point, indicating, "Look here for any dataโ€”such as variables or stringsโ€”that will be used from this point forward."

-- mov ds, ax๋กœ ๋ฐ์ดํ„ฐ ๋™๋„ค ๊ธฐ์ค€์ ์„ 0์œผ๋กœ ์žก์•˜๊ธฐ ๋•Œ๋ฌธ์—, CPU๊ฐ€ msg ๋ฌธ์ž์—ด์˜ ์ •ํ™•ํ•œ ์œ„์น˜๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
By setting the data segment base address to 0 with the instruction `mov ds, ax`, the CPU was able to locate the exact position of the `msg` string.

CS (Code Segment): 
๋‚ด๊ฐ€ ์‹คํ–‰ํ•  ์ง„์งœ ๋ช…๋ น์–ด(์ฝ”๋“œ)๋“ค์ด ๋ชจ์—ฌ ์žˆ๋Š” ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค.
This is the address where the actual commands (code) I am to execute are located.

SS (Stack Segment): 
ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ์ž„์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž ์‹œ ์Œ“์•„๋‘๋Š” '์Šคํƒ'์ด๋ผ๋Š” ์ž„์‹œ ์ €์žฅ ๊ณต๊ฐ„์˜ ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค.
It is the address of a temporary storage space called the "stack," used for calling functions or briefly storing temporary data.


โœ”๏ธ ์ถœ๋ ฅํ•  ๋ฌธ์ž์—ด 'Hello miniOS!', 0์ด ์ €์žฅ๋œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์‹œ์ž‘ ์ฃผ์†Œ๋ฅผ SI ๋ ˆ์ง€์Šคํ„ฐ์— ๋„ฃ์Šต๋‹ˆ๋‹ค.
Load the starting address of the memory containing the string ‘Hello miniOS!’ and the value 0 into the SI register.

mov si, msg

— msg๋Š” ์ฝ”๋“œ ์œ—๋ถ€๋ถ„์—์„œ ์ดˆ๊ธฐํ™” ํ•œ๋ถ€๋ถ„์ด ์—†์ง€๋งŒ ์•„๋ž˜์— ‘msg db ‘Hello miniOS!’, 0’์ด ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  si ๋ ˆ์ง€์Šคํ„ฐ์— ์ž๋™์œผ๋กœ ์ฃผ์†Œ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
Although msg is not explicitly initialized in the upper section of the code, the address is automatically registered in the SI register based on the line msg db 'Hello miniOS!', 0 found further down.

— si ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฐ”๋กœ ์•„๋ž˜์— lodsb(Load String Byte) ์ฝ”๋“œ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
The reason the SI register is used is because of the lodsb (Load String Byte) instruction immediately following it.

— lodsb(Load String Byte) ๋ช…๋ น์–ด๋Š” CPU ๋‚ด๋ถ€์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ•์ œ๋กœ ์•ฝ์†์ด ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
The lodsb (Load String Byte) instruction is hard-wired within the CPU to operate according to the following conventions:

"lodsb ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜๋ฉด, CPU๋Š” ๋ฌด์กฐ๊ฑด si ๋ ˆ์ง€์Šคํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋กœ ์ฐพ์•„๊ฐ€์„œ 1๋ฐ”์ดํŠธ๋ฅผ ์ฝ์–ด AL ๋ ˆ์ง€์Šคํ„ฐ์— ๋„ฃ๋Š”๋‹ค."

When the `lodsb` instruction is executed, the CPU unconditionally accesses the memory address pointed to by the `SI` register, reads one byte, and loads it into the `AL` register.

— ๊ทธ๋ž˜์„œ lodsb์™€ si๋ ˆ์ง€์Šคํ„ฐ๋Š” ๊ฐ™์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
Therefore, the lodsb instruction and the si register are used together.

— ์–ด์…ˆ๋ธ”๋Ÿฌ์—์„œ๋Š” ์ปดํŒŒ์ผ๋˜๊ธฐ์ „ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ์‚ดํŽด๋ณด๊ณ  ๊ณ„์‚ฐํ•œ ํ›„ ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค.
In the case of an assembler, the compiler examines and calculates the entire code before the actual compilation takes place.

โœ”๏ธ ํ…”๋ ˆํƒ€์ดํ”„ ๋ชจ๋“œ(ํ•œ๊ธ€์ž ์ถœ๋ ฅ ๊ธฐ๋Šฅ)
Teletype mode (character-by-character output function)

— ํ™”๋ฉด์— ํƒ€์ž๊ธฐ์ฒ˜๋Ÿผ ์ถœ๋ ฅํ•˜๋ผ๋Š” ๋ช…๋ น์ž…๋‹ˆ๋‹ค.
This is a command to output text to the screen like a typewriter.

— ํ…”๋ ˆํƒ€์ดํ”„ ๋ชจ๋“œ๋ฅผ ์„ ํƒํ•˜๋ฉด ์ปค์„œ ์ž๋™์ด๋™ ์ž๋™์ค„๋ฐ”๊ฟˆ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
Selecting Teletype mode enables automatic cursor movement and automatic line wrapping.

— al ๋ ˆ์ง€์Šคํ„ฐ ๋‚ด์˜ ๋ฌธ์ž ์ถœ๋ ฅ ๊ธฐ๋Šฅ์ธ int 0x10์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
It is used in conjunction with int 0x10, a function for outputting characters via the al register.

mov ah, 0x0e  

โœ”๏ธ ๋ฌดํ•œ๋ฃจํ”„ ์ด์ „ ๋ฐ˜๋ณต๋ฌธ์—์„œ msg db ‘Hello miniOS!’, 0์ด ๋ฐ์ดํ„ฐ ๋ถ€๋ถ„์„ ๋ชจ๋‘ ์ฐธ์กฐํ•˜๊ณ  ๋ฌดํ•œ๋ฃจํ”„๋กœ ๋Œ€๊ธฐ ํ•ฉ๋‹ˆ๋‹ค.
In the loop preceding the infinite loop, msg db 'Hello miniOS!', 0 references the entire data section, and the program then waits within the infinite loop.

jmp $

โœ”๏ธ ๋ฉ”๋ชจ๋ฆฌ msg์— Hello miniOS!0 ๊ฐ’์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
Enter the value “Hello miniOS!0” into the memory location msg.

— 0์€ ๋ฌธ์ž์—ด์˜ ๋์ž„์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค.
It is to verify that 0 marks the end of the string.

— ๋ณ€์ˆ˜์— ํƒ€์ž…์ด ์—†๋Š” ์ด์œ ๋Š” ๋ชจ๋‘ ascii๊ฐ’์œผ๋กœ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
The reason variables do not have types is that they are all stored as ASCII values.

msg db 'Hello miniOS!', 0

โœ”๏ธ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋‚˜๋จธ์ง€ ๊ณต๊ฐ„์„ ๋ชจ๋‘ 0์œผ๋กœ ์ฑ„์›๋‹ˆ๋‹ค.
Fill all remaining unused space with zeros.

— times๋Š” ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฐ˜๋ณต๋ช…๋ น์ง€์‹œ์–ด ์ž…๋‹ˆ๋‹ค.
‘times’ is not a variable; it is a command for repetition.

times 510 - ($ - $$) db 0

โœ”๏ธ ๋ถ€ํŒ…๊ฐ€๋Šฅํ•จ์„ ์ง€์‹œํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
This is the code that indicates bootability.

dw 0xaa55

๐Ÿ‘‹ ๊ฒฐ๋ก  / conclusion

โœ”๏ธ16๋น„ํŠธ ์ปดํ“จํ„ฐ์—์„œ ํ™”๋ฉด์— ๊ธ€์ž๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” msg๋ณ€์ˆ˜์— ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•ด๋†“๊ณ  ํ•œ๊ธ€์ž์”ฉ al๋ ˆ์ง€์Šคํ„ฐ์—์„œ ๊ฐ€์ ธ์™€์„œ ํ™”๋ฉด์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
To display characters on the screen of a 16-bit computer, the characters are stored in the msg variable, then retrieved one by one from the AL register and output to the screen.

โœ”๏ธ al๋ ˆ์ง€์Šคํ„ฐ์—์„œ ํ•œ๊ธ€์ž์”ฉ ๋ฌธ์ž๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ธฐ๋Šฅ์„ ๋ฐ˜๋ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ si ๋ ˆ์ง€์Šคํ„ฐ์™€ lodsb๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
To repeatedly fetch characters one by one from the register, the SI register and the lodsb instruction are used.

Leave a Reply