StudlyCaps wrote:@DavidCooper: Are you seriously saying that implementing a hash set or string tokenization code (as an example) is equally easy in a disassembler as in a high level language?
Clearly some things are slower. If I need to program a message to appear, I might write it as numbers, typically taking four key presses to input each letter, but I do this so rarely that speed isn't an issue, and anything that goes into a menu is now dealt with by a different method where I can simply edit the menu, typing the text straight into its class or object. I've never implemented a hash set, but if I need to, I'll write code to automate it. I now have code that lets me calculate floating point numbers and poke them into the code so that I don't have to spend ages working them out manually with a calculator. I have also automated parts of the generation of machine code numbers for some of the more complex instructions. Whenever something annoys me by being slow, I automate it, but I still write most of my machine code directly because it is no trouble to do so.
Calling a function for example requires knowing calling convention, pushing to the stack, setting up register states. This is more difficult than c = function(a,b).
You still have to know what a and b are and which order the function wants them in. What I do now though with complex programs is keep variables in places pointed at by BP so that I don't have to put them on the stack at all - I simply call a named function after pointing BP at the right variables so that the function can use that space instead of the stack. No frames, minimal copying, fully re-entrant, fast and simple. The deeper you go with such calls, the more values from BP are saved on the stack along with ret addresses, but hardly anything else ever needs to go on the stack - just the occasional value where there's no register free to hold it. I allocate very little space to stacks as a result.
It isn't impossible, and it can even be a superior tool for some tasks, but insisting that high level languages are only used out of laziness is a bizarre claim, and it flies in the face of common sense.
I don't think I've ever called it lazy - I consider my way of working to be the lazy one because I find it more comfortable to work with. Abstractions make me feel ill if they work in arbitrary ways that don't conform to natural thinking, so I prefer to work with things directly where they make immediate sense. Where something genuinely needs automating to make it easier to understand, I'm all in favour of automating it, and indeed, my aim is to automate everything to the point where complete beginners who are good at thinking logically can write faultless complex programs just by holding a conversation with a machine, but importantly, that kind of abstraction is all natural abstraction fitting in with the way people already think rather than forcing them to think in unnatural ways - things like tangles of mathematical notation are not natural, and I dislike any kind of programming system that forces people to learn to produce that kind of mess (although I have nothing against it being used by those who prefer to work that way). The main reason for me not wanting to automate things in conventional ways now though is that I want to automate them at a much higher level, and any work done to automate things in the meantime at an intermediate level will be rendered obsolete later, so it's only worth doing if it speeds up the production of the higher-level automation (that will replace it) more than it delays that production.
That said, I actually do think that as a live disassembler that you can jump into immediately is really cool, and actually pretty useful. I also think that as a tool to teach new programmers how system code works and how it comes together to form an operating system is also cool and good. I think a vital part of a CS education that gets skipped over too often these days is understanding how the machine actually interfaces with the system code, without abstraction. It seems to fall by the wayside in trying to teach "job skills" like 5 different types of milestone tracking charts.
Thanks for the positive response. Unfortunately, I still haven't got my OS into the right form for it being used seriously in education - there's a lot of redesign needed so that everything's done properly. I broke all the rules from the start because I had no knowledge of how things are normally done and no access to any such knowledge either, so there's a danger that it could teach some very bad habits. I'll get it all fixed some day, but don't have time to work on that at the moment - I need to continue building better tools first so that I can tidy up the mess in a fraction of the time it would take if I tried to do it now.
_____________________________________________________________________
MichaelFarthing wrote:The area that was much more difficult was jump calculations and one of my first enhancements was to provide an automation for calculating these. I know David also made this a priority in his own system, though he adopted a very different technique for this. The other requirement that I found was the need to use many 0x90 bytes - no operation - to allow for code correction without having to recalculate lots of existing jumps.
I automated 32-bit jumps right from the start using the indexing system, but for a long time I had to count out all the short jump distances every time and mend then all every time I moved code around (to insert new bits unto a routine or remove obsolete parts from it), but I later added an extra index to handle these short jumps too, though only storing information in it temporarily so as not to waste space on anything other than the positions of those jump instructions within 128 bytes of the location where I wanted to open up or close a gap. (Some instructions that aren't short jumps typically end up in the index too when doing this, but it's easy enough to identify them and remove them from it.)
(51 192 191 0 128 11 0 176 0 185 0 1 0 0 170 170 64 226 ...)
cmp al 192, mov di -32768, adc wrd ptr [bx+si] 176, ...
Doesn't make much coding sense
I can't read code in hex, so I'd make similar mistakes attempting to make sense of a bit of code written that way. The code here starts with an XOR that sets EAX to 0. Then DI is loaded with the first byte of screen memory (the text screen used on boot). AL is already 0, so the instruction that sets it to 0 here is completely unnecessary. ECX is set to 256 for use as a count. AL is then posted to the screen twice (by the two 170s), then EAX in incremented (by the 64), and 226 is a loop instruction. The jump size that followed it must have been 251. That routine sends the values 0 to 255 to the screen to show how they appear as char.s in text screen mode, and the colours change too as the same value is used for both the char and the colour byte.