Problem with bootloader

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
skapunky
Posts: 3
Joined: Tue May 13, 2008 1:50 am
Contact:

Problem with bootloader

Post by skapunky »

Hi, firstly sorry for my english. i'm spanish

I have a problem with my simple boot loader. I want that it are charged display "skaos", but when y simulated with vmware, see very rare strings :S.

This is the code, is compiled in fasm:

Code: Select all

        org 0x7C00  ; Dirección donde se encuentran las bios.
        use16       ; Usamos modo de 16 bits.

INFO    db "SKAOS"

INI:    MOV AH,00H          ;Configuramos modo video
        MOV AL,03h
        int 10h
        XOR AX,AX           ; AX = 0
        MOV DS,AX           ; DS = AX = 0

        MOV SI,INFO         ; Apuntamos a INFO
        MOV CX,5            ; Metemos en CX valor del string a cargar
VER:    MOV AH,0x0E         ; CARGAMOS 1 CARÃ
Visit my spanish project site SkaOs
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

I see you use the segment override [ES:SI] but you don't seem to set the value of ES - it may be that it just contains a junk value initially. You also never seem to terminate your VER loop.

You may like to look at using the instruction LODSB and also NULL terminating your string.

Cheers,
Adam
skapunky
Posts: 3
Joined: Tue May 13, 2008 1:50 am
Contact:

Post by skapunky »

Hi, thanks for your response.

I use instruction LODSB, but in vmware, i see the first character any.This is the code with lodsb:

Code: Select all

org 0x7C00  ; Dirección donde se encuentran las bios.
	use16	    ; Usamos modo de 16 bits.



INI:	XOR AX,AX	  ; AX = 0
	MOV DS,AX	    ; DS = AX = 0
	MOV SI,INFO	    ; Apuntamos a INFO
	CALL VER

FIN:	JMP FIN 	    ; Salto sobre si mismo

VER:	LODSB		    ; CARGAMOS 1 CARÃ
Visit my spanish project site SkaOs
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Ok, not much time at the moment, but here's what I use if it's any help:

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	PutString - print a string on the screen		;
;	takes - si: pointer to 0-terminated str	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PutString:
	mov 	ah,	0x0E	;	TeleType Function
	mov		bh,	0x00	;	Page 0
 	mov 	bl,	0x07	;	Grey on Black

	.nextchar:
	 	lodsb 
	 	or		al,	al
	 	jz		.str_end
	 	int		0x10 
 	jmp .nextchar

	.str_end:
ret
Cheers,
Adam
skapunky
Posts: 3
Joined: Tue May 13, 2008 1:50 am
Contact:

Post by skapunky »

Thanks, is perfect and the problem is solved, thanks thanks :D .

The code is:

Code: Select all

org 0x7C00  ; Dirección donde se encuentran las bios.
	use16	    ; Usamos modo de 16 bits.



INI:	XOR AX,AX	    ; AX = 0
	MOV DS,AX	    ; DS = AX = 0
	MOV SI,sk_INFO	    ; Apuntamos a INFO
VER:	MOV AH,0EH
	MOV BH,0	  ;pagina 0
	MOV BL,07H	  ;Color blanco sobre negro
NEXT:	lodsb
	OR AL,AL
	JZ FIN
	INT 10H
	JMP NEXT
FIN:

LOP:	JMP LOP 	    ; Salto sobre si mismo

sk_INFO    db 'Sistema operativo SkaOs',0


	times 510- ($-INI)  db 0
	dw 0xAA55
Thanks AJ :D
Visit my spanish project site SkaOs
svdmeer
Member
Member
Posts: 87
Joined: Tue May 06, 2008 9:32 am
Location: The Netherlands

Post by svdmeer »

This is my print-function:

Code: Select all

; **********************
; *** Function Print ***
; **********************
;
;  Usage: The string must follow directly after the call
;         to the function "Print".
;
;  For example:
;               call Print ; Call printfunction
;               db 'Put your message here...',0
;               nop     ; Program execution continues..
;
Print:       cld             ; Directionflag=0, for lodsb
             pop si          ; ds:si -> string
             push bp         ; BP on stack, buggy bioses
             lodsb           ; Char from string in AL
