OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:04 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: NASM JMP offset ignored
PostPosted: Sun Feb 04, 2018 8:34 pm 
Offline
Member
Member

Joined: Sun Feb 04, 2018 8:04 pm
Posts: 35
I am new to NASM and i386 assembly. I did some 8 bit work back in the day, but ... enough said about that.

From various tutorials online, I have cobbled together a bootloader that reads a kernelette directly from sector 2 and transfers control.

My problem is that the final JMP instruction's offset address seems to be ignored. I can set JMP SEG:OFFSET to any value of offset and the kernelette still works. Even if the offset is way past the address where the instructions would have loaded (eg 0xFFFF) my kernelette still executes.

I have read all I can about the JMP instruction and nothing says real mode JMP immediate ignores the offset. My code is below.

I don't want code that works by accident, so if anyone can explain the JMP (or NASM's interpretation of JMP) better than what I've found online so far, I would be most grateful!

Thanks for reading.
DP

boot loader code
Code:

;bootloader code
%assign KERNEL_BASE_SEGMENT         0x1000   ; DPP: I added this.
%assign KERNEL_ENTRY_ADDRESS              0x0000  ; DPP: I added this.
%assign KERNEL_SECTOR_START         1      ; DPP: I added this.
%assign KERNEL_SECTOR_COUNT         12      ; DPP: I added this.

%define BOOT_DRIVE_NUMBER                  0x80
%assign BIOS_VIDEO_SERVICES         0x10
%assign BIOS_DISK_SERVICES                 0x13

%assign READ_DISK_SECTORS                 0x02

%assign SET_VIDEO_MODE            0x00   

[BITS 16]
[ORG 0x7C00]

   mov si,   MESSAGE_LOADING
   call print

   ;load kernelette from sector 2 into 0x1000:0000
   MOV DL, 0x80      ;drive number
   MOV DH, 0x0    ;head (0=base)
   MOV CH, 0x0    ;track/cylinder
   MOV CL, 0x02    ;sector
   
   MOV BX, 0x1000    ;can't update ES directly, so put destination segment into BX
   MOV ES, BX       ;place BX in pointer ES
   MOV BX, 0x0            ;BX is actually destination offset, so we want it to be zero.

   
read_disk:
   MOV AH, 0x02
   MOV AL, 0x01
   INT 0x13
   JC read_disk    ;infinite retry for now.

   ;pointers to kernel segment (0x1000)
   MOV AX, 0x1000
   MOV DS, AX              ;DS (update data segment)
   MOV SS, AX      ;SS (update stack segment)
   
   ;ANY of these JMPs work. Offset is ignored. why?
   JMP 0x1000:0x0000   
   ;JMP 0x1000:0x0200   
   ;JMP 0x1000:0x0020   
   ;JMP 0x1000:0xDADA   
   ;JMP 0x1000:0xFFFF

never_get_here:
   cli
   hlt
   jmp $

print:
   mov bp,sp
   print_repeat:
   lodsb
   or al,al
   jz print_done
   mov ah,0x0e
   mov bx,0
   int BIOS_VIDEO_SERVICES
   jmp print_repeat
   
print_done:
   mov sp,bp
   ret

MESSAGE_LOADING db "Loading simple Kernel...",10,13,0
MESSAGE_LOADED db "Kernel Loaded. Transferring control",10,13,0

TIMES 510 - ($ - $$) db 0   ;pad to exact sector size (512) minus signature
DW 0xAA55          ;boot loader signature



kernel code

Code:
;kernelette code

[BITS 16]

%assign BIOS_VIDEO_SERVICES         0x10

   mov AH, 0x0E
   mov BH, 0x00
   mov BL, 0x07

hello_again:
   MOV SI, message_hello            ;move msg to SI-pointer
   CALL print             ;call function to print SI (msg)

   mov ah,0              ;wait for keypress
   int 16h

   jmp hello_again

print:
   mov bp,sp
   print_repeat:
   lodsb
   or al,al
   jz print_done
   mov ah,0x0e
   mov bx,0
   int BIOS_VIDEO_SERVICES
   jmp print_repeat
   
print_done:
   mov sp,bp
   ret

message_hello db 'Hello world from the kernel!', 13, 10, '  Press any key to continue!', 13, 10, 0

TIMES 512 - ($ - $$) db 0 ;pad the sector

_________________
Code or code not. There is no try.


Top
 Profile  
 
 Post subject: Re: NASM JMP offset ignored
PostPosted: Sun Feb 04, 2018 11:24 pm 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
What you're read and your understanding of the instruction is correct.

The only way any of those combinations can work is if there is nothing preventing system from wrapping around. Therefore jumping to 0x1000:0xffff would work so long as the next 16 instructions at that address don't prevent wrap around. Have a look at your disk image or what the software you're using for testing is doing.


Top
 Profile  
 
 Post subject: Re: NASM JMP offset ignored
PostPosted: Mon Feb 05, 2018 10:21 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

davidpi wrote:
I have read all I can about the JMP instruction and nothing says real mode JMP immediate ignores the offset. My code is below.


In real mode, JMP doesn't ignore the offset; therefore there must be a problem with how you're testing your code.

For example, maybe there's a problem with the makefiles/scripts/whatever you're using to build your project (e.g. maybe the file is assembled but a floppy image isn't updated, so the emulator you're using boots an old copy of the code from the floppy image and doesn't boot the new code with a different JMP offset).

For another example, maybe you're not using "single-step debugging", and maybe the JMP actually does work correctly; but the memory at those offsets (at 0x1000:0x0200, 0x1000:0xDADA, etc) is full of zeros so the CPU thinks they're ADD instructions and executes them until IP wraps around to 0x0000, and you see that the code at 0x1000:0x0000 does get executed (kernel still prints the hello message) and assume it's because the JMP didn't work when it actually did.

The best way to figure out what is going on is with something like the single-step debugger in Bochs, which displays the instruction from RAM (and not from a file) immediately before it's executed and lets you see "CS:IP" immediately after it's executed.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: NASM JMP offset ignored
PostPosted: Tue Feb 06, 2018 7:25 pm 
Offline
Member
Member

Joined: Sun Feb 04, 2018 8:04 pm
Posts: 35
Thank you both...both answers pointed me in the right direction.

After a bit of a learning curve on the bochs debugger, I found that the 'empty' segment data at the end of my 80 byte kernel was treated as a series of NOPs to the end of the stack, at which point a GPF was triggered. The GPF's RET effectively reset the IP to zero and continued execution at the start of the segment ... my kernelette's entry point!

So it was effectively a wrap-around and did need a single-step debugger to figure it out. =D>

A great learning experience, that got me started with the bochs debugger, not as daunting as I initially thought.

Now I feel much more confident, not quite so much of a NOOB.

Thanks again.

DP

_________________
Code or code not. There is no try.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 43 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group