Page 3 of 4
Re: Bootloader needs fix. See (JMP ...)
Posted: Mon Dec 21, 2015 6:43 pm
by TightCoderEx
The scope and purpose of this site is to point you in the right direction and to that end in all three of the topics you've started, many have given you valuable information and direction. You desperately need to understand segmentation, plain and simple, as without that you'll become monumentally frustrated. I would venture to say, all of us that have developed our own booting systems have been there and done that, and I would suspect all would agree, it wasn't till we understood this real mode model that it start coming together.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 1:33 am
by Techel
You just do a relative jump. Most assemblers will insert such a jump if the label is in a specific range.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 2:26 am
by 0b00000000
Roflo wrote:You just do a relative jump. Most assemblers will insert such a jump if the label is in a specific range.
Consider this:
Code: Select all
bits 16
org 0x7c00
jmp start
start:
xor ax, ax
mov cs, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
How can be sure that CS was a sensible value for the JMP? Are we saying that the JMP will work fine whatever state CS happens to be in? Actually scratch that question. I've just disassembled the above and the JMP comes out as JMP WORD 0x0:0x07CXX. Looks like I'm going to have to figure out the value the relative JMP should have and manually hard code.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 2:47 am
by 0b00000000
OK, let's try this again.
Code: Select all
bits 16
org 0x7c00
jmp start
start:
xor ax, ax
mov cs, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
I assembled this and disassembled this and it came out as JMP SHORT 0x7C02 (machine code EB00). I'm not sure if the assembler I'm using (nasm) can be relied on to always convert this syntax to a short jmp or whether one should hardcode this to be sure. One thing I will note is that any attempt to set CS breaks the code later on. This seems to run contrary to points made in various sources.
Anyway, my basic question remains. How can we assume that the short JMP is always going to work when we have no idea what CS is set to? Or are we saying that in the case of a short JMP it really doesn't matter?
0x00
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:04 am
by iansjack
You cannot set CS in the way that you are attempting to (with a MOV instruction). Any half-decent assembler should refuse to assemble such an instruction.
You need to use a FAR JMP to alter CS.
Being a relative jump, the short jump will work irrespective of the value of CS. It just jumps a certain number of instructions forwards (or backwards) from the current instruction.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:10 am
by Kazinsal
iansjack wrote:You cannot set CS in the way that you are attempting to (with a MOV instruction). Any half-decent assembler should refuse to assemble such an instruction.
There is technically an encoding for it (8E C8 -- MOV CS, AX). However, it is wired to fire an invalid opcode exception.
An assembler does technically have to accept it and assemble it. It does not however have to guarantee the resulting code executes properly.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:12 am
by Techel
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:12 am
by alexfru
0b00000000 wrote:
I assembled this and disassembled this and it came out as JMP SHORT 0x7C02 (machine code EB00). I'm not sure if the assembler I'm using (nasm) can be relied on to always convert this syntax to a short jmp or whether one should hardcode this to be sure.
You could make it
and NASM would error out in case it can't produce a short jump.
0b00000000 wrote:
One thing I will note is that any attempt to set CS breaks the code later on. This seems to run contrary to points made in various sources.
It's just indicative of unsolved problems in your code. I have no problems changing CS in my
boot sector.
0b00000000 wrote:
Anyway, my basic question remains. How can we assume that the short JMP is always going to work when we have no idea what CS is set to? Or are we saying that in the case of a short JMP it really doesn't matter?
Jumps can be absolute far (e.g. jmp sel:ofs), indirect near/far (e.g. jmp eax or jmp [eax] or jmp far [eax] (I hope I got the syntax right)), or near relative only.
The first loads sel into CS. The second changes CS only if it's a far jump with the far address being in memory (e.g. jmp far [eax]). The last doesn't touch CS at all, it merely adds a constant to [R|E]IP. That's why it's relative and that's why it isn't affected by the value in the org directive. If you move code containing a relative jump (short or not), it will still jump by the same amount forwards or backwards. Time to start reading the instruction set reference?
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:16 am
by 0b00000000
iansjack wrote:You cannot set CS in the way that you are attempting to (with a MOV instruction). Any half-decent assembler should refuse to assemble such an instruction.
You need to use a FAR JMP to alter CS.
Being a relative jump, the short jump will work irrespective of the value of CS. It just jumps a certain number of instructions forwards (or backwards) from the current instruction.
If that is true I'm guessing this must be in reference to whatever ORG was set to because JMP start and JMP SHORT 0x7C02 in my current test codes are disassembling to the exact same machine JMP SHORT 0x7C02 with machine code (EB00). I don't know much about machine code but I'm guessing that EB must be the short jump instruction and 00 is the distance of the short jump? This, of course, giving the overall effect that there is no jump at all. IP remains unchanged and execution proceeds with the following bytes in memory.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:20 am
by 0b00000000
alexfru wrote:0b00000000 wrote:
Jumps can be absolute far (e.g. jmp sel:ofs), indirect near/far (e.g. jmp eax or jmp [eax] or jmp far [eax] (I hope I got the syntax right)), or near relative only.
The first loads sel into CS. The second changes CS only if it's a far jump with the far address being in memory (e.g. jmp far [eax]). The last doesn't touch CS at all, it merely adds a constant to [R|E]IP. That's why it's relative and that's why it isn't affected by the value in the org directive. If you move code containing a relative jump (short or not), it will still jump by the same amount forwards or backwards. Time to start reading the instruction set reference?
I'm starting to think that assembly is not as low level as may be desirable for some situations. It seems that the only way to be sure this is working right in some cases is to inspect the machine code. I wonder if there is a disassembler out there that can give a richer instruction set that differentiates between all the variant of instructions like JMP, MOV etc.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:23 am
by iansjack
Kazinsal wrote:An assembler does technically have to accept it and assemble it.
I'm not sure that an assembler
must assemble such code, any more than a C compiler must compile incorrect code. In both cases the translator should at least have the ability to warn the user of the consequences of such code. In the case of the assembler I can think of no good reason to assemble code that will automatically lead to an "undefined opcode" exception. (It's not as if there aren't other ways of inserting such an instruction if you are determined to.)
At the very least a half-decent assembler would refuse to assemble the instruction without a manual override from the user (indicating that they know what they are doing). Otherwise we end up with silly situations like the current one.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:26 am
by Techel
I don't know much about machine code but I'm guessing that EB must be the short jump instruction and 00 is the distance of the short jump?
Ehem.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:32 am
by 0b00000000
I guess it would be useful to be able to include inline machine code to be sure this is always going to assemble properly.
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:36 am
by Techel
You can add the db, dw dd etc directives to insert bytes, but thats not neccessary as you can add the short keyword to the jump (or omit it, near jumps are short by default in nasm)
Re: Bootloader needs fix. See (JMP ...)
Posted: Tue Dec 22, 2015 3:44 am
by 0b00000000
Roflo wrote:I don't know much about machine code but I'm guessing that EB must be the short jump instruction and 00 is the distance of the short jump?
Ehem.
OK,
so now I have two basic variants which seem to output the desired machine code (EB00).
and
I'm wondering if there is a way I bypass both of these and just tell the assembler in no uncertain terms that I want a short jmp (EB) and want it to make no change to the IP (00). As far as I can see there is no way of doing this without using a label or calculating the relative jmp oneself. Why can't I just tell the assembler quite simply that I want the operand to be 00?