Thanks to commenters I have already learned two useful things as a result of yesterday’s post, both things which I cannot fathom how I did not already know. But here’s something I learned for myself as a result of a comment made by Malcolm Groves at the Auckland Delphi 2010 launch day recently.
As mentioned in yesterdays post, a new feature in Delphi 2010 is the ability to drag and drop the execution point when stopped in debug mode.
However, Malcolm mentioned that this could be achieved – rather more awkwardly – in previous versions of Delphi via the CPU window, although the precise details escaped his memory at the time, other than that it involved modifying the contents of a particular register.
I found myself last night in exactly the situation I described in my speculative “when this might be useful” discussion of moving execution points. I happened to be in an older version of Delphi at the time and it was a relatively small project so a “halt, modify, recompile and retest” cycle wouldn’t have been too arduous, but I decided instead to reach for the CPU window to see if I couldn’t figure out how to achieve it and see just how awkward it might be.
It didn’t take long, and actually, it wasn’t too awkward at all.
Here’s the CPU view, with an additional bit of highlighting to draw attention to the useful areas (click to embiggen):
The two connected box highlights show that the EIP register contains the current execution point address. So this is the register that Malcolm was referring to.
Now, there are actually TWO ways we can use this information to change the execution point in older Delphi versions…
You can either position the highlight in the CPU disassembly view on the desired execution point and invoke the “New EIP” item on the disassembly context menu:
Or you can directly increment or decrement the EIP register using the register view context menu:
In this capture I’ve also highlighted the address of the next executable point corresponding to a line of source in my code – you will notice that the addresses in that list are non-contiguous, and when incrementing or decrementing the EIP value I think you need to be careful that you set the value to an address that corresponds to one of the addresses in this list.
When you increment/decrement the EIP register, the value is incremented as a simple value, without respect to this list of addresses. i.e. “Increment” add’s 1 (one) to the value, it doesn’t advance it to the “next valid address”.
I’m not sure what would happen if you tried to resume execution from an address that is not in that CPU disassembly list, but I’m pretty confident it wouldn’t be “good things”.
So grateful thanks to the commenters to my previous post and to Malcolm for furthering my awareness of things already at my disposal.