Ok, back with another JIT-related question.
In my custom machine-code, I need to be able to embedd calls to native functions that are part of the compiled program. The easiest working way I found is this:
void JitGenerator::WriteCallFunctionPointer(const void* pAddress)
{
WriteStoreConstant(std::uintptr_t(pAddress), RegisterType::RAX);
WriteLine({ 0xff, 0xd0 }); // call rax
}
void test(void) {}
WriteCallFunctionPointer(&test);
However, this is using an “indirect” call, which is slower (ranging from neglegible to exterme depending on the branch-prediction as far as I've read). So I'd like to change this to use a direct call instead, however I'm not 100% sure about how I'd go about changing it. From the documentation (https://www.felixcloutier.com/x86/call), it seems I'm looking for:
E8 cd => Call near, relative, displacement relative to next instruction. 32-bit displacement sign extended to 64-bits in 64-bit mode.
So basically I'd take the address I have and convert it to an offset relative to the address of the start of the next instruction, like you'd do to reference cdata.
But later on, it says:
Near Call — A call to a procedure in the current code segment (the segment currently pointed to by the CS register), sometimes referred to as an intra-segment call.
So thats where I'm a bit lost. What exactly does CS contain? I'm feeling a bit dumb but I've not been able to find a definitive answer. Is a “code segment” the address range for a given piece of executable code, ie. the compiled exe, as opposed to the page I allocate for my JIT-code? If so, is there any better alternative than indirect-call? I'm assuming that "9A cp" while not specifying “indirect” still having to fetch the address from the "ptr16:32" will be equally slow, but I'm not sure.
If CS actually means something different and I can just take the difference of address of my function to the next instruction in the JIT-code, is there any way to ensure that the memory is always in a region that is near the executable? On a 64-bit machine with a 32-bit register, if both values are 2^32 apart from each other than I couldn't use a near call eigther way.
Those are also all just my presumptions anyways. Anybody with a bit more knowledge about this topic able to anser the question?