NASM Forum > Other Discussion
Boot Loader Peculularity
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