NASM Forum > Other Discussion

Boot Loader Peculularity

(1/2) > >>

TightCoderEx:
In my effort to roll my own BIOS and OS  :-\ well at least the intention is there, I've come across a problem. Certain information is missing from the sites I visit, so what I'm doing is writing an informative phase to my boot loader. Initial prompt is as follows;

Loading BONES OS

Stack Pointer 0000:03E2

Not surprisingly BIOS stack is just below BPB (Bios Parameter Block) 0x400 to 0x501. This is the code that does this.


--- Code: --- [bits 16]

BOOT_BASE equ 0x7c00

org BOOT_BASE ; Bootstrap base

; ============================================================================================

start mov     ax, ss
        mov     bx, sp
       
        cli
        xor     ax, ax
        mov     ss, ax
        mov     ds, ax
        mov     es, ax
        mov     sp, BOOT_BASE
        sti
       
        push    bx
        push    ax
       
        mov     si, SignOn
        call    ShowS
       
        pop     ax
        push    si
        mov     di, Stack
        call    I2A_16
       
        pop     si
        pop     ax
        push    si
        add     di, 5
        call    I2A_16
       
        mov     si, Disp
        call    ShowS

        ; Wait for operator input before carrying on
               
.Again xor ax,  ax
inc al
int 0x16
jz .Again

int 0x19

; --------------------------------------------------------------------------------------------
; Display NULL termianted string teletype mode

; ENTRY: SI = Pointer to string

; LEAVE: SI = Pointer to next string if applicable. If stings are positioned properly
;      in data area, this could be called successively without modifying SI.
; ____________________________________________________________________________________________

         ShowS mov ah, 14
 
  .Next lodsb ; Get character from string
  or al,  al
  jz .Done
 
  int 0x10 ; Display character
  jmp .Next
 
  .Done ret ; BX = Pointer to next possible string

; ============================================================================================
; Converts unsigned integer to NULL terminated ASCII string

; ENTRY: AX = 16 bit value to be converted
; DX = Pointer to destination buffer (must be at least 5 bytes in length)

; LEAVE: AX = Pointer to first character of conversion
; DX = Unchanged and points to ASCII string padded with blanks.
; --------------------------------------------------------------------------------------------

I2A_16 push di ; Preserve base pointer
        add     di, 3                   ; Bump to end of display area
push dx
mov dx, ax

; It might be a better idea to check flag before changing, but in this case I'm
; going to assume all routines change to auto increment before completing.

std ; Auto decrement

; Cycle until DX is null, but should it be zero at least one '0' will be written.

.Next mov al, dl ; Get next byte
and al, 15 ; Strip high nibble
or al, '0' ; Make ASCII
cmp al, 58 ; and determine if greater than '9'
jb $ + 4 ; Branch if between '0' & '9'

add al, 7 ; Makes character 'A' - 'F'

stosb ; Write ASCII character to buffer
shr dx, 4 ; Shift next nibble into AL
jnz .Next ; and continue if not zero

cld ; Set default direction
pop dx ; Restore original contents
mov ax, di ; Copy pointer
inc ax ; and bump so there are no leading spaces
pop di ; Pointer with leading spaces
ret

; <> - <> - <> - <> - <> - <> - <> - <> - < > - <> - <> - <> - <> - <> - <> - <> - <> - <>- <>

  SignOn db 'Loading BONES OS', 13, 10, 13, 10, 0
  Disp          db      'Stack Pointer '
  Stack         db      '0000:0000', 13, 10, 0

times 510 - ($ - $$) db 90H

dw 0xAA55

--- End code ---

My alternate version, which should have worked, because it does on my DOS box invoked from command prompt, DEBUG and SYMDEB, but didn't when booting. Code in part;


--- Code: ---         mov     si, SignOn
        call    ShowS
       
        pop     ax
        push    si
        mov     di, Stack
        call    I2A_16
       
        pop     si
        pop     ax
        push    si
        add     di, 5
        call    I2A_16
       
        pop     si
        call    ShowS


--- End code ---

