(Machine-Language Programming) Let’s create a computer called the Simpletron. As its name implies, it’s a simple machine, but powerful. The Simpletron runs programs written in the only language it directly understands: Simpletron Machine Language (SML).
The Simpletron contains an accumulator—a special register in which information is put before the Simpletron uses that information in calculations or examines it in various ways. All the information in the Simpletron is handled in terms of words. A word is a signed four-digit decimal number, such as +3364, -1293, +0007 and -0001. The Simpletron is equipped with a 100-word memory, and these words are referenced by their location numbers 00, 01, …, 99.
Before running an SML program, we must load, or place, the program into memory. The first instruction (or statement) of every SML program is always placed in location 00. The simulator will start executing at this location.
Each instruction written in SML occupies one word of the Simpletron’s memory (so instructions are signed four-digit decimal numbers). We shall assume that the sign of an SML instruction is always plus, but the sign of a data word may be either plus or minus. Each location in the Simpletron’s memory may contain an instruction, a data value used by a program or an unused (and so undefined) área of memory. The first two digits of each SML instruction are the operation code specifying the operation to be performed. SML operation codes are:
Operation code Meaning Input/output operations: final int READ = 10; Read a word from the keyboard into a specific location in memory. final int WRITE = 11; Write a word from a specific location in memory to the screen. Load/store operations: final int LOAD = 20; Load a word from a specific location in memory into the accumulator. final int STORE = 21; Store a word from the accumulator into a specific location in memory. Arithmetic operations: final int ADD = 30; Add a word from a specific location in memory to the word in the accumulator (leave the result in the accumulator). final int SUBTRACT = 31; Subtract a word from a specific location in memory from the word in the accumulator (leave the result in the accumulator). final int DIVIDE = 32; Divide a word from a specific location in memory into the word in the accumulator (leave result in the accumulator). final int MULTIPLY = 33; Multiply a word from a specific location in memory by the word in the accumulator (leave the result in the accumulator). Transfer-of-control operations: final int BRANCH = 40; Branch to a specific location in memory. final int BRANCHNEG = 41; Branch to a specific location in memory if the accumulator is negative. final int BRANCHZERO = 42; Branch to a specific location in memory if the accumulator is zero. final int HALT = 43; Halt. The program has completed its task.
The last two digits of an SML instruction are the operand—the address of the memory location containing the word to which the operation applies. Let’s consider several simple SML programs.
The first SML program reads two numbers from the keyboard and computes and displays their sum;
Location Number Instruction 00 +1007 (Read A) 01 +1008 (Read B) 02 +2007 (Load A) 03 +3008 (Add B) 04 +2109 (Store C)
The instruction +1007 reads the first number from the keyboard and places it into location 07 (which has been initialized to 0). Then instruction +1008 reads the next number into location 08. The load instruction, +2007, puts the first number into the accumulator, and the add instruction, +3008, adds the second number to the number in the accumulator. All SML arithmetic instructions leave their results in the accumulator. The store instruction, +2109, places the result back into memory location 09, from which the write instruction, +1109, takes the number and displays it (as a signed four-digit decimal number). The halt instruction, +4300, terminates execution.
The second SML program reads two numbers from the keyboard and determines and displays the larger value. Note the use of the instruction +4107 as a conditional transfer of control, much the same as Java’s if statement.
Location Number Instruction 00 +1009 (Read A) 01 +1010 (Read B) 02 +2009 (Load A) 03 +3110 (Subtract B) 04 +4107 (Branch negative to 07) 05 +1109 (Write A) 06 +4300 (Halt) 07 +1110 (Write B) 08 +4300 (Halt) 09 +0000 (Variable A) 10 +0000 (Variable B)
I thought that too Liutauras! A good and interesting task for me to learn new things...Liutauras Vilda wrote:This sounds like a very interesting programming task.
I thought on posting the first 2 because they are connected with each other. But will do like you asked Junilu.Junilu Lacar wrote:This one exercise is enough to make this a very long thread. I suggest you focus on this problem first. If you're going to post the second exercise, please do it in a different thread.
Although i never ever tried to learn assembly, i already had the curiosity about how things are done inside the processor so i've allready read before about registers (EAX, EBX, and so on) and opcodes. It's not easy to understand (at least for me) how all things are processed internaly by the processor, but i got a slight view on them.Junilu Lacar wrote:This first exercise will be easier for you to understand if you have some idea of how programs work at a very low level. Registers and opcodes (short for operation codes) are terms that are directly related to the internals of a computer and are about as close as you'll get to actually working directly with its hardware. Registers are the heart of a CPU and opcodes form the instruction set that it recognizes.
Search for assembly language instructions to see examples of real assembly language programs. Some of the links that search brings will have diagrams that help you visualize what registers are, what they're for, and how they work.
Never did an UML diagram. Read about it but never really used it. And i have a little problem with that because i can't install programs here were i'm working. So does anyone know a portable version of an UML program?Liutauras Vilda wrote:I encourage you as one of the starting points to draw an UML class diagram in order to get an idea what you're most likely going to deal with.
I started to think about it already. To be honest since this exercise is about processing SML, i thought that one class would be enough and it could be called SMLProcessor. In the second exercise there will be more: the Simpletron computer itself and a SML loader at least.Liutauras Vilda wrote:In order to get that, you'll need probably to accomplish step 1 and step 2 from below.
1. Think what classes you may need to represent the Simpletron and its components. To identify classes look for the nouns in text, i.e.: Machine, Instruction, ... look for other (notice I started class names with an upper case, this is how class names supposed to start in Java, but I presume you know that already).
1.1. When thinking about the instructions, think what all instructions may have in common, so you may want to make one as a generalised and other instructions to derive from it, where each of it does some certain operation.
2. Similarly think about the verbs, which should represent your methods/operations your classes/objects do. i.e.: perform/execute instruction... look for other (I took randomly first verb I noticed, it may or may not relevant, that is for you to workout).
More than enough...Liutauras Vilda wrote:Is it enough to start thinking where you may start?
Pencil and piece of paper....i can't install programs here... So does anyone know a portable version of an UML program?
Carlos Reves wrote:I've been trying to get some UML done... So far i have this:
Class Diagram
Junilu Lacar wrote:Search for assembly language instructions to see examples of real assembly language programs. Some of the links that search brings will have diagrams that help you visualize what registers are, what they're for, and how they work.
Junilu Lacar wrote:So you went ahead and coded up the second exercise without trying to write the Simpletron assembly language programs required by the first exercise? I thought that was what your text files would be but I guess not. You'd have three more text files if you complete exercise 1.
Carlos Reves wrote:But there were many question being made about why the news of those registers for example
Director (e.g., the OS kernel): SimpleTron, use this Loader to initialize yourself with a new program.
SimpleTron: Ok. Hey, Loader, do you have another instruction?
Loader: Yes... (or if No, we're done)
SimpleTron: Ok, let me check if I can still take on more instructions...
(errors out if no capacity to take more instructions)
SimpleTron: Ok, I'm still good. Loader, give me your next instruction.
Loader: Here you go.
SimpleTron: (takes instruction and puts it in the next open address in memory)
(repeat from step where SimpleTron asks Loader if it has more instructions)
Thanks Junilu. I just realised it's very pleasant when you don't have remarks on my code... Not even in the variable names...Junilu Lacar wrote:1. I don't see much of a need to comment your code. It is pretty well-written and self-documenting. Good job on that.
I get what you are saying after your post next to this one. I'm still fiding it hard to think in an object oriented way... My earlier diagram shows that clearly i think. I'll take a look at your examples and your explanation on the "conversation" between objects to see if i can improve my way of thinking about these things.Junilu Lacar wrote:2. I think you may have gone a bit too far with externalizing the memory array but it's not too bad right now that it can't be fixed.
I was just refering to this post by Liutauras:Junilu Lacar wrote:
Carlos Reves wrote:But there were many question being made about why the news of those registers for example
I don't get what you mean by that.
I just went with all those registers and those names because they are the exercise specifications.Liutauras Vilda wrote:When I said you most likely over-complicated some parts in diagram, particularly I had in my mind at that time - SimpletronRegisters.
Now think for a moment:
1. Do the registers really maintain the counter of the instructions?
2. Do the registers really need to know operation code?
3. Do the registers need to know operands?
4. Do the registers do all those operations?
I won't give you a last question I'm holding in my mind at the moment as it would become obvious, that is for you to think for a moment.
Carlos Reves wrote:
Thanks Junilu. I just realised it's very pleasant when you don't have remarks on my code... Not even in the variable names...Junilu Lacar wrote:1. I don't see much of a need to comment your code. It is pretty well-written and self-documenting. Good job on that.
Right... Won't be! But still it's good!Junilu Lacar wrote:
Carlos Reves wrote:
Thanks Junilu. I just realised it's very pleasant when you don't have remarks on my code... Not even in the variable names...Junilu Lacar wrote:1. I don't see much of a need to comment your code. It is pretty well-written and self-documenting. Good job on that.
Well, don't get too cocky, now. It's still early.
Here is the program in SML:Use a sentinel-controlled loop to read 10 positive numbers. Compute and display their sum.
Location | Instruction | Comments |
---|---|---|
00 | 1009 | Read an integer |
01 | 2009 | Load the integer to accumulator |
02 | 4207 | Sentinel can be zero, so branch to end the loop if it's entered |
03 | 4107 | Sentinel can also be a negative number |
04 | 3010 | Add the number to the sum |
05 | 2110 | Store the sum |
06 | 4000 | Repeat process |
07 | 1110 | Write the sum |
08 | 4300 | End the program |
09 | 0000 | Location for input integer |
10 | 0000 | Location for sum |
Here it is:Use a counter-controlled loop to read seven numbers, some positive and some negative, and compute and display their average.
Location | Instruction | Comments |
---|---|---|
00 | 2016 | Load initial counter to accumulator |
01 | 2118 | Store current counter value |
02 | 1019 | Read an integer |
03 | 2019 | Load integer to accumulator |
04 | 3020 | Add the number to the sum |
05 | 2120 | Store the sum |
06 | 2018 | Load current counter to accumulator |
07 | 3117 | Decrement counter |
08 | 4211 | If counter == 0 end loop |
09 | 2118 | Store current counter value |
10 | 4002 | Repeat the process |
11 | 2020 | Load the sum to accumulator |
12 | 3216 | Divide the sum by the count of numbers entered |
13 | 2121 | Store the average of the numbers |
14 | 1121 | Write the average |
15 | 4300 | End program |
16 | 0007 | Initial value for counter |
17 | 0001 | Counter decrement |
18 | 0000 | Location for current counter |
19 | 0000 | Location for input integer |
20 | 0000 | Location for sum |
21 | 0000 | Location for average |
Junilu Lacar wrote:That first requirement to "use a sentinel-controlled loop to read 10 positive numbers" seems ambiguous to me. If it's a purely sentinel-controlled loop, then there's no telling how many valid positive numbers will be entered before a sentinel value is entered. It could be less than 10, or 10, or more than 10. So, are you supposed to mix the logic, watch for a sentinel but don't terminate until the user has entered exactly 10 positive numbers? Of do you just trust the user to enter 10 positive numbers and then a sentinel value?
Thanks. But honestly didn't use a true sentinel value. With the current limited capabilities of the SML there is no way to "inform" the user about the sentinel value. So i used the <=0 values as sentinels since we want to sum only positive integers.Junilu Lacar wrote:Aside from the ambiguity in the first program requirements, those SML programs look pretty good to me.
Carlos Reves wrote:But honestly didn't use a true sentinel value. With the current limited capabilities of the SML there is no way to "inform" the user about the sentinel value. So i used the <=0 values as sentinels since we want to sum only positive integers.
All things are lawful, but not all things are profitable.
Knute Snortum wrote:I suspect you will have problems with this code in SMLProcessor.java:
I think the second time you will not be able to open System.in again. Two things I would recommend: Open a Scanner object only once and don't close it. Your IDE may complain of a resource leak, but you can ignore this.
Junilu Lacar wrote:What's more, hard-coding it to a Scanner that's associated with System.in severely limits your ability to test. If this code were instead just programmed to a Scanner and didn't care where the Scanner was getting input, you could plug in a Scanner that was reading from non-interactive sources and you could run tests much faster.
Junilu Lacar wrote:That first requirement to "use a sentinel-controlled loop to read 10 positive numbers" seems ambiguous to me. If it's a purely sentinel-controlled loop, then there's no telling how many valid positive numbers will be entered before a sentinel value is entered. It could be less than 10, or 10, or more than 10. So, are you supposed to mix the logic, watch for a sentinel but don't terminate until the user has entered exactly 10 positive numbers? Of do you just trust the user to enter 10 positive numbers and then a sentinel value?
Junilu Lacar wrote:No, that would be a counter-controlled loop. I think specifying 10 integers to be entered for a sentinel-controlled loop was a mistake that the authors and editors overlooked.
Junilu Lacar wrote:Regarding the scanner, no, you wouldn't even create the Scanner in the class that uses it, you'd have it provided from outside, either as a parameter to the constructor or via a setter. Your Scanner basically becomes a field. Read about dependency injection.
Read a series of numbers, and determine and display the largest number. The first number read indicates how many numbers should be processed.
Location | Instruction | Comments |
---|---|---|
00 | 1016 | Input the total number of integers (counter) |
01 | 1017 | Input an integer |
02 | 2018 | Load maximum to accumulator |
03 | 3117 | Subtract the entered number |
04 | 4110 | If result < 0 goto 10 |
05 | 2016 | Load counter to accumulator |
06 | 3115 | Decrement counter |
07 | 4213 | If counter == 0 end loop and goto 13 |
08 | 2116 | Store the counter |
09 | 4001 | Repeat input process |
10 | 2017 | Load input integer to accumulator |
11 | 2118 | Store it as new maximum |
12 | 4005 | Goto 05 to decrement counter |
13 | 1118 | Write the maximum |
14 | 4300 | End Program |
15 | 0001 | Counter decrement value |
16 | 0000 | Location for counter |
17 | 0000 | Location for input integer |
18 | 0000 | Location for maximum |
Would anybody like some fudge? I made it an hour ago. And it goes well with a tiny ad ...
Smokeless wood heat with a rocket mass heater
https://woodheat.net
|