3 ms·
> No. The virtual address space starts at the 64KB boundary. You can confirm this by calling GetSystemInfo and checking the lpMinimumApplicationAddress. It wi
by titzer 4y ago
> No. The virtual address space starts at the 64KB boundary. You can confirm this by calling GetSystemInfo and checking the lpMinimumApplicationAddress. It will be 0x00000000`00010000.
Aw, man. I recently found out there is also a similar restriction on Linux. Bummer, because I have a good use for putting code into the lower 64KB of memory (not 4KB, still want to use that for catching NPEs). My use case is a fast interpreter for bytecode. Since every bytecode handler needs an entry in the dispatch table, and I have 7--yes 7!--dispatch tables, I'd like to make their entries 2 bytes. So instead of taking 1KB each, they would take only 512B each. But alas.
Another great use case is Wasm. Since the memory is a sandboxed 4GB range and only indexed into by 32-bit offsets, placing it at virtual address 0 would save an add instruction (or use of segment register) on every access.
- p_l 4y agoOn linux it depends on a sysctl parameter, and on 4kB platforms some runtimes used the fact that it was set to "one page" as a method to have very short pointers starting at address 4097 for things very often references (and which might need guard page, like NULL value). Made for some borked code with Clozure Common Lisp when people started running 64kB pagesize on PPC64, and that meant that even with minimal zero page it still was too big to map the "low memory" where CCL stuck it's NULL definition.
- messe 4y ago> Since every bytecode handler needs an entry in the dispatch table, and I have 7--yes 7!--dispatch tables, I'd like to make their entries 2 bytes. So instead of taking 1KB each, they would take only 512B each. But alas. Hmm. If the upper half of the handler addresses are the same, then why not store just the lower 2-bytes of each handler address in the dispatch table. If you're on x86, there's no add needed if the upper bytes of the register you're loading into already contain the upper half of the address, for example: mov eax, HANDLER_BASE mov ax, [edi + ebx]
- titzer 4y agoInteresting idea. I think it means using another register to permanently hold the HANDLER_BASE though? The dispatch sequence is only 4 instructions. I tried it as a delta encoding, requiring another add instruction on every dispatch, but that is an approx. 5% penalty. So I was hoping that putting it at absolute address < 64KB I could do the sequence without another add.