flat assembler
Message board for the users of flat assembler.

Index > OS Construction > trying to print a string in protected mode

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
retro



Joined: 12 Oct 2021
Posts: 47
retro 20 Aug 2022, 00:54
hi, it's been some days since i started to try to make my own os from scratch using only fasm.
however, i can't print a simple string in protected mode.
here's what i tried but failed miserably:
Code:
include 'boot.asm'

mov esi,str0
mov ebp,$b8000

print0:
mov al,[esi]
mov ah,$0f
cmp al,$00
je print1
inc esi
add ebp,2
jmp print0

print1:
ret

str0: db "test",$00    

and here's boot.asm:
Code:
org 0x7c00
KERNEL_LOCATION=$1000

mov [BOOT_DISK],dl

xor ax,ax
mov es,ax
mov ds,ax
mov bp,$8000
mov sp,bp

mov bx,KERNEL_LOCATION
mov dh,2

mov ah,$02
mov al,dh
mov ch,$00
mov dh,$00
mov cl,$02
mov dl,[BOOT_DISK]
int $13            ; no error management, do your homework!

mov ah,$00
mov al,$03
int $10    ; text mode

CODE_SEG=GDT_code-GDT_start
DATA_SEG=GDT_data-GDT_start

cli
lgdt [GDT_descriptor]
mov eax,cr0
or eax,1
mov cr0,eax
jmp CODE_SEG:start_protected_mode

jmp $

BOOT_DISK: db 0

GDT_start:
    GDT_null:
        dd $00
        dd $00

    GDT_code:
        dw $ffff
        dw $00
        db $00
        db 10011010b
        db 11001111b
        db $00

    GDT_data:
        dw $ffff
        dw $00
        db $00
        db 10010010b
        db 11001111b
        db $00

GDT_end:

GDT_descriptor:
    dw GDT_end-GDT_start-1
    dd GDT_start

use32
start_protected_mode:
    mov ax,DATA_SEG
    mov ds,ax
    mov ss,ax
    mov es,ax
    mov fs,ax
    mov gs,ax

    mov ebp,$90000 ; 32 bit stack base pointer
    mov esp,ebp

    jmp KERNEL_LOCATION

times 510-($-$$) db 0
dw $aa55    
Post 20 Aug 2022, 00:54
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 20 Aug 2022, 03:34
Code:
mov bp,$8000    
It is not necessary to set the top of the stack after the address of the boot sector. Depending on the BIOS implementation, this may overwrite the program. Or at least increase the stack size to 32 kb.

Code:
print1:
ret

...

mov ah,$00
mov al,$03
int $10    ; text mode    
To output text in the text mode of the video card, it is enough to copy a string with an extension of 1 byte to two (adding a color attribute) at the addresses 0x000B8000 - 0x000B8FFF.

Placing the protected mode switch code in the boot sector is a bad idea. If you need to fully configure the CPU to work in protected mode, then you will also need TSS, IDT, (PLM5, PLM4), PDE, PTB, a long code to check the capabilities of the CPU via CPUID and a bunch of other real code.

And you also don't have the A20 opening code. Via the system port
Code:
openA20:
in al, $92
or al, 00000010b
out $92, al

...

closeA20:
in al, 11111101b
and al, $0FD
out $92, al    
or by reconfiguring the i8042 (keyboard controller)
Code:
wait:
push cx
mov cx, $0FFFF
@@:
in al, $64
test al, 00000010b
loopnz @b
pop cx
retn

openA20:
call wait
mov al, $0D1
out $64, al
call wait
mov al, $0DF
out $60, al
call wait

...

closeA20:
call wait
mov al, $0D1
out $64, al
call wait
mov al, $0DD
out $60, al
call wait    
Post 20 Aug 2022, 03:34
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 20 Aug 2022, 06:26
Quote:
Code:
mov esi,str0
mov ebp,$b8000

print0:
mov al,[esi]
mov ah,$0f
cmp al,$00
je print1
mov [ebp],ax ; Forgot the write to memory command
inc esi
add ebp,2
jmp print0

