I created a simple "Master Boot Record" for my future toy OS. The first sector (MBR) loads perfectly to memory address 0x7C00. At first I didn't know why, but I was finally able to use pointer to other memory addresses by adding these few line at the start of my nasm code:
Code: Select all
CLI
MOV AX,CS ; Copy code segment
MOV DS,AX ; Make DS correct
MOV ES,AX ; Make ES correct
MOV SS,AX ; Make SS correct
MOV BP,0x7C00
MOV SP,0x7C00 ; SETUP A STACK
STI
Here is my full code:
Code: Select all
;********************************************************************;
;* START OF CODE *;
;********************************************************************;
%define SIZE 512 ; MBR sector size (512 bytes)
%define BASE 0x7C00 ; Address at which BIOS will load MBR
%define DEST 0x0600 ; Address at which MBR should be copied
;********************************************************************;
;* NASM settings *;
;********************************************************************;
[BITS 16] ; Enable 16-bit real mode
[ORG BASE] ; Set the base address for MBR
;********************************************************************;
;* Setup segment registers *;
;********************************************************************;
CLI
MOV AX,CS ; Copy code segment
MOV DS,AX ; Make DS correct
MOV ES,AX ; Make ES correct
MOV SS,AX ; Make SS correct
MOV BP,0x7C00
MOV SP,0x7C00 ; SETUP A STACK
STI ;IT WAS ORIGINALLY PUBLISHED ON HTTPS://WWW.APRIORIT.COM/
;********************************************************************;
;* Prepare registers *;
;********************************************************************;
MOV BX,Prepare
CALL print_string ; function that prints a string whose pointer is loaded in BX
XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV SS,AX
MOV SP,BASE
;********************************************************************;
;* Copy MBR to DEST and jump there *;
;********************************************************************;
MOV BX,Copy
CALL print_string ; function that prints a string whose pointer is loaded in BX
MOV SI,BASE
MOV DI,DEST
MOV CX,SIZE
CLD
REP MOVSB
JMP DEST + SKIP ; When you ask to jump somewhere it will jump in absolute address
; For instance JMP 0x05 will jump to memory address 0x05 instead
; of 0x7C05
SKIP: EQU ($ - $$) ; Go here in copied code
MOV BX,Loading
CALL print_string ; function that prints a string whose pointer is loaded in BX
;Extended Read
MOV AH, 0x42
MOV AL, 3
;MOV DL,
MOV BX, 0
MOV DS, BX
MOV SI, DAP
MOV BX, 0x7C00
INT 0x13
JMP 0x7600 + 0x7C00
DAP:
DAP_SIZE: DB 0x10
UNUSED: DB 0x00
SECTOR_COUNT: DW 3 ; int 13 resets this to # of blocks actually read/written
SEGMENT_OFFSET: DD 0x7C00 ; memory buffer destination address (0:7c00)
LBA: DQ 2048 ; put the lba to read in this spot
%include "../../inc/chapter3/print_string.inc.asm" ; print string function is in an external file
Prepare: DB "Prepare registers.",10,13,0
Copy: DB "Copy MBR to DEST and jump there.",10,13,0
Loading: DB "Loading the partition bootsector.",10,13,0
TIMES 446-($-$$) DB 0
;********************************************************************;
;* END OF CODE *;
;********************************************************************;
Note that on the Bochs Emulator and on Oracle Virtualbox the old MBR is overwritten and there is no endless loop. What should I do to make VMWare Player copy the partition's first sector to memory 0x7C00.
Thanks in advance.