This tutorial is intended to follow the tutorial on assembly language branching.
The IJVM instruction set includes two instructions to provide character input and output: IN and OUT, respectively. The IN instruction reads the first character from the input buffer, converts it to an unsigned integer value (the low-order 8-bits store the character value), and pushes it onto the stack. If there is nothing in the input buffer then a value of zero is pushed onto the stack. The OUT instruction pops the top element from the stack, extracts the low-order byte, and writes that byte to the input/output window as character data.
1. Clear
the memory of the computer (Memory menu; Clear Memory).
2. If
necessary, clear the source code editor (Source menu, Clear
Source Code).
3. Enter
the following assembly language program using the source code editor. This
program displays a menu with two options ("Uppercase" and "Lowercase"), displays
a prompt for input, and waits for the user to enter a single character response.
If the user types 'u' or 'U' then the text "IJVM" will be sent to the
input/output window. If the user types 'l' or 'L' then the text "ijvm" will be
sent to the input/output window. Otherwise, the text "ERROR" will be displayed.
Note: This is a long program but it is highly repetitive so make good use of copy and paste.
.constant NEWLINE 10 .end-constant .main .var option .end-var // Display the menu and user prompt bipush 'U' out bipush 'p' out bipush 'p' out bipush 'e' out bipush 'r' out bipush 'c' out bipush 'a' out bipush 's' out bipush 'e' out ldc_w NEWLINE out bipush 'L' out bipush 'o' out bipush 'w' out bipush 'e' out bipush 'r' out bipush 'c' out bipush 'a' out bipush 's' out bipush 'e' out ldc_w NEWLINE out ldc_w NEWLINE out bipush 'C' out bipush 'h' out bipush 'o' out bipush 'i' out bipush 'c' out bipush 'e' out bipush '(' out bipush 'U' out bipush ' ' out bipush 'o' out bipush 'r' out bipush ' ' out bipush 'L' out bipush ')' out bipush '?' out bipush ' ' out // Get a keystroke from the user top: in // Push character (or zero) onto the stack dup // Duplicate the character value on the stack ifeq clear // If character = 0 then branch to clear goto end // Otherwise, branch to the end of loop clear: pop // Clear the stack goto top // Branch back to the top of the loop end: istore option // Echo the user's keystroke to the output window iload option out ldc_w NEWLINE out // Perform the indicated operation iload option // if (option == 'u') goto uppercase bipush 'u' if_icmpeq uppercase iload option // else if (option == 'U') goto uppercase bipush 'U' if_icmpeq uppercase iload option // else if (option == 'l') goto lowercase bipush 'l' if_icmpeq lowercase iload option // else if (option == 'L') goto lowercase bipush 'L' if_icmpeq lowercase err // else error uppercase: bipush 'I' out bipush 'J' out bipush 'V' out bipush 'M' out goto halt lowercase: bipush 'i' out bipush 'j' out bipush 'v' out bipush 'm' out halt: halt .end-main
4.
Assemble the program (tap the F2 function key). If you do not want to
save this program, just click the Cancel button in the file save dialog;
the machine language code will still be loaded into memory.
5. Check
the Single-Step through IJVM Code checkbox below the input/output window.
6. Click
the Reset button.
7.
Click the Display Words button below the memory display.
8.
Click the IJVM Step button two (2) times to allow the machine language interpreter to perform its start-up
routine.
Note: Be very careful as you complete the steps below. It is easy to get out of sync with the instructions.
9. The
first 74 statements display the menu and the user prompt. You could single-step
through these instructions, but there may be a better way. Make sure that the
checkboxes that disable animation are unchecked. We want to slow the simulator
down. What you want to do is click the Run button and then click
the Break button (its the same button with a different label) when
this section of code has almost been executed. I suggest you click the Break
button when you see the prompt being displayed in the input/output window. Then,
click the IJVM Step button until you have executed the final OUT
instruction: "113: OUT". The last
character sent to the input/window is the blank space that follows the '?' and
separates the prompt from the user's response. The input/output window looks
like this:
10. This
section of code begins with a loop that waits until the user has entered a
keystroke. The keystroke entered by the user will be stored in the variable
"option". Click the Goto SP button and confirm that the top of the
stack is at 4096. (The 32 at address 4097 is the character code for the blank
space that was just sent to the input/output window.)
11. Click
the IJVM Step button. Since the input buffer is empty, IN pushes a
value of 0 onto the stack:
12. Click
the IJVM Step button. This value is duplicated on the stack.
13. Click
the IJVM Step button. The IFEQ instruction has just been executed.
Since the Z flag is 1, the branch to address 122 succeeds (the next instruction
is "122: POP"). The value originally
returned by IN is, once again, on the top of the stack:
14. Click
the IJVM Step button. The POP instruction removes the value
returned by the previous IN instruction in preparation for going back to the top
of the loop.
15. Click
the IJVM Step button. The unconditional branch takes us back up to
the top of the loop at byte-address 114.
16.
Click anywhere in the input/output window. The
input/output window is implemented as a JTextArea and it must
have the focus in order to receive input. Clicking anywhere within the window
gives it the focus.
17. Type
the letter 'u' on the keyboard.
18. Click
the IJVM Step button. The character code for 'u' is pushed onto
the stack by the IN instruction:
19. Click
the IJVM Step button. This character code is duplicated on the
stack:
20. Click
the IJVM Step button. Since the Z flag is 0, the IFEQ branch to
122 fails (the next instruction is "119: GOTO 126"). The code originally
returned by IN is, once again, on top of the stack:
21. Click
the IJVM Step button. The unconditional GOTO takes us out of the
loop.
22. Click
the IJVM Step button. The keystroke entered by the user is popped
from the stack (SP is back to 4096) and copied to the variable "option" (offset
0 from LV):
23. Click
the IJVM Step button four (4) times. These four instructions
output the keystroke entered by the user and a new-line character:
24. Click
the IJVM Step button. The option selected by the user is pushed
onto the stack:
25. Click
the IJVM Step button. The code for 'u' is pushed onto the stack:
26. Click
the IJVM Step button. The top two values are popped from the stack
and compared (the difference is calculated in the ALU). Since the top two values
were equal, the IF_ICMPEQ branch to 164 succeeds (the next
instruction is "164: BIPUSH 73").
If you look, you will notice that the branch succeeded even though Z is not
equal to 1. Actually, Z was 1 but the machine language interpreter has already
begun the process of reading the next byte from the program by
incrementing the PC register. See the section on single-stepping through a
machine language program in the overview for more
details.
27. Click
the IJVM Step button until the program terminates (i.e., until the
HALT instruction is executed). The uppercase letters "IJVM" are sent to the
input/output window:
28. Rerun
the program (Click Reset and then Run) several times
with different keystrokes until you are convinced that the program works
correctly. When you click the Run button, the input/output window
automatically gets the focus and it should not be necessary to click on the
window before entering your keystroke (unless, of course you have clicked on
some other interface component first).
The next tutorial covers assembly language methods.