I am creating a bootloader in nasm, in order to create my own operating system in 64 bits in c++. I test my bootloader with Qemu and it works perfectly (it enters protected mode, enters long mode, can return to real mode and then return to long mode), but when I test it with Oracle VM VirtualBox it suddenly crashes in an arbitrary moment, usually in a loop, and I don't know why. And when I test it with my computer (I burn the .iso on a DVD), it enters protected mode and then it gets to write only one message (I have made it write the state of the registers) before the computer restarts. This is the code of my bootloader (The rest of the code is in c++ and has nothing to do with this problem):
bootloader1.asm:
;The first sector of the bootloader has to load the next 127 sectors,
;so it leaves the first 64 KiB of the disc from 0x7c00 to 0x17c00
%macro R_PRINT 1
push si
mov si,%%string
call real_print
pop si
jmp %%jump
%%string: db %1,0
%%jump:
%endmacro
%macro R_ENDL 0
call real_endl
%endmacro
%macro R_PAUSE 0
push cx
mov cx,4000;0
%%loop:
push cx
mov cx,10000
%%loop2:
loop %%loop2
pop cx
loop %%loop
pop cx
%endmacro
%macro P_PRINT 1
push esi
mov esi,%%string
call protected_print
pop esi
jmp %%jump
%%string: db %1,0
%%jump:
%endmacro
%macro P_ENDL 0
call protected_endl
%endmacro
%macro P_PAUSE 0
push ecx
mov ecx,40000000;0
%%loop:
loop %%loop
pop ecx
%endmacro
%macro P_MESSAGE 1
P_PRINT %1
P_ENDL
P_PAUSE
%endmacro
%macro P_DUMP 0
pushad
push dword %%next
call protected_dump
add esp,4
popad
P_PAUSE
%%next:
%endmacro
BITS 16
ORG 0x7c00 ; Loaded into memory at 0x7C00
cli
; set cs to 0
jmp 0x0000:start
start:
mov ax,0
mov ds,ax
mov ax,REAL_MODE_STACK_SEGMENT
mov ss,ax
mov sp,REAL_MODE_STACK_BASE
; Setting VGA text mode
mov ax,2 ; 80x25
int 0x10
; Disabling the cursor
mov ah,1
mov ch,0x3f
int 0x10
R_PRINT "-The first 512 bytes of the boot-loader have been successfully loaded"
R_ENDL
R_PAUSE
mov si,0 ; The sectors aren't read with the BIOS extension
push si
; Check if I can read from disc with int 13h ah=42h
mov ah,0x41
mov bx,0x55AA
int 0x13
jc .extension_not_supported
cmp ah,1
je .extension_not_supported
and cx,1
cmp cx,0
jne .extension_supported
.extension_not_supported:
; Resetting disc
mov ah,0x00
int 0x13
; Reading Bytes from disc
mov ax,0x7e0
mov es,ax
mov bx,0
mov ah,0x2
mov al,127
mov cx,2
mov dh,0
int 0x13
jc .reading_error
cmp al,127
jne .reading_error
jmp .successful_reading
.extension_supported:
; Resetting disc
mov ah,0x00
int 0x13
pop si
mov si,1 ; The sectors are read with the BIOS extension
push si
; Reading Bytes from disc with BIOS extension
mov si,disc_read_information
mov ah,0x42
int 0x13
jnc .successful_reading
.reading_error:
R_PRINT "-Error reading from disc: ah=0x"
mov bl,ah
call real_print_hex8
R_PRINT " al=0x"
mov bl,al
call real_print_hex8
pop si
cmp si,1
je .error_extended_function
R_PRINT " (with: int 13h;ah=02h)"
jmp $
.error_extended_function:
R_PRINT " (with: int 13h;ah=42h)"
jmp $
.successful_reading:
; dl contains the drive number, since the beggining of the execution
mov [DRIVE_NUMBER],dl
jmp sector2
disc_read_information:
db 0x10
db 0
dw 127 ; 0x200 or 0x800?(0x200 in qemu)-sized CD sectors
dw 0 ; offset of address
dw 0x7e0 ; segment of address
dq 1 ; From sector number 1
; Input:
; cl: byte to write (lower 4 bits).
real_print_hex4:
pusha
push es
and cl,0x0f;
cmp cl,10
jae .hex
add cl,'0'
jmp .end_if
.hex:
add cl,'a'-10
.end_if:
mov ax,0xb800
mov es,ax
mov di,[cursor]
shl di,1
mov [es:di],cl
mov byte [es:di+1],0x0F
add di,2
shr di,1
mov [cursor],di
pop es
popa
ret
; Input:
; bl: byte to write
real_print_hex8:
push cx
mov cl,bl
shr cl,4
call real_print_hex4
mov cl,bl
call real_print_hex4
pop cx
ret
; Input:
; si: Pointer to null-terminated string
real_print:
pusha
push es
mov ax,0xb800
mov es,ax
mov di,[cursor]
shl di,1
.loop:
mov al,[si]
cmp al,0
je .endloop
mov [es:di],al
mov byte [es:di+1],0x0F
add di,2
inc si
jmp .loop
.endloop:
shr di,1
mov [cursor],di
pop es
popa
ret
real_endl:
pusha
mov ax,[cursor]
mov bl,80 ; Characters per line
div bl
inc al
mul bl
mov [cursor],ax
popa
ret
cursor: dw 0
times 510-($-$$) db 0x00 ; Fill bootloader to 512-bytes
dw 0xAA55 ; Magic word signature
%include "bootloader2.asm"
%include "bootloader3.asm"
%include "bootloader4.asm"
bootloader2.asm:
BITS 16
; dx: address to jump in 32 bit protected mode
real_mode_to_protected_mode:
mov si,[address_of_global_descriptor_table]
lgdt [si]
mov eax,cr0
or eax,1
mov cr0,eax
jmp CODE_SEGMENT32:.protected_mode
BITS 32
.protected_mode:
mov ax,DATA_SEGMENT32
mov ss,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
jmp dx
gdt_start32:
dq 0x0
gdt_code32:
dw 0xFFFF
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data32:
dw 0xFFFF
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end32:
gdt_pointer32:
dw gdt_end32-gdt_start32-1
dd gdt_start32
CODE_SEGMENT32 equ gdt_code32-gdt_start32
DATA_SEGMENT32 equ gdt_data32-gdt_start32
;---------------------------------------------------------------------
;
; |--this doesn't check if the CPU supports 64 bit mode [!]
; | and also doesn't check other important things
; V
BITS 32
; qword [address_to_jump_after_changing_the_mode]: address to jump in 64 bit long mode
protected_mode_to_long_mode:
; Disable paging, assuming that we are in a see-through. <-(?)
mov eax,cr0 ; Read CR0.
and eax,7FFFFFFFh; Set PE=0
mov cr0,eax ; Write CR0.
mov eax, cr4
or eax, 1<<5
mov cr4, eax
mov esi,[address_of_PML4T]; address of the PML4T
mov cr3,esi
; setting the LM-bit
mov ecx,0xC0000080 ; Set the C-register to 0xC0000080, which is the EFER MSR number.
rdmsr ; Read from the model-specific register.
or eax,1<<8 ; Set the LM-bit which is the 9th bit (bit 8).
wrmsr
; Enabling paging
mov eax, cr0 ; Read CR0.
or eax, 1 << 31 ; Set PE=1.
mov cr0, eax ; Write CR0.
mov eax,[address_of_global_descriptor_table]
lgdt [eax] ; Load the 64-bit global descriptor table.
jmp CODE_SEGMENT64:.long_mode ; Set the code segment and enter 64-bit long mode.
BITS 64
.long_mode:
mov rsp,[LONG_MODE_STACK_POINTER_SAVED]
jmp [address_to_jump_after_changing_the_mode]
gdt_start64: ; Global Descriptor Table (64-bit).
dw 0xFFFF ; Limit (low). <- The null descriptor.
dw 0 ; Base (low).
db 0 ; Base (middle)
db 0 ; Access.
db 1 ; Granularity.
db 0 ; Base (high).
gdt_code64: ; The code descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 10011010b ; Access (exec/read).
db 10101111b ; Granularity, 64 bits flag, limit19:16.
db 0 ; Base (high).
gdt_data64: ; The data descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 10010010b ; Access (read/write).
db 00000000b ; Granularity.
db 0 ; Base (high).
gdt_end64:
gdt_pointer64: ; The GDT-pointer.
dw gdt_end64 - gdt_start64 - 1 ; Limit.
dq gdt_start64 ; Base.
CODE_SEGMENT64 equ gdt_code64-gdt_start64
DATA_SEGMENT64 equ gdt_data64-gdt_start64
;---------------------------------------------------------------------
BITS 64
; dword [address_to_jump_after_changing_the_mode]: address to jump in 32 bit protected mode
long_mode_to_protected_mode:
mov [LONG_MODE_STACK_POINTER_SAVED],rsp
;returning to compatibility mode
push CODE_SEGMENT32
mov rcx,0
mov ecx,.long_mode_to_protected_mode_jump
push rcx
ret
BITS 32
.long_mode_to_protected_mode_jump:
mov ax,DATA_SEGMENT32
mov ss,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
; Disable Paging to get out of Long Mode
mov eax,cr0 ; Read CR0.
and eax,7fffffffh ; Set PE=0.
mov cr0,eax ; Write CR0.
; <---------------------------- VM VirtualBox suddenly changed to 16 bit protected mode after disabling paging,
; and fails in lgdt[gdt_pointer32]
; Deactivate Long Mode
mov ecx,0c0000080h ; EFER MSR number.
rdmsr ; Read EFER.
and eax,0xfffffeff ; Set LME=0.
wrmsr ; Write EFER.
jmp dword [address_to_jump_after_changing_the_mode]
gdt_start16:
dq 0x0
gdt_code16:
dw 0xFFFF
dw 0x0
db 0x0
db 10011010b
db 00001111b
db 0x0
gdt_data16:
dw 0xFFFF
dw 0x0
db 0x0
db 10010010b
db 00001111b
db 0x0
gdt_end16:
gdt_pointer16:
dw gdt_end16-gdt_start16-1
dd gdt_start16
CODE_SEGMENT16 equ gdt_code16-gdt_start16
DATA_SEGMENT16 equ gdt_data16-gdt_start16
BITS 32
; dx: address to jump in real mode
protected_mode_to_real_mode:
mov eax,cr0
and eax,0x7fffffff
mov cr0,eax
mov eax,0
mov cr3,eax
mov eax,[address_of_global_descriptor_table]
lgdt [eax]
jmp CODE_SEGMENT16:.entry_16bits ; Enters 16 bit protected mode
BITS 16
.entry_16bits:
mov ax,DATA_SEGMENT16
mov ds,ax
mov ss,ax
mov es,ax
mov fs,ax
mov gs,ax
lidt [BIOS_REAL_MODE_IVT]
mov eax,cr0
and eax,0xfffffffe
mov cr0,eax
jmp 0x0000:.entry_16bits2 ; Enters real mode
.entry_16bits2:
mov ax,0
mov ds,ax
mov ax,REAL_MODE_STACK_SEGMENT
mov ss,ax
mov bp,REAL_MODE_STACK_BASE
mov sp,bp
jmp dx
;---- Reset the CPU
BITS 32
mov al,0xfe ; get shutdown command
out 0x64,al ; send command to shutdown CPU
hlt
;----
; Create PML4T table from edi with the first 64 MiB
create_PML4T_table_64MiB:
P_DUMP;-----------------------------------------------------------------
pusha
P_DUMP;-----------------------------------------------------------------
cld ; clear direction flag, so "rep stosd" increments edi
P_DUMP;-----------------------------------------------------------------
;PT's: (Size: 128 KiB = 0x20000 Bytes, 0x20 tables)
mov ebx,3
mov esi,edi
mov ecx,0x4000
P_DUMP;-----------------------------------------------------------------
.SetPT:
mov [edi],ebx
mov dword [edi+4],0
add ebx,0x1000
add edi,8
loop .SetPT
P_DUMP;-----------------------------------------------------------------
;PDT: (Size: 0x1000 Bytes, 1 table)
mov ebx,esi ; Address of PT's
add ebx,3
mov esi,edi
mov ecx,0x20
.SetPDT:
mov [edi],ebx
mov dword [edi+4],0
add ebx,0x1000
add edi,8
loop .SetPDT
P_DUMP;-----------------------------------------------------------------
mov eax,0
mov ecx,(0x200-0x20)*2
rep stosd
P_DUMP;-----------------------------------------------------------------
;PDPT: (Size: 0x1000 Bytes, 1 table)
mov ebx,esi ; Address of PDT
add ebx,3
mov esi,edi
P_DUMP;-----------------------------------------------------------------
mov [edi],ebx
mov dword [edi+4],0
add edi,8
P_DUMP;-----------------------------------------------------------------
mov eax,0
mov ecx,(0x200-1)*2
rep stosd
P_DUMP;-----------------------------------------------------------------
;PML4T: (Size: 0x1000 Bytes, 1 table)
mov ebx,esi ; Address of PDPT
add ebx,3
mov esi,edi
P_DUMP;-----------------------------------------------------------------
mov [edi],ebx
mov dword [edi+4],0
add edi,8
P_DUMP;-----------------------------------------------------------------
mov eax,0
mov ecx,(0x200-1)*2
rep stosd
P_DUMP;-----------------------------------------------------------------
mov dword [PML4T_64MiB_ADDRESS+4],0
mov [PML4T_64MiB_ADDRESS],esi
P_DUMP;-----------------------------------------------------------------
popa
P_DUMP;-----------------------------------------------------------------
ret
; ----------------------------------------
bootloader3.asm:
%macro REAL_MODE_TO_PROTECTED_MODE 2
mov word [address_of_global_descriptor_table],%2
mov dx,%1
jmp real_mode_to_protected_mode
%endmacro
%macro PROTECTED_MODE_TO_REAL_MODE 2
mov dword [address_of_global_descriptor_table],%2
mov dx,%1
jmp protected_mode_to_real_mode
%endmacro
%macro PROTECTED_MODE_TO_LONG_MODE 3
mov dword [address_of_PML4T],%3
mov dword [address_of_global_descriptor_table],%2
mov dword [address_to_jump_after_changing_the_mode+4],0
mov dword [address_to_jump_after_changing_the_mode],%1
jmp protected_mode_to_long_mode
%endmacro
%macro LONG_MODE_TO_PROTECTED_MODE 1
mov dword [address_to_jump_after_changing_the_mode],%1
jmp long_mode_to_protected_mode
%endmacro
BITS 16
real_mode_interruption_from_long_mode:
mov al,[INTERRUPT_NUMBER]
mov [.intnumbyte],al
; Loading registers that could be parameters
mov ax,[SAVED_RAX]
mov bx,[SAVED_RBX]
mov cx,[SAVED_RCX]
mov dx,[SAVED_RDX]
mov si,[SAVED_RSI]
mov di,[SAVED_RDI]
mov es,[SAVED_ES]
db 0xcd
.intnumbyte:
db 0
; Saving the registers that could be outputs of the interruption
mov [SAVED_AX],ax
mov [SAVED_BX],bx
mov [SAVED_CX],cx
mov [SAVED_DX],dx
mov [SAVED_SI],si
mov [SAVED_DI],di
mov [SAVED_ES],es
ret
; Input:
; eax: Address to use. It has to be in the first MiB
; ebx: Maximum address plus one( i.e.: [ ax , bx ) ).
; It has to be in the first MiB, and within the same segment as eax (that ebx-eax<=0xfff0 to be sure), and ebx-eax>=24.
; Output:
; [SAVED_AX]: Number of entries read
; [SAVED_BX]: 1 if an error occurred, otherwise 0.
get_memory_map:
; Point es:di at the destination address
mov eax,dword [SAVED_RAX]
mov di,ax
and di,0xf
shr eax,4
mov es,ax
; Store the value limit of di in [SAVED_SI]
mov ebx,dword [SAVED_RBX]
sub ebx,dword [SAVED_RAX]
add bx,di
mov [SAVED_SI],bx
; First call --------------------------------------------------------
mov ebx,0 ; It has to be 0 for the first call
mov word [es:di+20],1
mov word [es:di+22],0
mov eax,0xE820 ; Number of function (the upper 16-bits of eax have to be 0)
mov edx,0x534D4150 ; Magic number
mov ecx,24 ; Required
int 0x15
jc .error
cmp eax,0x534D4150
jne .error
add di,24
cmp ebx,0
je .only_one_entry
; -------------------------------------------------------------------
; Subsequent calls --------------------------------------------------
.loop1:
; Testing if the limit is reached
mov si,[SAVED_SI]
mov ax,di
add ax,24
cmp ax,si
ja .exit_loop
mov word [es:di+20],1
mov word [es:di+22],0
mov eax,0xE820 ; Number of function (the upper 16-bits of eax have to be 0)
mov edx,0x534D4150 ; Magic number
mov ecx,24 ; Required
int 0x15
jc .exit_loop
cmp ebx,0
je .exit_loop
add di,24
jmp .loop1
; -------------------------------------------------------------------
.exit_loop:
add di,24
.only_one_entry:
; Calculating number of entries read
mov eax,dword [SAVED_RAX]
and ax,0xf
sub di,ax
mov ax,di
mov dx,0
mov cx,24
div cx
mov [SAVED_AX],ax
mov word [SAVED_BX],0
ret
.error:
mov word [SAVED_BX],1
ret
BITS 64
call_real_mode_function_cpp:
LONG_MODE_TO_PROTECTED_MODE .pmode
BITS 32
.pmode:
PROTECTED_MODE_TO_REAL_MODE .rmode,gdt_pointer16
BITS 16
.rmode:
call [REAL_MODE_FUNCTION_TO_CALL]
REAL_MODE_TO_PROTECTED_MODE .pmode2,gdt_pointer32
BITS 32
.pmode2:
mov eax,[address_of_PML4T]
PROTECTED_MODE_TO_LONG_MODE .lmode,gdt_pointer64,eax
BITS 64
.lmode:
ret
BITS 64
real_mode_from_long_mode_test:
LONG_MODE_TO_PROTECTED_MODE .pmode
BITS 32
.pmode:
P_PRINT "-Successfully returned to 32-bit protected mode"
P_ENDL
P_PAUSE
PROTECTED_MODE_TO_REAL_MODE .rmode,gdt_pointer16
BITS 16
.rmode:
R_PRINT "-Successfully returned to real mode"
R_ENDL
R_PAUSE
REAL_MODE_TO_PROTECTED_MODE .pmode2,gdt_pointer32
BITS 32
.pmode2:
mov eax,[address_of_PML4T]
PROTECTED_MODE_TO_LONG_MODE .lmode,gdt_pointer64,eax
BITS 64
.lmode:
ret
bootloader4.asm:
; Real mode stack: [0x71000 , 0x80000)
REAL_MODE_STACK_SEGMENT equ 0x7100
REAL_MODE_STACK_BASE equ 0xF000
; Long mode bootloader stack: [0x69000 , 0x71000)
LONG_MODE_BOOTLOADER_STACK_BASE equ 0x71000
BITS 16
sector2:
R_PRINT "-The boot-loader has been completely loaded"
R_ENDL
R_PAUSE
; Enable A20 bit
mov ax,0x2401
int 0x15
jnc .noerror
R_PRINT "-Error: Unable to enable the A20 bit by using the BIOS function int 15h;ax=2401h"
jmp $
.noerror:
REAL_MODE_TO_PROTECTED_MODE boot32,gdt_pointer32
BITS 32
boot32:
mov esp,LONG_MODE_BOOTLOADER_STACK_BASE
P_DUMP
mov eax,0x12345678
P_DUMP
mov ebx,0x23456789
mov ecx,0x34567890
mov edx,0x09876543
mov esi,0x98765432
mov edi,0x87654321
mov ebp,0x01020304
P_DUMP
P_PRINT "-32-bit protected mode entered"
P_DUMP
P_ENDL
P_DUMP
P_PAUSE
P_DUMP
mov edi,0x18000
P_DUMP
call create_PML4T_table_64MiB
P_DUMP
P_PRINT "-A PML4T that maps the first 64 MiB has been created"
P_DUMP
P_ENDL
P_DUMP
P_PAUSE
P_DUMP
P_ENDL
P_DUMP
mov eax,[PML4T_64MiB_ADDRESS]
PROTECTED_MODE_TO_LONG_MODE boot64,gdt_pointer64,eax
BITS 64
boot64:
call entrypoint
jmp $
%macro LMF 2
cmp rax,%1
jne %%next
call %2
jmp .end
%%next:
%endmacro
%macro RMF 2
cmp rax,%1
jne %%next
mov word [REAL_MODE_FUNCTION_TO_CALL],%2
call call_real_mode_function_cpp
jmp .end
%%next:
%endmacro
call_assembly_function_from_cpp:
push rbp
mov rax,[ASSEMBLY_FUNCTION_NUMBER]
RMF 0,real_mode_interruption_from_long_mode
RMF 1,get_memory_map
LMF 2,real_mode_from_long_mode_test
.end:
pop rbp
ret
BITS 32
; Input:
; esi: Pointer to null-terminated string
protected_print:
pushad
mov ebx,0xb8000
mov edi,0
mov di,[cursor]
shl edi,1
.loop:
mov al,[esi]
cmp al,0
je .endloop
mov [ebx+edi],al
mov byte [ebx+edi+1],0x0F
add edi,2
inc esi
jmp .loop
.endloop:
shr edi,1
mov [cursor],di
popad
ret
protected_endl:
pushad
mov ax,[cursor]
mov bl,80 ; Characters per line
div bl
inc al
mul bl
mov [cursor],ax
popad
ret
; Input:
; cl: 4 bits to write (lower 4 bits).
protected_print_hex4:
pushad
and cl,0x0f;
cmp cl,10
jae .hex
add cl,'0'
jmp .end_if
.hex:
add cl,'a'-10
.end_if:
mov ebx,0xb8000
mov edi,0
mov di,[cursor]
shl edi,1
mov [ebx+edi],cl
mov byte [ebx+edi+1],0x0F
add edi,2
shr edi,1
mov [cursor],di
popad
ret
; Input:
; al: 8-bit value to write
protected_print_hex8:
pushad
mov cl,al
shr cl,4
call protected_print_hex4
mov cl,al
call protected_print_hex4
popad
ret
; Input:
; eax: 32-bit value to write
protected_print_hex32:
pushad
mov ebx,eax
mov ecx,eax
shr ebx,16
mov al,bh
call protected_print_hex8
mov al,bl
call protected_print_hex8
mov al,ch
call protected_print_hex8
mov al,cl
call protected_print_hex8
popad
ret
; Input:
; the registers put into stack with pushad and the next instruction's address put into stack
protected_dump:
mov si,[cursor]
mov ax,80*22
mov [cursor],ax
P_PRINT "Dump number 0x"
mov eax,[dump_number]
call protected_print_hex32
inc eax
mov [dump_number],eax
P_ENDL
P_PRINT "eax=0x"
mov eax,[esp+4*9]
call protected_print_hex32
P_PRINT " ebx=0x"
mov eax,[esp+4*6]
call protected_print_hex32
P_PRINT " ecx=0x"
mov eax,[esp+4*8]
call protected_print_hex32
P_PRINT " edx=0x"
mov eax,[esp+4*7]
call protected_print_hex32
P_PRINT " esi=0x"
mov eax,[esp+4*3]
call protected_print_hex32
P_ENDL
P_PRINT "edi=0x"
mov eax,[esp+4*2]
call protected_print_hex32
P_PRINT " esp=0x"
mov eax,[esp+4*5]
call protected_print_hex32
P_PRINT " ebp=0x"
mov eax,[esp+4*4]
call protected_print_hex32
P_PRINT " eip=0x"
mov eax,[esp+4*1]
call protected_print_hex32
P_PRINT " Next: "
mov ebx,eax
mov ecx,4
.loop:
mov al,[ebx]
call protected_print_hex8
P_PRINT " "
inc ebx
loop .loop
mov [cursor],si
ret
dump_number: dd 1
times (0x10000-0x7c00)-($-$$)-(sector2_end-bootloader_info) db 0x00
bootloader_info:
PML4T_64MiB_ADDRESS: dq 0
; For calls
LONG_MODE_STACK_POINTER_SAVED: dq LONG_MODE_BOOTLOADER_STACK_BASE
REAL_MODE_FUNCTION_TO_CALL: dw 0
address_of_PML4T: dq 0
address_of_global_descriptor_table: dq 0
address_to_jump_after_changing_the_mode: dq 0
;----------
BIOS_REAL_MODE_IVT:
dw 0x3ff
dd 0x0000
DRIVE_NUMBER: db 0
; For calls from c++ ----------------------------------------
INTERRUPT_NUMBER: db 0
SAVED_ES: dw 0
SAVED_AX: dw 0
SAVED_BX: dw 0
SAVED_CX: dw 0
SAVED_DX: dw 0
SAVED_SI: dw 0
SAVED_DI: dw 0
SAVED_RAX: dq 0
SAVED_RBX: dq 0
SAVED_RCX: dq 0
SAVED_RDX: dq 0
SAVED_RSI: dq 0
SAVED_RDI: dq 0
ASSEMBLY_FUNCTION_NUMBER dq 0
CALL_ASSEMBLY_FUNCTION: dq call_assembly_function_from_cpp
;------------------------------------------------------------
sector2_end:
entrypoint:
The bootloader starts at the beginning of "bootloader1.asm", in "jmp sector2" jumps to the beginning of "bootloader4.asm" and my computer restarts between the first "P_DUMP" and the second "P_DUMP" (because it shows on the screen the values of the registers and the number of the dump is 1 before it restarts).
Also: Is it necessary to use the BIOS function "int 13h; ah=42h" to read from the DVD? Or can I just use "int 13h; ah=02h"?
User contributions licensed under CC BY-SA 3.0