Search code examples
assemblyoperating-systemfasm

How to add text to OS written in assembly


So I started learning assembly and am writing a simple OS with FASM. I have a blue screen with a gray top bar and a cursor but can't get text to appear on a line. On the top line I want it to say "FILE SYSTEM" and then on other lines I want other stuff. I'll put the code here:

mov ax, 9ch
mov ss, ax
mov sp, 4096d
mov ax, 7c0h
mov ds, ax
;----------------


;this sets blue to background
mov ah, 09h
mov cx, 1000h
mov al, 20h
mov bl, 17h
int 10h
;end of blue

;start of gray top
mov ah, 09h
mov cx, 80d
mov al, 20h
mov bl, 87h
int 10h
;end of gray
;top bar






;end of top bar
;define mouse
mov ah, 01h
mov cx, 07h
int 10h

mov bl, 5h
mov cl, 5h


_mouser:
mov ah, 02h
mov dl, bl
mov dh, cl
int 10h

mov ah, 00h
int 16h

cmp al, 77h
je _up
cmp al, 73h
je _down
cmp al, 61h
je _left
cmp al, 64h
je _right
cmp al, 20h
je _click
jmp _mouser



_click:
mov ah, 0eh
mov al, 0b2h
int 10h
jmp _mouser

_up:
cmp cl, 0h
je _mouser
sub cl, 1h
jmp _mouser

_down:
cmp cl, 24d
je _mouser
add cl, 1h
jmp _mouser

_left:
cmp bl, 0h
je _mouser
sub bl, 1h
jmp _mouser

_right:
cmp bl, 79d
je _mouser
add bl, 1h
jmp _mouser



;----------------
times 510-($-$$) db 0
dw 0xAA55

i have tried

mov ah, eoh
mov al, 'F'
int 10h

problem is that can only make a single character not a string.


Solution

  • The PC's ROM BIOS provides a set of video services, invoked via interrupt 10h, including some that print characters to the string. Comprehensive documentation for them can be found here.

    It seems you have already discovered service 0Eh, which writes a single character to the screen at the current character position and advances the character position. This treats the screen as if it were a teletype (TTY), and makes it very easy to get output on the screen.

    (At least, it looks like you were trying to invoke service 0Eh. Your code wasn't correct. You had mov ah, eoh, which isn't correct. o isn't a hexadecimal value, and even if that was a typo for 0, you have the nibbles reversed. It should be mov ah, 0Eh.)

    If you want to print a string (multiple characters), you essentially have two options:

    1. You can iteratively invoke a service like 0Eh, writing a single character to the string each time. An example implementation of this would be:

          mov  ah, 0Eh             ; service 0Eh: print char as TTY
      .PrintNextChar:
          mov  al, BYTE PTR [si]   ; get next character in string, pointed to by SI
          inc  si                  ; increment pointer
          test al, al              ; is character == 0 (end-of-string)?
          je   .Done
          int  10h
          jmp  .PrintNextChar
      .Done
      

      This prints characters from the string pointed to by SI until it reaches a 0 (NUL character), which signifies the end of the string (a standard C-style NUL-terminated string).

      However, this print-one-character-at-a-time method is relatively slow. Instead, one usually prefers to…

    2. Use service 1300h or 1301h to print an entire string at once. The difference is that service 1301h advances the cursor after printing the string, whereas service 1300h doesn't change the cursor. Otherwise, they are the same.

      The parameters for these services are documented in the link above; reprinted here for convenience:

      • AX == 1300h/1301h
      • BL == video attribute (in text mode, specifies foreground and background colors)
      • BH == video page (usually 0)
      • CX == length of string
      • DL/DH == column/row of starting position for string
      • ES:BP == address of beginning of string

      Obviously this requires that you know the length of the string in advance, and pass it in as a parameter in the CX register. The string is pointed to by ES:BP.

      In your case, to print "FILE SYSTEM", you would declare an array of characters in your DATA segment that contained this string, then do something like:

      MyString DB "FILE SYSTEM"
      
      mov  ax, ds
      mov  es, ax          ; set ES == DS
      mov  bp, MyString
      mov  cx, 11          ; length of string (number of chars)
      mov  bx, 07h         ; foreground & background color (white on black)
      xor  dx, dx          ; starting position (top-left)
      mov  ax, 1301h       ; service 1301h: print string and update cursor
      int  10h