Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Boot Loader problem

Status
Not open for further replies.

adholioshake

Programmer
Feb 9, 2003
136
0
0
Hi people.

I have been working on a boot loader program for a while, and it is almost working fully. I've just hit one problem that occurs after loading a program (off sector 2) in memory. Take a look at the code:
Code:
  assume cs:code

code segment
  org 100h

program:
  jmp start

  msg1 db 'Boot Program Started.',0
  err1 db 'Error reading disk! Push a key to restart.',0

start:
  ; Setup segment registers
  mov ax,07b0h
  dw 08ec8h
  mov ax,cs
  mov ds,ax
  mov es,ax

  ; Clear screen
  mov ax,0003h
  int 10h
  ; Remove cursor
  mov ah,02h
  mov bh,00h
  mov dx,2000h
  int 10h

  ; talk to user :)
  sub di,di
  add di,0148h
  lea si,msg1
  call message

reset:              ; Reset the floppy drive
  mov ax,00h        
  mov dl,00h
  int 13h
  jc reset

read:
  mov ax,3000h
  mov es,ax
  mov bx,00h
  mov ah,02h 
  mov al,01h 
  mov ch,00h 
  mov cl,02h 
  mov dh,00h 
  mov dl,00h 
  int 13h

  jc disk_error

  mov ax,3000h
  mov ds,ax
  mov ax,0b800h
  mov es,ax
  mov si,00h

  ; wait for key press
  mov ax,00h
  int 16h
  sub di,di
  mov cx,0400h
output_loop:
  mov al,[si]
  call putchar
  inc si
  loop output_loop

  ; wait for key press
  mov ax,00h
  int 16h

; WHY DOES THIS NOT WORK ???
  ; change cs to 3000
;  mov ax,3000h
;  dw 08ec8h

  ; jmp to 3000:0000, where we loaded program
  db 0eah
  dd 030000000h

disk_error:
  sub di,di
  add di,0148h
  lea si,err1
  call message
  ; wait for key
  mov ax,00h
  int 16h

; reboot system
  mov ax,0040h
  mov es,ax
  mov es:0072h,1234h
  db 0eah
  dd 0ffff0000h


; Dump ds:si msg to screen
message:
  push ax
  push es
  mov ax,0b800h
  mov es,ax
messageloop:
  lodsb
  or al,al
  jz messagedone
  call putchar
  jmp messageloop
messagedone:
  pop es
  pop ax
  ret


; put character (in vid. mem)
putchar:
  mov es:[di],al
  inc di
  inc di
  ret

; boot sig.
  org 510
  dw 0aa55h

code ends

end program
I have indicated the problem with 'WHY DOESN'T THIS WORK??'.
I want the code segment (CS) to be where the program is in memory, but when I try to change it (the code commented out below 'WHY DOESN'T...'), it screws up and just reboots. Why does it do this? Does anyone know what I should do?

Adonai.
 
sorry, in a hurry, no time to check: are your offset and segment right way round for the hard-coded jmp? I always get them wrong if I try to do it myself. Pity assembler won't do jmp's like that for you.
 
Yes lionelhill. I checked that - the boot loader actually works if i don't change CS, the program is loaded and it jumps to the right place. The only problem is the cs and ds registers are in an unknown state when I have jumped to the program, which makes finding data hard. Thanks for the suggestion, though. :)
 
hang on a mo! Sorry, I'm not good at reading op-codes! Do you mean you manually set cs with the commented-out dw 08ec8? (i.e. that's the code for mov cs, ax)?
The current location from which instructions are being taken is cs:ip, so cs must be defined wherever the processor is running? If you set cs on its own, you are doing a far jump. You'd need to set ip at the same time as cs, because otherwise you'd be jumping into the middle of nowhere.
Or am I misunderstanding?? Sorry if so.
 
If I do a jump to the program, as below, do I need to change CS to 3000 then and have IP as 0000, or will that instruction just change the IP address and leave the CS as it was originally?
Code:
  ; jmp to 3000:0000, where we loaded program
  db 0eah
  dd 030000000h
How could I change the CS and the IP at the same time?
If I change just CS the next instruction will be wrong. If I change IP, again the next instruction will be wrong.
 
I've done a little reading in a book of opcodes called "The 8086/8088 family - design, programming and interfacing".
Doing a far jump changes the CS and IP together, not just the IP. For example:
Code:
opcode:     objectcode:   sybolic op.
====================================
JMP far     EA 03 00      IP<-0003
               D3 9E      CS<-9ED3
[code]
 
Yes, absolutely. That is what a far jump is. Anything near changes ip but leaves the code segment the same. Far jumps to a different code segment, which is to say it sets cs and ip. The processor's address for retrieving the next instruction is cs:ip.

There is an analogous problem if you decide to set up your own stack segment while running under a normal operating system such as a dos box. Your code may be interrupted by an interrupt at any time, and it has a right to expect a minimal stack (it needs one anyway, for saving the return address after the interrupt!). If you want to set up a new stack, you need to initialise ss and sp, and if you get the interrupt call between the two, you will be passing a half-prepared stack, and horrible things can happen.
 
I found out why it wasn't working.
The program I have in sector 2 is a dos com file, so always goes to offset 100h. So to correct this, I just needed to load the program to 3000:0100 and jmp there instead.
I think the lower 100 are used for parameter passing in DOS.
Thanks lionel. :)
 
remove org 100h directive and u will have ur code at cs:00.
normally this address is used by the PSP structure, btw.

regards
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top