9 ms·
Back when I was a kid, in the days before Google, you tried to figure out how things worked just by poking around your computer. For example, I noticed that pro
by codeflo 9y ago
Back when I was a kid, in the days before Google, you tried to figure out how things worked just by poking around your computer. For example, I noticed that professional programs were always .com/.exe files, but I only knew how to edit simple batch scripts. So of course, the "logical" thing to try was to write a .bat and save it with a different extension and see what happened.
.exe files created this way wouldn't launch, but a .com created this way would instantly reboot the computer. Even more weirdly, this only worked for the specific command that happened to enter in my first attempt -- it might have been something like "cd games". If I changed anything at all, it no longer worked. Only years later I realized that the characters I typed were directly executed as machine code, and that I must have stumbled upon a set of instructions that caused a CPU exception!
For several years, this weird file was the only way I knew to programmatically reboot a computer, so I renamed it "reset.com" and kept it around. I think it stopped working only in the Windows XP era when DOS programs were finally sandboxed to some extent.
- UnoriginalGuy 9y agoI'd imagine that wouldn't have worked on NT or 2000 either. You just likely jumped from the 9x series of OSs to XP which was the first one to offer "good" memory protection. Full explanation for how you could do this here[0]. It really was the wild west back when 9x was popular. I'm genuinely surprised they ran as well as they did. NT was a vast improvement. [0] https://en.wikipedia.org/wiki/Windows_9x#Kernel https://en.wikipedia.org/wiki/Windows_9x#Kernel
- dfox 9y agoWhile NT was vast improvement, the 3.1/9x was pretty significant feat of engineering and in comparison NT is "just another OS". In my opinion the lacking memory protection was not about the architecture itself but about the fact that it was meant to be single-user and thus there were no permissions. IIRC from Win32 code you had to jump though some hoops to be able to access whatever memory/hardware you wanted (ie. you could not overwrite random non-owned memory by mistake), the fact that you could do almost whatever you wanted in vm86 code was essentially an feature and that Win16 code could access any other Win16 process data was weird design decision that is also shared by all NT versions up to 2000 (where it is configurable).
- TeMPOraL 9y ago> the fact that you could do almost whatever you wanted in vm86 code was essentially an feature and that Win16 code could access any other Win16 process data was weird design decision that is also shared by all NT versions up to 2000 (where it is configurable). Hey, I actually liked that! Back when Internet was young and the OS was single-user, I felt like I had more control over my own machine than I do now. Being able to mess with other processes' memory was a feature for me :).
- deleted 9y ago[deleted]
- dfox 9y ago'cd ' diassembles into arpl [si+0x20],sp which seems like privileged instruction but actually isn't, on the other hand it is not even valid instruction in real/virtual mode and thus causes illegal instruction exception. It is interesting to note that code for the warmest of warm reboots on PC is 0xcd 0x19 (int 0x19). This jumps back into the point in BIOS code when it starts looking for the operating system to boot. Needles to say, this works reliably only in pure real mode and confuses NT's NTLDR in really interesting way (the thing was obviously originally designed to be run from DOS and contains some left over logic from that time).
- qubex 9y agoPlease expand ”confuses in a really interesting way”.
- dfox 9y agoIt produces error message along the lines of "you computer does not have enough free conventional memory to run windows NT". It is interesting that the message is actually translated into language of the NT install, says that you need 639kB of free memory for windows NT and reports whatever was the amount of free conventional memory in DOS before the "reboot" (which makes sense given the fact that at that point the original DOS is in memory in probably completely working state). Interesting about this is that there probably is not any other way to get the same message, because NTLDR actually is not valid as anything that DOS can execute (IIRC it is not MZ image and is too large to be loaded as COM).
- mycall 9y agoWouldn't something like HIMEM or QEMM run it?
- dfox 9y agoIt is designed to run in real mode. The NT bootblock probably even loads it as if it was .COM, but it is too large for DOS's .COM loader. The actual binary is concatenation of two files, there is realmode part (on XP SP3 it is 0x4cd0 bytes long, most of which are either zeros or text strings, including the aforementioned error message) and rest of the file is 32 bit PE binary, complete with "This program cannot be run in DOS mode" stub. The PE binary part is obviously somewhat special because it has to be able to switch to real or vm86 mode in order to call BIOS and run NTDETECT.COM, which is valid DOS .COM (from quick look at the code it even looks like it takes command line arguments) except the obvious fact that it does not do any DOS calls. Edit: The message in the XP's NTLDR says that it needs 512kB of conventional memory (I think that I've seen the 639kB number on NT4 or 2000) and there is also message along the lines "Windows NT needs 7MB of expanded memory", which is also somewhat interesting given that BugCheck 0x0000007D INSTALL_MORE_MEMORY is defined as "more than 5MB" and the fact that when you boot NT normally on computer with 4MB RAM you get the 0x0000007D BSOD, not the message from NTLDR.
- vram22 9y ago>a .com created this way would instantly reboot the computer. Even more weirdly, this only worked for the specific command that happened to enter in my first attempt Interesting that you did that by chance, since the probability was somewhat low. but possible, of course. I used to assemble a tiny .COM program on new computers sometimes, using just DEBUG.COM (the built-in rudimentary debugger that came with DOS), using something like the following (the dash is the DEBUG prompt): DEBUG reboot.com -A JMP F000:FFF0 -. -W -Q Meaning of the above: A to enter Assembly mode - to enter assembly language instructions, the JMP jumps to that address (Intel x86 segment:offset format), which was the location of the instruction in ROM that would reboot the PC, the dot to signal end of assembly input, W to write the code to reboot.com, Q to quit DEBUG. Then if you typed "reboot", it would.
- webtechgal 9y agoThis!! And as I recall, if we replace -W with -G (for 'go') and hit Enter, it would immediately reboot. Then, there also used to be a flag (boolean) that could be used to effect either a warm or a cold boot. Nostalgic. :-)
- vram22 9y agoI had forgotten about -G, and knew about warm and cold boot, but did not know about the flag. Cool, and nostalgic indeed :-)
- rep_movsd 9y agoOr you could just use INT 19 ; (CD 19) On my Windows 9x box it was the fastest way to soft reboot when made to be an MSDOS mode shortcut
- eriknstr 9y ago>So of course, the "logical" thing to try was to write a .bat and save it with a different extension and see what happened. Ha ha, same here. Also the next thing I did was to open exe files with notepad and conclude that this is what real code looked like and that the programmers that wrote the programs had written it that way. When a little bit later I learned that programs were written in languages like C++, I got a book about C++ while on vacation and I read a bit in that book and I wrote down the Hello World program on paper and wrote variations of it and a couple of programs that would ask questions and say something. When I got back from vacation I sat down in front of my computer, typed in hello world and used a compiler called Bloodshed C++ which the book had recommended and compiled the program and double-clicked the exe file, only to have it open a window and immediately close. I had failed to understand that I needed to run the program via cmd.exe because of course Hello World exits immediately when it's printed the text. This discouraged me a bit so I stayed away from programming languages for several years after that but at least I kept learning HTML and a bit about reverse engineering and a couple of other things and eventually I got back to programming when I started high school and we were using Texas Instruments TI-84 Plus calculators and we were given a couple of programs written in TI-BASIC which we were told to store on our calculators. Once I'd written some programs of my own in TI-BASIC I then read a book about PHP and wrote some PHP. Such was the beginning of my experience with programming.
- Sharlin 9y ago> I had failed to understand that I needed to run the program via cmd.exe because of course Hello World exits immediately when it's printed the text. And till this day, people writing command-line programs in an IDE like Visual Studio stumble on this fact, and the workaround is still the same: adding an stdin read or something like system("PAUSE") at the end, pausing the execution until the user hits Enter.
- to3m 9y agoBest solution I've found: static void PressEnter(void) { if(IsDebuggerPresent()) { fprintf(stderr,"press enter\n"); getchar(); } } Then from somewhere right near the top of main or whatever: atexit(&PressEnter); You can throw in some isatty calls, or #ifdef _CONSOLE, or if(GetConsoleWindow()), etc., but the above pretty much always does the right thing.