I have a code segment which was located at sector 37 of boot.img file, and in my master boot record I loaded this code into memory 0x5678:0x1234, here is my asm code:
[BITS 16] ;Set code generation to 16 bit mode
ORG 0x1234 ;set addressing to begin at 0x5678:0x1234
mov ax, cs
mov ds, ax
mov es, ax
call cls ;call routine to clear screen
call dspmsg ;call routine to display message
startdt:
call date
call cvtmo
call cvtday
call cvtcent
call cvtyear
call dspdate
call time
call cvthrs
call cvtmin
call cvtsec
call dsptime
jmp startdt ;use infinite loop to halt?
cls:
mov ah,06h ;function 06h (Scroll Screen)
mov al, 0 ;scroll all lines
mov bh,0x0a ;Attribute (light green on black)
mov ch,0 ;Upper left row is zero
mov cl,0 ;Upper left column is zero
mov dh,24 ;Lower left row is 24
mov dl,79 ;Lower left column is 79
int 10H ;BIOS Interrupt 10h (video services)
ret
dspmsg:
mov ah,13h ;function 13h (Display String)
mov al,0 ;Write mode is zero
mov bh,0 ;Use video page of zero
mov bl,0x0c ;Attribute (light red on black)
mov cx,msglen ;Character string is 25 long
mov dh,3 ;position on row 3
mov dl,[center] ;and column 28
lea bp,[msg] ;load the offset address of string into BP
int 10H
ret
msg: db 'Pradox V 0.1 Jiansong He',10,13
msglen: equ $-msg
int 10H
ret
date:
;Get date from the system
mov ah,04h ;function 04h (get RTC date)
int 1Ah ;BIOS Interrupt 1Ah (Read Real Time Clock)
ret
;CH - Century
;CL - Year
;DH - Month
;DL - Day
cvtmo:
;Converts the system date from BCD to ASCII
mov bh,dh ;copy contents of month (dh) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld],bh
mov bh,dh
and bh,0fh
add bh,30h
mov [dtfld + 1],bh
ret
cvtday:
mov bh,dl ;copy contents of day (dl) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld + 3],bh
mov bh,dl
and bh,0fh
add bh,30h
mov [dtfld + 4],bh
ret
cvtcent:
mov bh,ch ;copy contents of century (ch) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld + 6],bh
mov bh,ch
and bh,0fh
add bh,30h
mov [dtfld + 7],bh
ret
cvtyear:
mov bh,cl ;copy contents of year (cl) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld + 8],bh
mov bh,cl
and bh,0fh
add bh,30h
mov [dtfld + 9],bh
ret
dtfld: db '00/00/0000'
dspdate:
;Display the system date
mov ah,13h ;function 13h (Display String)
mov al,0 ;Write mode is zero
mov bh,0 ;Use video page of zero
mov bl,0x0a;Attribute
mov cx,10 ;Character string is 10 long
mov dh,4 ;position on row 4
mov dl,[center] ;and column 28
push ds ;put ds register on stack
pop es ;pop it into es register
lea bp,[dtfld] ;load the offset address of string into BP
int 10H
ret
time:
;Get time from the system
mov ah,02h
int 1Ah
ret
;CH - Hours
;CL - Minutes
;DH - Seconds
cvthrs:
;Converts the system time from BCD to ASCII
mov bh,ch ;copy contents of hours (ch) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmfld],bh
mov bh,ch
and bh,0fh
add bh,30h
mov [tmfld + 1],bh
ret
cvtmin:
mov bh,cl ;copy contents of minutes (cl) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmfld + 3],bh
mov bh,cl
and bh,0fh
add bh,30h
mov [tmfld + 4],bh
ret
cvtsec:
mov bh,dh ;copy contents of seconds (dh) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmfld + 6],bh
mov bh,dh
and bh,0fh
add bh,30h
mov [tmfld + 7],bh
ret
tmfld: db '00:00:00'
dsptime:
;Display the system time
mov ah,13h ;function 13h (Display String)
mov al,1 ;Write mode is zero
mov bh,0 ;Use video page of zero
mov bl,0x0a;Attribute
mov cx,8 ;Character string is 8 long
mov dh,5 ;position on row 5
mov dl,[center];and column 0
push ds ;put ds register on stack
pop es ;pop it into es register
lea bp,[tmfld] ;load the offset address of string into BP
int 10H
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;variables;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
center: db 25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;end variables;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
my emulator is dosbox, operation system is lubuntu running on Oracle VM virtual box, my own operating system is win8 x64
notice the variable field at the end of file, if I put this filed at the top, right after I updated my DS and ES register, I got a issue:
cls and dspmsg subroutine won't work
however if I change the value to center: db 30
or just put this field at the end of my code, it will work.
Can someone explain why putting the variable field on top of my code and changing the value of my label will effect the program's performance? Does this has to do with my segment register?
here is my loader:
;bit16 ; 16bit by default
org 0x7c00
jmp short start
nop
bsOEM db "OS423 v.0.1" ; OEM String
start:
;;load sector into memory & 5678h:1234h
mov bx, 0x5678 ;segmented address
mov es, bx ;move segemented address to es
mov bx,0x1234 ;base address to bx
mov ah, 02 ;function read sectors
mov al, 01 ;# of sectors to load
mov ch, 00 ;track to read
mov cl, 02 ;sector to read
mov dh, 00 ;head to read
mov dl, 00 ;drive number
int 0x13 ;call interrupt 13
jmp 0x5678:0x1234 ;jump to memory address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;variables;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
msg: db 'Welcome to Pradox OS 0.1! Authored by Jiansong he', 10, 13, '$'
mlen equ $-msg
padding times 510-($-$$) db 0 ;to make MBR 512 bytes
bootSig db 0x55, 0xaa ;signature (optional)