NextChar:    mov bx,7        ; Color 7 (ordinary light gray)
             mov ah,0x0e     ; Function 0x0e: Teletype output
             int 0x10        ; Call video-BIOS with interrupt 10h
             lodsb           ; Char from string in AL
             or al,al        ; Value 0 ?
             jnz NextChar    ; If not, print this char
             pop bp          ; Restore BP
             push si         ; Put the right value of IP on the stack
             ret             ; Return from function
Instead of pointing SI to the string when calling the function, I have the string directly after the function call in the code. The print-function increases the return-address, so execution of the code continues after the string.

POP SI in the beginning and PUSH SI are doing all the work for geting the address of the string and let de code continue. That are 2 bytes of code. MOV SI,<addr> is 3 bytes of code, so you save one byte. But if you are calling this function twice, you safe another 3 bytes, total 4 bytes. Three times, you save 7 bytes, and so on. I assume you'll call the print-function multiple times, otherwise it isn't efficient to use it as a function.

In a bootsector I take every change to save bytes, because a bootsector is VERY small to read the (beginning of) a file from a FAT12-file system, with support for both legacy int 13h functions and the int 13h extensions.

skapunky wrote:Thanks, is perfect and the problem is solved, thanks thanks :D .

The code is:

Code: Select all

org 0x7C00  ; Dirección donde se encuentran las bios.
	use16	    ; Usamos modo de 16 bits.



INI:	XOR AX,AX	    ; AX = 0
	MOV DS,AX	    ; DS = AX = 0
	MOV SI,sk_INFO	    ; Apuntamos a INFO
VER:	MOV AH,0EH
	MOV BH,0	  ;pagina 0
	MOV BL,07H	  ;Color blanco sobre negro
NEXT:	lodsb
	OR AL,AL
	JZ FIN
	INT 10H
	JMP NEXT
FIN:

LOP:	JMP LOP 	    ; Salto sobre si mismo

sk_INFO    db 'Sistema operativo SkaOs',0


	times 510- ($-INI)  db 0
	dw 0xAA55
Thanks AJ :D
I see you are not using a function call (I think you'll need a function when you like to display both a message and disk-errors).

You can improve your code this way:

Code: Select all

org 0x7C00  ; Dirección donde se encuentran las bios. 
use16       ; Usamos modo de 16 bits. 


INI:    XOR AX,AX       ; AX = 0 
        MOV DS,AX       ; DS = AX = 0 
        MOV SI,sk_INFO  ; Apuntamos a INFO 
        cld             ; just be sure.. 
        lodsb           ; read 1st character 
next:   MOV AH,0EH 
        MOV BX,07H      ; MOV BH,0 and MOV BL,07 in one instruction 
        INT 10H
        lodsb 
        OR AL,AL 
        jnz next 

LOP:    JMP LOP         ; Salto sobre si mismo 

sk_INFO db 'Sistema operativo SkaOs',0 

times 510- ($-INI)  db 0 
        dw 0xAA55
Using an extra LODSB, you can do it without that jump, and BL and BH can be initialized with one MOV BX,.. instruction. I add CLD just to be sure the direction flag is right (LODSB depends on it).

In my version I push BP on stack. 2 valuable bytes, but Ralph Browns interrupt list says some buggy bioses can destroy BP when scrolling the screen (maybe it can occur with those older BIOSes with a lage bunch of PCI-hardware strings so your first string will let the screen scroll). I use BP very often in the bootsector for addressing variabeles in memory with less code.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

svdmeer wrote:You can improve your code this way:
Using an extra LODSB, you can do it without that jump, and BL and BH can be initialized with one MOV BX,.. instruction. I add CLD just to be sure the direction flag is right (LODSB depends on it).
Of course, some more size improvement is possible. For one thing, if we use bx instead of ax to initialize ds, we can save one byte because we only need a mov bh instead of bx. Also, if you do not care for an extra blank to be printed at the end of the string, you can print the terminating zero, then compare. As for initializing ah and bx/bh, I'd do that outside the loop for speed optimization (int 10h shouldn't destroy any registers, except the mentioned bp bug on some old BIOSes). Doing a CLD should not be necessary I think in this case, but I'm not entirely sure all BIOSes leave it reset. So then the code becomes:

Code: Select all

        xor bx,bx
        mov ds,bx
        mov si,sk_info
        mov ah,0eh
        mov bh,7
        cld
next:   lodsb
        int 10h
        or al,al
        jnz next

lop:    jmp lop

sk_info db 'Sistema operativo SkaOs',0

JAL
Post Reply