Bootloader needs fix. See (JMP ...)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Bootloader needs fix. See (JMP ...)

Post by alexfru »

0b00000000 wrote:
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.
You need check your assembler documentation to see what syntax is to be used for what forms of instructions. There's nasmdoc.(txt|pdf) for NASM.

It is true, however, that in certain cases assemblers are too primitive or too smart on the contrary and you have to encode instructions manually. For example, there are instructions like SHL and SAL and intel and AMD are trying to deprecate SAL and some assemblers accept SAL but generate SHL instead. Both do the same thing, but differ in encoding. Deprecating SAL frees an opcode for some other new instruction or subset of instructions. AFAIR, there are a few other duplicates in the instruction set. There are also instructions like MOV r/m8, R8 and MOV r8, r/m8, where r8 is an 8-bit register and r/m8 is either an 8-bit register or an 8-bit memory location. Obviously, there are two different encodings available for MOV AL, AH, which is representable as either. For most purposes it doesn't matter which of the two is used. But if you're trying to use code as data or data as code, you have to consider the issue. The same thing applies to instruction prefixes. There's a certain freedom as to their order of appearance, which typically should make no difference (except, it looks like some older CPUs had bugs w.r.t. the order).
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Bootloader needs fix. See (JMP ...)

Post by alexfru »

0b00000000 wrote: OK,

so now I have two basic variants which seem to output the desired machine code (EB00).

Code: Select all

jmp short start
start:
and

Code: Select all

jmp short 0x7c00
I doubt that both assemble into the same byte sequence in your code.
0b00000000 wrote: 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).
You've been told to use "short".

Strictly speaking, if the instruction pointer does not change, your code makes no forward progress, looping forever or hanging.
0b00000000 wrote: 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?
Rarely needed thing. What do you have against labels? They cost nothing in the generated code and occupy a line in the source code.

There's, however, an alternative way to express 0xEB, 0x00:

Code: Select all

jmp short $ + 2
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

alexfru wrote:
0b00000000 wrote:
0b00000000 wrote: 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?
Rarely needed thing. What do you have against labels? They cost nothing in the generated code and occupy a line in the source code.

There's, however, an alternative way to express 0xEB, 0x00:

Code: Select all

jmp short $ + 2
Great. Just tested it. Works fine.
0x00
Post Reply