As you can see, identical except SI is derived from stack. Hoping somebody has an idea before I have to code a trace mechanism in to follow what's happening  >:(

Frank Kotler:

--- Code: --- start mov     ax, ss
        mov     bx, sp
       
        cli
        xor     ax, ax

--- End code ---

I don't doubt that ss was 0 before you put it there, but we don't really know this... If you're looking for some "standard" values for what BIOS hands us in any register but dl (boot drive), I don't think there is any...  I'm not sure I understand what the issue is, TightCoderEx. Feeling slow today...

Best,
Frank

TightCoderEx:
ES @ start is zero & SS is 0x3E2, so that is resolved no problem.

ShowS is designed to take SI as a pointer and when done SI points to the next location after the terminator being NULL. So at the first invocation of ShowS SI = 7C65 and when it's done 7C7A.

--- Code: ---   112 7C65 4C6F6164696E672042-       SignOn db 'Loading BONES OS', 13, 10, 13, 10, 0
   113 7C6E 4F4E4553204F530D0A-
   114 7C77 0D0A00             
   115 7C7A 537461636B20506F69-       Disp          db      'Stack Pointer '
   116 7C83 6E74657220         
   117 7C88 303030303A30303030-       Stack         db      '0000:0000', 13, 10, 0
   118 7C91 0D0A00             

--- End code ---

At lines 20 & 21 I save ES:SP and at lines 26 & 27 exchange ES with pointer to Disp = 7C7A.  That value being zero is converted correctly and then @ 31 - 33 in essence 7C7A is exchanged with 03E2 and then converted so my display in previous posting is 0000:03E2.  by the time we get to 37, contents of stack should be 7C7A, but it's not.  The string @ SignOn is displayed again, so somehow the contents of stack got changed to 7C65.


--- Code: ---    20 7C11 53                              push    bx
    21 7C12 50                              push    ax
    22                                         
    23 7C13 BE[6500]                        mov     si, SignOn
    24 7C16 E81F00                          call    ShowS
    25                                         
    26 7C19 58                              pop     ax
    27 7C1A 56                              push    si
    28 7C1B BF[8800]                        mov     di, Stack
    29 7C1E E82300                          call    I2A_16
    30                                         
    31 7C21 5E                              pop     si
    32 7C22 58                              pop     ax
    33 7C23 56                              push    si
    34 7C24 83C705                          add     di, 5
    35 7C27 E81A00                          call    I2A_16
    36                                         
    37 7C2A 5E                              pop     si
    38 7C2B E80A00                          call    ShowS

--- End code ---

The question is, how did the contents of the stack get changed to 7C65 when application was tested in DEBUG & SYSDEB it worked just fine.  Also when @ line 37 I directly address Disp mov si, Disp it also works fine.


As usual and has been the case for quite some time, work arounds are in order. My guess would be the BIOS encounters some sort of interrupt and trashes SP. Just thought somebody might have some quick insight. It is working, just not the way I wanted

Thanks for the heads up Frank, as one never knows if the question is stated clearly, if not made aware.

s_dubrovich:
    37 7C2A 5E                                 pop     si

This version works for me, indentical to your first version.  Tested as a real floppy disk boot sector on a pentium mmx laptop.  The output is:

Loading BONES OS

Stack Pointer 0000:0100

(I think you know your code overwrites the segment value with zero.)
(It should be SS:SP 0030:0100h for this machine.)
(I had to try your code, because I couldn't see the problem - there isn't one.  You must've made some other inadvertant error.)

hth,
Steve

Keith Kanios:

--- Quote from: TightCoderEx on January 07, 2013, 12:23:19 AM ---Stack Pointer 0000:03E2

--- End quote ---

Recommended reading: x86 Memory Map @ OSDev.org

TL;DR: Stay above 0000:0500 in Real Mode.


--- Quote from: TightCoderEx on January 07, 2013, 12:23:19 AM ---Hoping somebody has an idea before I have to code a trace mechanism in to follow what's happening  >:(

--- End quote ---

Use Bochs.

Navigation

[0] Message Index

[#] Next page

Go to full version