Something that tricked me:If 0x7c is the actual physical memory where my program is getting loaded, how does ORG = 0x7c is an offset from the beginning of the segment to the head of my program? Doesn't that mean that the segment starts from memory 0x0?

it does if you set the segment register to 0 (like you are doing with DS) -- note though that you can only access the first 64KB of memory without changing DS to something different (in normal RMode, your offset, and thus your ORG also, will always be less than 64K)

because DS.base == 0, your ORG is the same as the address you are loading to, but if your DS.base != 0, then your ORG would not be the same as the loading address

Oh I was thinking that ORG was the offset from the CS.base to the start of my program. I read your post where you said about it and I found out I missed that you where saying from the DS.base to the head of my program.

Now I get everything!!! Thank you so much!Well, I'll certainly be back with more questions when I move further in learning about OSes.

You'd probably run into fewer issues if you use org 0x7c00 and set the segment registers to zero. This has the advantage that linear addresses (in real mode the same as physical ones) are the same. Offsets are relative to the beginning of memory. This is advantageous if you intend to create a GDT to be loaded with LGDT. The GDT record requires a linear address to the base of the GDT. If you use a non-zero segment like 0x7c0 then you have to adjust any linear addresses you may use by adding 0x7c00 to them.

Regarding the lack of segment .text... We don't use "segment .text" in the code because of its redundancy; .text is the default segment. It is also important to note that org 0 is the default origin value if not specified.

Regarding the org directive... Instructions that reference labels generate relocations that get added to the origin value. This is important for generating correct label addresses. Note this is an assembler directive and is only used to translate to correct code. For example:

Scenario 1: With org 0, segments set to 0x7c0...instructions like mov ax, ds:[myLabel] are translated as mov ax, ds:[myLabel+0]. Because ds is 0x7c0 this is 0x7c0:myLabel which is what we want. So org 0, ds=0x7c0 works.

Scenario 2: With org 0x7c00, segments set to 0...Instructions like mov ax, ds:[myLabel] are translated as mov ax, ds:[myLabel+0x7c00]. Because ds is 0, this is 0:myLabel+0x7c00=0x7c0:myLabel. So org 0x7c00, ds=0 works. This is what we do in the tutorial.

Scenario 3: With org 0x7c00, segments set to 0x7c0...Instructions like mov ax, ds:[myLabel] are translated as mov ax, ds:[myLabel+0x7c00]. Because ds is 0x7c0, this places myLabel at 0x7c0:myLabel+0x7c00, or 0xf80:myLabel which is well outside the boot record code. This would result in garbage data being loaded into ax - not what we want.

About the code... The code assumes the assembler translates "jmp loader" as a 3 byte near jump. However, with optimization, could be translated as a short jump which will cause problems with the BPB. It is recommended to be explicate; "jmp near loader" or "jmp short loader .. nop". Also, the code should not assume its actual load address. Right at the start of "loader", it should do a far jump or push/retf to fix it. Not doing so may cause unexpected behavior on systems that loads the code in a different segment then what your code expects (i.e. loading to 0:0x7c00 instead of 0x7c0:0.) Finally, to stop executing, cli and hlt should be in an infinite loop. I.e. "stop: cli .. hlt .. jmp stop". cli does not mask SMM and NMI's which can wake the system, so cli and hlt alone isn't enough.

Also, the code should not assume its actual load address. Right at the start of "loader", it should do a far jump or push/retf to fix it.

I cannot possibly disagree with this advise more strongly

the truth is, while it is true (as I stated in my previous posts) that you cannot know what CS:IP combination in use, it is also true (as I stated in my previous posts) that it doesn't matter what the CS:IP combination is

Quote:

Not doing so may cause unexpected behavior on systems that loads the code in a different segment then what your code expects (i.e. loading to 0:0x7c00 instead of 0x7c0:0.)

the only "unexpected behavior" that can possibly occur is IP wrapping around to zero before getting to the end of your code... which would only happen if CS was set to something really weird (like CS:IP == F7C1:FFF0)... which doesn't happen often enough to care about, and even when it does, it is safe enough to assume it can reach the end of the BPB -- that means, if you assume CS <= 0xF7C0 || CS >= 0xF7E0 (and half of those values would fail to boot DOS/Windows too) then there is no need to care what CS is

Not doing so may cause unexpected behavior on systems that loads the code in a different segment then what your code expects (i.e. loading to 0:0x7c00 instead of 0x7c0:0.)

the only "unexpected behavior" that can possibly occur is IP wrapping around to zero before getting to the end of your code... which would only happen if CS was set to something really weird (like CS:IP == F7C1:FFF0)... which doesn't happen often enough to care about, and even when it does, it is safe enough to assume it can reach the end of the BPB -- that means, if you assume CS <= 0xF7C0 || CS >= 0xF7E0 (and half of those values would fail to boot DOS/Windows too) then there is no need to care what CS is

One spot where you would run into trouble is if your boot code uses an absolute indirect near jump rather than a relative near jump, but that's easily enough avoided.

Who is online

Users browsing this forum: Bing [Bot] and 16 guests

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