print1:
ret

str0: db "test",$00    
Post 20 Aug 2022, 06:26
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 20 Aug 2022, 11:19
well, i still can't understand why it doesn't work. does the a20 and stuff code has something to do with that? if so, that'd be weird, 'cos i already tried to print a single character to the screen and also tried to print the same character filling the screen, and both worked.
Post 20 Aug 2022, 11:19
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 20 Aug 2022, 18:30
one thing that i noticed is that if i remove the cmp and je, i get a screen with random characters written at the middle of the screen on the color i want. i wonder why this happens instead of writing the same string over and over...
Post 20 Aug 2022, 18:30
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 20 Aug 2022, 18:49
Maybe because mov esi, str0 inserts the value $00007E19 (org + offset str0) into esi
Post 20 Aug 2022, 18:49
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 20 Aug 2022, 19:29
what registers should i use, then? i have tried several registers but obviously push & pop'd their values, even so, it doesn't seem to work at all...
Post 20 Aug 2022, 19:29
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 20 Aug 2022, 20:39
Code:
include 'boot.asm'
@@:
mov esi,str0 - @b + KERNEL_LOCATION
mov ebp,$b8000

print0:
mov al,[esi]
mov ah,$0f
cmp al,$00
je print1
mov [ebp],ax
inc esi
add ebp,2
jmp print0

print1:
ret

str0: db "test",$00    
You need to properly organize the formation of binary blocks (boot and kernel). Each block should have its own org ($00007C00 and $00001000, respectively). Or you will have to manually recalculate the addresses for labels in RAM.
Code:
file 'boot.bin' ; include 'boot.asm'
org $00001000
mov esi,str0
mov ebp,$b8000

print0:
mov al,[esi]
mov ah,$0f
cmp al,$00
je print1
mov [ebp],ax
inc esi
add ebp,2
jmp print0

print1:
ret

str0: db "test",$00    


Last edited by macomics on 20 Aug 2022, 20:58; edited 1 time in total
Post 20 Aug 2022, 20:39
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 794
Location: Adelaide
sinsi 20 Aug 2022, 20:54
Code:
include 'boot.asm'
org KERNEL_LOCATION
    
Post 20 Aug 2022, 20:54
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 20 Aug 2022, 20:58
oh sh**, that was what i was missing... thanks for the explanation though, i gotta read more about this kinda stuff!
so now, when i put "org $1000" at the beginning of the file, it has the same effect as the modification you did... so if i wanted to make this "pseudo-kernel" load another file (the os file or something for example), would i need to define the org of it?
Post 20 Aug 2022, 20:58
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 20 Aug 2022, 20:59
yes
Post 20 Aug 2022, 20:59
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 21 Aug 2022, 14:15
so now i was thinking of using the boot.asm to load up floppy disks, however, even after researching so much, i still couldn't manage to read the floppy drive using int $13.
maybe i should make a new post about it, or just read the same code 9999999999999 times.
Post 21 Aug 2022, 14:15
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 21 Aug 2022, 14:46
nevermind, i fixed it! so now the boot loader can read text from floppies, however, it can't execute binaries, which is what i wanna do now.
Post 21 Aug 2022, 14:46
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 21 Aug 2022, 18:36
deleted


Last edited by macomics on 13 Nov 2024, 20:39; edited 1 time in total
Post 21 Aug 2022, 18:36
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 21 Aug 2022, 20:32
thanks!
Post 21 Aug 2022, 20:32
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 21 Aug 2022, 20:52
and now i'm trying to write the execution code, what the code tries to do is that it first sets bx to an address where it can load the data, and the value in this address goes in al, and the value in al goes to the address of bp, which has the address where it can write the executable code. and then both bx and bp registers get incremented, until bx reaches $8000, which is the limit address.
however, it looks like it's not working. my other binary file i'm using to test, which just prints an "a" to the screen, doesn't seem to get executed at all.
Post 21 Aug 2022, 20:52
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 21 Aug 2022, 21:14
These boot sectors (there are two variants of them) load a file with a length of almost all conventional memory (640 kb - IDT - BIOS_vars - ExtBIOS_vars - STACK_SIZE = ~607 kb).

