Nice article, but nothing really surprising when you follow the progression starting from 8080. One correction though: > EAX is called the “Accumulator register” is not just a convention, it actually makes a difference to the encoding (and potentially the performance, as a result) No. As the decoder doesn't decode byte-by-bytes, but whole strings together and registers are all renamed meaning that %eax isn't really d…
My point is the smaller encoding is what gives you the performance benefit. When done across an entire function/module, you can get a measurable increase in hit rate for the instruction cache. Not that the instruction itself is faster. Apologies if that wasn't clear.
Weird things I learned while writing an x86 emulator
71–75 of 75 posts
Re: Weird things I learned while writing an x86 emulator
#72Earlier quoted context omitted.
That's what I thought as well, limited to the single-core race conditions era. Thanks for the evidence.
It's not limited to any era - it's a general-purpose tool that can perfectly reproduce bugs, even most race conditions. The lack of multi-threading will mostly just slow things down. Being able to perfectly reproduce a bug is immensely valuable.
Re: Weird things I learned while writing an x86 emulator
#73Earlier quoted context omitted.
Ha, I was just reading some of the discussion and thinking it sounded quite similar to the JIT we use in our own (Linuxy) Time Travel Debugger. It's similarly am x86-on-x86 JIT / emulator but (and I'm sure WinDbg's TTD is similar) most of what you want to do there is just code copying for any instructions that don't need special instrumentation. And you want to run entirely in the cache of JITted code so you're close…
Funny enough, we tried going down the road of doing a JIT, but for our use cases pure emulation was often fast enough and it wasn't worth the extra complexity to do JIT. Part of that is probably due to the architecture of how TTD works, but part of it is how efficient we were able to get with the emulation mode. Later, a different emulator was created for running x86 code on ARM64, and that one uses an extremely effi…
I'm surprised a JIT wasn't worth it but, from what I'm aware of, I can see a few reasons why the trade offs are different.
Re: Weird things I learned while writing an x86 emulator
#74Earlier quoted context omitted.
IIRC from our similar code, the LEA (load effective address) instruction is useful for doing adds / subtracts of arbitrary integers without updating the flags. Flags turn out to be quite the annoyance for the kind of in-process virtualization needed by Time Travel Debug. You need to instrument code with minimal overhead so, on the one hand, you don't want to save/restore flags all the time .... And on the other hand…
Yes, saving and restoring flags is very expensive. I thought about talking about that in the article but figured that was too much of a detour. Darek Mihocka wrote a really interesting article about how to optimize flag calculations in an x86 emulator: http://emulators.com/docs/nx11_flags.htm Although looking at your username I suspect you may have read this one before...
Re: Weird things I learned while writing an x86 emulator
#75Has anyone used TTD, or rr for that purpose in Linux world, to debug a complex multi-threaded application? What is the main use-case of these tools? For example, limitations of rr seem to suggest that it is almost of no use for multi-threaded programs so I have never actually tried it. I don't know about the TTD though. > rr limitations > ... > emulates a single-core machine. So, parallel programs incur the slowdown…
As others have said here, in practice rr works very well for debugging a wide range of bugs in multithreaded programs, including race conditions.
Where it falls down:
* It can only use a single core, so highly parallel programs run very slowly when recorded by rr.
* Some race conditions may be difficult or impossible to reproduce under rr recording (but rr's chaos mode helps a lot with this).
* rr imposes sequential consistency on the recorded program, so bugs due to weak memory models do not show up under rr. Such bugs are pretty rare on x86 (because x86's memory model is pretty strong); this may be more of an issue on ARM.