纯汇编实现从硬盘读取字符串并输出到TTTY的技术问询
Hey there! Let's build out that hard disk string read + TTY output functionality you need for your "full-handheld assembly OS" project. Since you've already nailed reading a single character from disk and printing it, we can expand that logic step by step:
1. Expand Hard Disk Read Logic to Fetch Strings
First, let's adjust your disk read code to capture entire strings (which may span one or more sectors). The core BIOS interrupt for disk reads is int 0x13 with AH=0x02 (read sectors). Here's how to refine it:
- Set
ALto the number of sectors you need to read (e.g.,AL=2if your string spans two sectors) - Configure
CH(cylinder number),CL(sector number),DH(head number) to point to where your string is stored on disk - Load
ES:BXwith the address of a memory buffer large enough to hold the string (make sure this buffer lives outside the 512-byte boot sector to avoid overwriting critical code) - After calling
int 0x13, check the carry flag (CF) to confirm success—if CF is set, the read failed, so add basic error handling (like printing an error message) if needed.
Example assembly snippet for disk read:
; DL holds drive number (auto-set by BIOS on boot) mov ah, 0x02 ; BIOS read sector function mov al, 0x01 ; Read 1 sector (adjust if your string is larger) mov ch, 0x00 ; Cylinder 0 mov cl, 0x02 ; Sector 2 (boot sector is sector 1) mov dh, 0x00 ; Head 0 mov bx, 0x7E00 ; Buffer at 0x7E00 (right after boot sector) int 0x13 ; Call disk interrupt jc disk_error ; Jump if carry flag is set (read failed)
2. Implement TTY String Output
Once your string is loaded into memory, use the BIOS TTY interrupt (int 0x10 with AH=0x0E) to print each character until you hit a null terminator (0x00):
- Use a register (like
BX) as a pointer to the start of your string - Loop: load the character at
[BX], check if it's0x00(end of string) - If valid, call
int 0x10to print, then incrementBXto move to the next character - Repeat until the null terminator is found.
Example assembly snippet for string output:
print_string: mov ah, 0x0E ; TTY output function mov si, bx ; SI points to our string buffer print_loop: lodsb ; Load byte at SI into AL, increment SI cmp al, 0x00 ; Check for null terminator je print_done ; Exit loop if we're done int 0x10 ; Print the character jmp print_loop print_done: ret
3. Integrate and Debug
- After reading the disk into your buffer (e.g.,
0x7E00), setBXto that buffer address and callprint_string - For debugging in QEMU, use flags like
qemu-system-i386 -fda your_os_image.img -gdb tcp::1234 -Sto pause at startup, then connect with GDB to step through the disk read and print logic - Verify register values (especially
ES:BXand the result ofint 0x13) to ensure the string is loaded correctly into memory before printing
Once you get this working, you'll have the key functionality to break past the 512-byte boot sector limit and load larger OS components. Happy coding!
内容的提问来源于stack exchange,提问作者Dahlia Radio