retro wrote:
and now i'm trying to write the execution code, what the code tries to do is that it first sets bx to an address where it can load the data, and the value in this address goes in al, and the value in al goes to the address of bp, which has the address where it can write the executable code. and then both bx and bp registers get incremented, until bx reaches $8000, which is the limit address.
however, it looks like it's not working. my other binary file i'm using to test, which just prints an "a" to the screen, doesn't seem to get executed at all.
The bootstrap address is determined by the SAFETY_OFFSET value set in the file ./FAT12_1M/FILES/BOOT.ASH

When calling the loaded program, the transition is made to the segment (SAFETY_OFFSET + 15 ) / 16.
For this, I printed out the IP and CS in the example. The es and ds registers are not defined. you need to determine their values yourself.


Last edited by macomics on 13 Nov 2024, 20:42; edited 1 time in total
Post 21 Aug 2022, 21:14
View user's profile Send private message Reply with quote
retro



Joined: 12 Oct 2021
Posts: 47
retro 21 Aug 2022, 21:43
what do you mean? i need to set the values of these 2 registers in order to make my test program get executed?
Post 21 Aug 2022, 21:43
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 21 Aug 2022, 21:47
retro wrote:
what do you mean? i need to set the values of these 2 registers in order to make my test program get executed?
Yes. In the example, their values are defined as follows
Code:
kb              fix *1024
Mb              fix *1048576
include "BOOT.ASH"
org SAFETY_OFFSET and 15
; CS:IP = 0100:0000
        push    cs ; CS = 0100 <- Save the CS value for printing.
        call    @f ; Save the IP value for printing.

@@: ; IP = 0004
        push    cs
        pop     ds ; ds = cs = 0100
        push    ds
        pop     es ; es = ds = cs = 0100
        mov     si, str0
        call    WriteTTY
        mov     si, IP_val
        call    WriteTTY
        pop     ax
        call    WriteWord
        mov     si, CS_val
        call    WriteTTY
        pop     ax
        call    WriteWord

@@:
        hlt
        jmp     @b

WriteWord:
        push    ax
        mov     al, ah
        call    WriteByte
        pop     ax

WriteByte:
        push    ax
        shr     ax, 4
        call    WriteHex
        pop     ax

WriteHex:
        and     al, 15
        cmp     al, 10
        sbb     al, 105
        das
        mov     ah, 14
        int     16
        retn

@@:
        mov     ah, 14
        push    si
        int     16
        pop     si

WriteTTY:
        lods    byte [si]
        test    al, al
        jnz     @b
        retn

str0            db 'Test string!', 0
IP_val          db 13, 10, 'IP = ', 0
CS_val          db '; CS = ', 0

any_data db 512 kb dup (0)    
Post 21 Aug 2022, 21:47
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 21 Aug 2022, 22:16
Here is the approximate memory allocation of the first MB at the time of loading TEST.APP
Code:
$00000 - $003FF ; Real IDT (1 kb)
$00400 - $005FF ; BIOS_vars (512 bytes)
$00600 - $00FFF ; empty (2,5 kb)
$01000 - $811FF ; TEST.APP (512,5 kb)
$81200 - $97FFF ; empty (91,5 kb)
$98000 - $9FBFF ; stack segment (31 kb)
$9FC00 - $9FFFF ; ExtBIOS_vars if exists (1 - 4 kb)
$A0000 - $AFFFF ; Video segment (64 kb)
$B0000 - $B7FFF ; Mono text segment (32 kb)
$B8000 - $BFFFF ; Color text segment (32 kb)
$C0000 - $CFFFF ; Video BIOS (64 kb)
$D0000 - $EFFFF ; Other ROM or Extended memory (128 kb)
$F0000 - $FFFFF ; Main BIOS (64 kb)    


Last edited by macomics on 21 Aug 2022, 23:16; edited 2 times in total
Post 21 Aug 2022, 22:16
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.