I'm reading http://thestarman.pcministry.com/asm/2bytejumps.htm but the text isn't very clear about how to do a JMP
to an offset (a short jump to a relative address without using a label).
Let's say I have
NOP
NOP
NOP
NOP
(which is 4 bytes of instructions), and I want to skip them (skip 4 bytes). What would I write?
jmp $+4;
?
jmp $+2+4;
?
A short jmp opcode uses two bytes. When you assemble that, the current position ( $
) points to the beginning of the JMP instruction, not to the beginning of the following instruction.
To jump to the next instruction (a jump that does not actually jump), you do
jmp $+2
So, to jump over N bytes past the JMP instruction, you will do:
jmp $+2+N
In your example, 4 NOP's
jmp $+6
The assembler should detect that this is a jump to a near address and assemble it as a short jump. If want to be sure, use
jmp short $+6
"Skipping" 4 bytes with a single jmp is awkward, because relative jmps occupy 2 or 5 bytes.
To skip over (a total) of 4 bytes, you could do:
jmp short $+4 ; the "short" forces a 2 byte relative branch
nop
nop
If your problem is to fill out a modest number N of bytes, you should emit an appropriately sized-nop. Here's what I use in a compiler I wrote:
void ObjectCodeEmitNByteNop(natural n)
{ // See http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2010-September/003881.html GOOD INFO
/* The Intel Architecture Software developer's guide, volume 2B (instructions N-Z) contains the following table (pg 4-12) about NOP:
Table 4-9. Recommended Multi-Byte Sequence of NOP Instruction
Length Assembly Byte Sequence
=================================================================================
2 bytes 66 NOP 66 90H
3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H
*/
switch(n)
{
case 0:
break; // accidentally aligned
case 1:
ObjectCodeEmitByte(0x90); // sequence recommended by AMD optimization manual
break;
case 2:
ObjectCodeEmitWord(0x9066); // sequence recommended by AMD and Intel optimization manual
// MS assembler suggests: ObjectCodeEmitWord(0xFF8B); "MOV EDI,EDI"
break;
case 3:
ObjectCodeEmitThreeByteNOP();
break;
case 4:
ObjectCodeEmitFourByteNOP();
// ObjectCodeEmitDword(0x90666666); // sequence recommended by AMD optimization manual
// MS assembler suggests: ObjectCodeEmitDword(0x0024648D); // LEA ESP,0[ESP]
break;
case 5:
#if 0
ObjectCodeEmitByte(0x05); // ADD EAX, imm32
ObjectCodeEmitDword(0);
#else
ObjectCodeEmitByte(0x0F); // NOP ...
ObjectCodeEmitDword(0x0000441F); // ... DWORD ptr [EAX + EAX*1 + 00H]
#endif
break;
case 6:
ObjectCodeEmitWord(0x9B8D); // LEA EBX,disp32[EBX] (Microsoft assembler emits this)
ObjectCodeEmitDword(0x00000000); // offset = 0 --> don't change EBX
break;
case 7:
ObjectCodeEmitByte(0x8D); // LEA opcode byte
ObjectCodeEmitWord(0x24A4); // ESP,disp32[ESP]
ObjectCodeEmitDword(0x00000000); // offset = 0 --> don't change ESP
break;
case 8:
ObjectCodeEmitDword(0x00841F0F); // NOP DWORD ptr [EAX + EAX*1 + ...
ObjectCodeEmitDword(0x00000000); // ...00000000H]
break;
case 9:
ObjectCodeEmitByte(0x66); // 66 0F 1F 84 00 00 00 00 00H
ObjectCodeEmitDword(0x00841F0F); // NOP DWORD ptr [EAX + EAX*1 + ...
ObjectCodeEmitDword(0x00000000); // ...00000000H]
break;
default:
{ ObjectCodeEmitJmpRelativeShort(ObjectCodeSize+n);
// ObjectCodeEmitJmpRelativeLong(DesiredObjectLocation); // 5 bytes is safe; 1-4 bytes handled above
ObjectCodeEmitNBreakpoints(n-2);
}
}
}
I prefer to use breakpoint instructions for inline padding that I do not intend to be executed, on the grounds that if it gets executed, the processor will trap and I'll find out about it. You can see that in the "default" case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With