Thread View: borland.public.delphi.language.basm
5 messages
5 total messages
Started by Aleksander Oven
Wed, 14 May 2008 17:33
Code patching, near jumps, and PAE
Author: Aleksander Oven
Date: Wed, 14 May 2008 17:33
Date: Wed, 14 May 2008 17:33
35 lines
1974 bytes
1974 bytes
Hi,
I have observed a problem with my patching code on 32-bit systems with
lots of RAM (4 GB) and Physical Address Extension enabled.
The patching code in question uses the same principle as the
FastcodeAddressPatch(), i.e. using the TJump record:
type
TJump = packed record
OpCode: Byte;
Offset: Cardinal;
end;
and then calculates the Offset as follows:
Jmp.OpCode := $E9;
Jmp.Offset := Cardinal(aNewAddr) - Cardinal(aOldAddr) - SizeOf(TJump);
What I've noticed on systems described above is that aNewAddr is not
necessarily greater than aOldAddr, so the resulting Offset may be
negative. I decided to experiment a little, so I changed the Offset
declaration to LongInt, and it seemed to work with the negative Offsets.
But every now and then I get an EIntegerOverflow, because the aNewAddr
and aOldAddr are so far apart, the result doesn't fit into a LongInt.
What should I do? Simply put a {Q-} before the calculation and hope for
the best? Or am I missing something?
Thanks in advance.
--
Regards,
Aleksander Oven
Re: Code patching, near jumps, and PAE
Author: Les Pawelczyk
Date: Wed, 14 May 2008 18:22
Date: Wed, 14 May 2008 18:22
13 lines
1256 bytes
1256 bytes
> What should I do? Simply put a {Q-} before the calculation and hope for
> the best? Or am I missing something?
Decide whether to use Cardinal or Integer and then be consistent (do not mix types):
Jmp.Offset := Cardinal(aNewAddr) - Cardinal(aOldAddr) - Cardinal(SizeOf(TJump));
or
Integer(Jmp.Offset) := Integer(aNewAddr) - Integer(aOldAddr) - SizeOf(TJump);
Les.
Re: Code patching, near jumps, and PAE
Author: Les Pawelczyk
Date: Wed, 14 May 2008 18:36
Date: Wed, 14 May 2008 18:36
10 lines
1283 bytes
1283 bytes
> But every now and then I get an EIntegerOverflow, because the aNewAddr > and aOldAddr are so far apart, the result doesn't fit into a LongInt. Of course you'd have to disable overflow checking around the address patching code. You do actually want the resulting offset to wrap around without checking for overflow and causing an exception. Les.
Re: Code patching, near jumps, and PAE
Author: Aleksander Oven
Date: Wed, 14 May 2008 18:43
Date: Wed, 14 May 2008 18:43
6 lines
1101 bytes
1101 bytes
It seemed to me the natural thing to do, too. Thanks for confirming it! -- Regards, Aleksander Oven
Re: Code patching, near jumps, and PAE
Author: Aleksander Oven
Date: Wed, 14 May 2008 18:52
Date: Wed, 14 May 2008 18:52
17 lines
1650 bytes
1650 bytes
Les Pawelczyk wrote: > Decide whether to use Cardinal or Integer and then be consistent (do not mix types): > > Jmp.Offset := Cardinal(aNewAddr) - Cardinal(aOldAddr) - Cardinal(SizeOf(TJump)); Interesting remark. Indeed, SizeOf() is documented as returning a SmallInt, which is a signed type. However, I've always considered SizeOf() as a syntactic placeholder to be replaced by an unsigned constant at compile-time. I mean, there really is no way the size of anything can be less than 0, is there? I figured if the the compiler doesn't emit any warning about comparing signed and unsigned types, it must be ok. -- Regards, Aleksander Oven
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads