I\'m developing an operating system in assembly language. At a certain time i get this error from NASM:
os.asm:113: error: TIMES value -138 is negati
Since your line:
times 512 - ($ - $$) db 0
is meant to fill up the rest of the 512-byte chunk of memory with zeroes, it's likely that you have already exceeded that (by roughly 138 bytes). You'll probably need to just shorten your code (or make some of those strings a little less verbose) so it fits.
My advice would be to start with about_string, which seems way more than necessary. Removing the (rather self-serving)" 8 hours of intense work done by Alex~s Software. Many errors but solved and very successful." would be a good start as it would save 93 bytes. In addition, at the cost of a few extra bytes of code, you could remove the duplicate "Press any key to go back!" (with leading and trailing CRLF).
This could be done with something like:
about_string db '|About|',13,10,'Smile OS is a console based operating system in assembly language.'
any_key db 13,10,'Press any key to go back!',0
message_str db '|Message|',10,13,'Hello, World!',0
The about string could then be printed in exactly the same manner (because about_string has no terminating 0 hence will also print any_key) but the message string would change into a two-step operation:
mov si, message_str --> mov si, message_str
call print_string call print_string
mov si, any_key
call print_string
That will save about another 20 bytes, giving you a saving of about 113 of the 138 bytes.
Other than that, there appear to be a few minor things that could save very small amounts of space such as converting:
mov ah, 0x00
mov al, 0x03
into:
mov ax, 0x0003
or refactoring the key input into a function (this will also keep your stack balanced, something your current code does not appear to do, although I'm not actually sure that it's necessary - the documentation seems to suggest that ax is the only register affected, meaning you could probably remove the pushes and pops):
get_kbd: push bx
push cx
push dx
xor ax,ax
int 16h
je start
pop dx
pop cx
pop bx
ret
Of course, if you do all that and you still can't get below the threshold, there's nothing requiring you to put the string in the boot code area. You could just as easily store them on another area which the boot code loads in as the first step. That way, you take away all the strings from the boot code area, saving some 460-odd bytes (adding maybe twenty back for the code to load the string sectors) and therefore coming in well under the threshold.