How to fix “os.asm:113: error: TIMES value -138 is negative” in assembly language

后端 未结 3 2014
挽巷
挽巷 2020-12-01 23:11

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

3条回答
  •  日久生厌
    2020-12-01 23:36

    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.

提交回复
热议问题