6 ms·
I've exchanged a couple of emails with the author a while ago. Reverse-engineering and decompiling DOS software running in real mode and especially video games
by boricj 2y ago
I've exchanged a couple of emails with the author a while ago. Reverse-engineering and decompiling DOS software running in real mode and especially video games is a particularly tricky endeavor, a notch above other similar projects on other platforms.
The combination of janky PC hardware, paper-thin MS-DOS operating system and prehistoric development tooling makes for an environment where anything goes. Real mode segmented memory and large memory models utterly confuse Ghidra's analyzers and decompiler, most common modern reverse-engineering tools either do not support 16-bit MS-DOS executables or have third-rate support.
It is more art than science in a way that I don't think reverse-engineering later software can match.
- duskwuff 2y agoIt's a little awful to think about just how much collective human effort was wasted by segmented memory. Everyone knew that 32-bit flat memory was the future; it just took a long time for the PC platform to get there.
- jandrese 2y agoYeah, but when you are shipping computers with 256kb like the original PC/XT those extra two bytes per pointer start to look like a major luxury. There was a heroic amount of effort in those days to make due with as little memory as possible because memory was so expensive that nobody had more than was absolutely necessary.
- ghaff 2y agoYeah. I’m not going to defend x86 segment registers and real-mode DOS too vigorously. (I programmed in x86 assembler for many years.) But I’m pretty sure the right approach wasn’t to say Screw it. Let’s wait until a 32-bit flat address space processor and OS come along at the consumer and individual business user level.
- jojobas 2y agoSegment:offset addresses were still 32 bits right? And most of the arseache was from the fact that the segments were overlapping as I understand.
- skissane 2y agoYes, but if your program required no more than 64KB of data, then you could use near pointers everywhere, halving the pointer size from 4 bytes to 2 bytes. Also, even if the program as a whole required more than 64KB of data, if you knew you required no more than 64KB of data for objects of type X, then you could use 2 byte pointers for all type X objects, with a fixed data segment. X here might, for example, be strings. When you only have 256KB of RAM to begin with, the odds that all data overall, or at least all X object data for some X, will fit in 64KB is quite high. And if you have a lot of pointers, halving their size makes a big difference when you have so little memory.
- MagerValp 2y agoBut segmented memory isn’t a requirement, that technique works just as well with linear address space. You use a single 32-bit base pointer and then store 16-bit offsets for your data. We used that all the time on 68K and other architectures.
- skissane 2y agoThe difference is that 68K is designed as fundamentally a 32-bit architecture. (Even though the original implementation was physically 16-bit.) Whereas 8086 is a 16-bit architecture with an extended address space. The use of segmentation to enable a 16-bit architecture to address more than 64K was not original to the 8086, many 16-bit minicomputers (e.g. the PDP-11) used the same basic idea, although the specific implementation Intel chose was rather unique Part of why the 8086 was 16-bit not 32-bit, was to make it easier to port software to it from the 8080, which was an 8-bit architecture with 16-bit addressing. It also was likely one of the reasons why the 8086/8088 was cheaper than the 68K, which is part of why IBM chose it over the 68K for the IBM PC
- skissane 2y agoI think it was unfortunate Intel went with 16 byte paragraphs instead of 256 byte. With 256 byte paragraphs, you would have been able to address 16MB instead of 1MB in real mode.
- iforgotpassword 2y agoWhy not just the full 64k. The sliding window trick was of such limited use compared to the headaches it caused. Or maybe 32k as a compromise. But then they repeated the same mistake with the 286, again!
- skissane 2y ago> Why not just the full 64k. The sliding window trick was of such limited use compared to the headaches it caused. As I pointed out in my other comment, the full 64KB would have made it harder to support child processes under DOS. Suppose I have 300KB of free conventional memory, and run an 8KB program (something like a menu program, for example.) If it starts a child process, that child process has about 292KB of free conventional memory to use. With your idea, it could only have 236KB, because even though the parent process only needs 8KB of memory, it would consume a whole 64KB.
- banish-m4 2y agoReal mode profiling and debugging is damn easy, it's protected mode debugging that requires more work. I used Turbo Debugger for years.
- LowLevelMahn 2y agoIDA Pro disassembler fully supports 16Bit DOS executables (they only removed the support from the recent free versions - thats why most using IDA Pro Free 5.0) but Hexrays the decompiler does sadly not support 16bit code (intentionaly) but i think the Hexrays guys could do wonders here (in comparison what Ghidra is able to do)
- anthk 2y agoBochs can help there.
- LowLevelMahn 2y agohow?
- anthk 2y agoIt has a debugger.