Posts Tagged ijvm
Archive: IJVM Machine Code Example
Yet another blog post from ye’ old blog.
This post was originally titled “IJVM Machine Code Example” and posted on the 8th of September, 2007
This is a little addition to my IJVM/ISA theme/posts. Now I will be going a little further into the whole Opcode part of IJVM/ISA.
First let me introduce you to a little “fun” machine code snippet (Hex representation of IJVM Machine Code):
00 01 00 00 10 ff a7 ff fe
It might not be that obvious, but this little 9 byte machine code, will actually make an endless loop, pushing fe (-1) onto the stack for each iteration. The end result will of course be a stack growing until there are no more memory.
Lets try to look at the machine code, and describe how the bytes are formatted/arranged. The first 4-bytes defines how many arguments and local variables there are. The first 2-bytes is a number representing how many arguments there are, and the next 2-bytes how many locals. In this particular case we have:
00 01 = 1 argument ; there is always the Obj-Ref/Link Pointer 00 00 = 0 locals ; the code isn't using any locals
Next we have the actual start of the code, from now on, each byte is a representation of either a Opcode, or an argument for the last Opcode. Each opcode, defines how many arguments it is taking. Here are some examples.
| Opcode | Symoblic name | Argument size | Description |
| 0×10 | BIPUSH | 1-byte |
Pushes the next 1-byte argument (representing an Integer in the range [-128, 127]) onto the stack |
| 0×59 | DUP | 0-byte |
This duplicates (copy) the top-word on the stack |
| 0xa7 | GOTO | 2-byte |
Jumps the execution to the new part in the memory. Moves the pointer relatively to the current pointer by the number of words defined in the 2-byte argument representing an integer in the range [-32.768, 32.767] |
Now lets see what the last 5-bytes of the machine code example, is actually doing.
10 ff = bipush -1 ; 10 is the opcode for bipush, and takes a 1-byte argument (ff) which is an integer representation of -1 a7 ff fe = goto -2 ; a7 is the opcode for goto, and this takes a 2-byte argument (ff fe), which is an integer representation of -2
So it pushes the number -1 onto the stack, and goes back two bytes (words). Since the pointer is at the 0xa7 instruction when executing, it will go two bytes back, to the 0×10 instruction, which again will make it push another number -1, onto the stack, and so fourth.
To execute this machine code in the IJVM Virtual Machine, you have to add some extra information though. Information of where the main method is starting, and information on the constant pool. Also remember to use UNIX formatting of the file, for example if you are using Windows to edit the files.
Now lets look at this example, wrapped with the information for the virtual machine executer.
main index: 0 method area: 9 bytes 00 01 00 00 10 ff a7 ff fe constant pool: 1 words 00000000
So that is it, for this example.
Archive: IJVM ISA Power Of Function
As mentioned earlier my old blog got wiped in a freak update of the WordPress software powering it, but luckily I have been able to salvage the database containing all my old posts. Therefore I am happy to announce that I will be re-posting those of which I was most fond and just maybe some of these old posts can be of renewed joy or use to someone else.
This first one was titled “IJVM ISA Power Of Function” and was originally posted the 2nd September, 2007
I have just returned to normal studies again, after a exam period. We have just started a course called Computers And Networks (Machine Architecture), and one of the first things we are learning, is a basic example ISA (Instruction Set Architecture) called IJVM which is a simplified Integer Java Virtual Machine.
On most modern machines, there are 6 levels (not including the device level), which are either translated to an underlying level, or interpreted (translated on the fly), until reaching level 0, which is the digital logic level, the machines actual hardware. Here is a list of the before mentioned six levels:
- Level 5 (Problem-Oriented Language Level)
- Translation (compiler)
- Level 4 (Assembly Language Level)
- Translation (assembler)
- Level 3 (Operating System Machine Level)
- Partial interpretation (operating system)
- Level 2 (ISA level)
- Interpretation (microprogram) or direct execution
- Level 1 (Micro-architecture level)
- Hardware
- Level 0 (Digital Logic Level)
When making code at the ISA level, you normally do this in Symbolic ISA, which makes it a little more human readable by replacing the instructions (op-code) which are in a word (often 8-bits/word = 1 byte/word on PCs) by a String symbol. For example the ISA instruction to pop (remove from top) two words (integers) from the stack, and push (add to the top) the sum of these back to the stack is:
Word (8bit): 10100111 Op-code (hex): 0xA7 Symbolic: IADD
In a simple ISA like the IJVM there are of course a limited number of instructions, but even with this limited list, it would be quite difficult to handle just writing code with the op-codes.
As a step in learning the IJVM ISA, I have made a little method of my own, which takes two arguments. It then calculates the first argument to the power of the second: a^b.
Here is the Symbolic ISA code for this method (it can only handle positive powers as of so far). This is as an example of what IJVM ISA code looks like.
.method main .args 3 .define a = 1 .define b = 2 iload a iload b invokevirtual pwr // pwr( int a, int b) ireturn .method pwr .args 3 .define a = 1 .define b = 2 iload a iload b bipush 0x01 isub // b - 1 while: bipush 0x01 isub // b - 1 dup // dup b iflt end_while swap dup // dup a iadd // a + a swap goto while end_while: pop ireturn
And here is the assembled ISA code:
main index: 0 method area: 39 bytes 00 03 00 00 15 01 15 02 b6 00 01 ac 00 03 00 00 15 01 15 02 10 01 64 10 01 64 59 9b 00 0a 5f 59 60 5f a7 ff f5 57 ac constant pool: 2 words 00000000 0000000c
Facebook
Twitter
Youtube
Last
Ping