1

How do I display a string in FASM when I'm makig an OS. I can do that (displays "8" character):

mov ax, 9ch
mov ss, ax
mov sp, 4096d
mov ax, 7c0h
mov ds, ax
;---- actual code:
mov ah, 0eh
mov al, 38h
int 10h
jmp $
;----
times 510 - ($-$$) db 0
dw 0xAA55  

but this doesn't work (i get black screen):

mov ax, 9ch
mov ss, ax
mov sp, 4096d
mov ax, 7c0h
mov ds, ax
;----
mov ah, 09h
mov dx, text

text:
db 'Hello$'

int 10h

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

Please tell me what am I doing wrong and how should I do it?

user3478487
  • 1,165
  • 2
  • 8
  • 10
  • possible duplicate of [Print a number in NASM - building an x86 Bootsector](http://stackoverflow.com/questions/30764183/print-a-number-in-nasm-building-an-x86-bootsector) – David Hoelzer Jun 16 '15 at 23:10
  • GAS hello world version: http://stackoverflow.com/questions/32508919/how-to-produce-a-minimal-bios-hello-world-boot-sector-with-gcc-that-works-from-a and a repository with working examples: https://github.com/cirosantilli/x86-bare-metal-examples – Ciro Santilli OurBigBook.com Sep 11 '15 at 09:11

2 Answers2

0

A couple of problems:

First, your string is in the middle of your code, so after executing mov dx, text the CPU will try to interpret the string 'Hello$' as code, which looks something like this:

dec ax
gs insb
outsw
and al, 0cdh
adc bl, ch
inc byte [bx+si]

As you can see, the original int 10h and jmp $ instructions are lost. To fix this, just move the text variable below your jmp $ statement.

Second, you seem to be confusing DOS functions and BIOS functions. Your second chunk of code is set up to use DOS to print a string (which, by the way, uses int 21h, not int 10h). Because you're writing an OS, however, you don't have any DOS functions available; you only have BIOS. Instead, you'll need to manually loop over the characters in the string and print each one until it reaches the end. An example might be something like this:

    mov si, text
    mov bx, 0007h ; set page to 0 and color to light gray text on black background
    mov ah, 0eh ; select single character print service
printLoop:
    lodsb ; grab next character from [si] and increment si
    cmp al, '$' ; check for end of string
    je printDone ; exit if done
    ; all parameters are set up - print the character now
    int 10h
    jmp printLoop ; run the loop again for the next character
printDone:
    ...
Drew McGowen
  • 11,471
  • 1
  • 31
  • 57
0

This might help you:

ORG 0x7c00

start:
    push cs
    pop ds         ; ds = None
    mov si, welcome
    call printl
    hlt ;or as you used jmp $

welcome db 'Welcome in os', 0

include 'sysf.asm'
times 510 - ($-$$) db 0

db 0x55
db 0xAA

and sysf.asm:

;SI is argument to function - string that you want to print out.
printl:
    pusha ;copy normal registers
    xor bx,bx ;clear bx
    jmp printl001
printl001:
    lodsb ;load next bit from si to al
    or al,al ;check is al = 0
    jz printl002 ;if al = 0 jump to printl002
    mov ah, 0x0e ; set ah to 0x0e for 0x10
    int 0x10 
    jmp printl001 ;continue printing (go again)
printl002:
    popa ;put old registers back
    ret ;go back to place of 'call printl'
vakus
  • 732
  • 1
  • 10
  • 24