Dan Moos wrote:
Ok, I've been slacking on the project a bit, but I'm back at it.
Hey! No goofing off around here!
Quote:
I am currently working on my monitor(although I think its going to morph into a full blown OS if I implement everything I have in mind)
Just a curmudgeonly opinion, but your M/L monitor should be a stand-alone application—running in the same ROM as the operating system, perhaps, but still separate.
The operating system and the monitor play two very different roles, as the monitor is a user application and the operating system is not. If the monitor needs an operating system service, such as getting input from the console, it should request it via a formalized API to the operating system and should not have to have any knowledge of what is going on in the operating system to make such a call. This reasoning is based on a fundamental principle of computer science, often referred to as the "Chinese wall," in which applications and the operating system remain two distinct entities and communicate only through an API. Microsoft violated that "Chinese Wall" principle when they developed Windows 95, 98 and ME (e.g., the desktop shell making direct entry into the kernel, rather than through the formal API), resulting in an unstable environment that is easily attacked by outside entities.
Quote:
I'm contemplating how to parse arguments for commands.
I can think of three strategies.
Strategy 1:
Strategy 1 is awkward and may limit the number of arguments that can be passed with commands. The problem comes with argument length, which is variable, and buffer size, which would be fixed, unless you plan to allocate buffer space on the fly (more on this below).
Quote:
Strategy 2:
I store the entire typed text in one buffer. I now have to alter my command recognition routine, so that it looks for spaces, and starts interpreting everything after a space as a new argument.
That is the basic strategy used in most shells. The shell itself parses for the command word and the code that is executed to carry out the command parses for arguments. The command word and the following arguments, if any, are separated from each other by "whitespace," which is minimally defined as a horizontal tab ($09) or a blank ($20)—other characters, such as a comma, could also be considered whitespace. The entire typed command, consisting of the command word and optional arguments, is terminated by a null so the parsing function can find the end of the character string. Your parser should also know how to deal with leading, trailing and redundant whitespace, which is trivial to implement, even in assembly language.
Quote:
Strategy 3:
I store the entire typed text in one buffer. Then, before I enter the command recognition routine, I scan the buffer for spaces, and strip out the arguments into individual buffers. I also use this opportunity to count the arguments, so that its easy to throw a "too many arguments" error, or conversely, if a command that requires arguments is typed with none, I can do the old "list the valid possibilities in a handy help screen" trick. I really like strategy 3.
That would work, but since memory is not inexhaustible, and since you don't know in advance how many arguments will be passed and how many bytes in length each argument will be, you may find yourself writing a complex memory allocation function to deal with these matters. Parsing the input buffer and passing some buffer pointers to the command execution code demands little more memory than needed by the buffer itself. At least in an M/L monitor, there is little or no need to save arguments once they have been processed. So why expend memory to store them separately from the input buffer?
Quote:
Also, instead of buffers, I was wondering if some sort of software stack for arguments would be a good way.
I don't think that would be a good strategy. A command line is a character string and hence a single data entity. In the scenario you are developing, you will read the string from left to right and process each "word" as it is encountered. That is not something that lends itself to stack storage.
On the subject of issuing commands within the M/L monitor, the classic design uses single letters to select commands, such as
A for assemble code, or
M to dump memory. Doing so
greatly simplifies parsing.