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
.
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
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.