1. x86 VM
Hi,
I'm writing a VM in Euphoria right now. It's totally portable because all
it does is parse opcodes and call the corresponding Euphoria routines(it
buils a list of x86 opcodes and routine ID's). I just ran into a little
problem, the JMP NEAR instruction isn't working quite as I expected it to.
Some programs will work, but others will not. Maybe someone would be kind
enough to look at my code, see what I'm doing wrong?
- Matt
2. Re: x86 VM
If you want you can email me a copy and ill take a look at it.
I can't promise anything, but i have worked extensively with
assembly code. If i can spot something ill gladly inform you.
--Al
3. Re: x86 VM
Before I send it, you should know a little something about the VM's(86VM)
innards.
* The file vm_codes.e is included, and each opcode is registered(opcodes
can be 1 to 2 bytes long).
* 86VM loads the program into VM memory so the program may read any data
in the file.
* 86VM reads in a .COM file(.EXEs and files above 64K are not allowed),
gets a character, looks for it in the x86 opcode table. If it's found,
it reads another character and checks all the 2-byte codes in the opcode
table. If a corresponding 2-byte code is not found, it's obviously 1
byte.
* If the opcode has been identified, it adds the corresponding routine ID,
the parameters(as defined in the sequence 'read_param_method')(each
parameter may be a byte or word), and the size of the x86 opcode and
its arguments. The position in the file and in the code sequence is
stored in a sequence called 'IP'
* If not, it immediately stops processing opcodes.
* When it's done processing, the IP register is read(it starts at 0).
86VM will read IP, and it searches for it in IP[x][1]. If it is found,
it a variable called x to 1. If it is not found, 86VM bombs out with an
error. Otherwise, the opcode's routine ID is executed and set to the
position in the file it found.
When JMP NEAR and JMP SHORT execute, they get the current memory location
of the current IP and convert the parameter into a signed offset. Then,
the offset is added to the IP, it makes an index from the code sequence,
and sets the IP.
Just about every .COM program ever written would work perfectly if these
near and short jumps would work!
P.S. Far jumps trigger a segment violation because segments haven't been
implemented yet. In fact, I'm thinking about creating another VM(86VM-
based of course) for some non-existent 32-bit segmentless platform.
4. Re: x86 VM
>When JMP NEAR and JMP SHORT execute, they get the current memory location
>of the current IP and convert the parameter into a signed offset. Then,
>the offset is added to the IP, it makes an index from the code sequence,
>and sets the IP.
JMP SHORT = jump relative, displacement relative to next instruction.
JMP NEAR = jump absolute indirect, address given in r/m.
So your JMP NEAR code needs to be fixed to use absolute addressing instead
of relative addressing.
_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.
Share information about yourself, create your own public profile at
http://profiles.msn.com.
5. Re: x86 VM
Ahh. Well if that's the case, then if not short and not near, what are all
my assembly programs using?
6. Re: x86 VM
Hold it!
If you go into DEBUG and use the 'A' command(rest assured, debug is NOT my
assembler), type 'JMP NEAR 100' and press enter twice, then use the 'U'
command, you get something like this:
20B4:0100 E9FDFF JMP 0100
20B4:0103 F8 CLC
20B4:0104 1910 SBB [BX+SI],DX
20B4:0106 4F DEC DI
20B4:0107 0E PUSH CS
20B4:0108 0000 ADD [BX+SI],AL
20B4:010A 10EF ADC BH,CH
20B4:010C 00F0 ADD AL,DH
20B4:010E 46 INC SI
20B4:010F 32B210B2 XOR DH,[BP+SI+B210]
20B4:0113 034F0E ADD CX,[BX+0E]
20B4:0116 2D2F00 SUB AX,002F
20B4:0119 FD STD
20B4:011A 46 INC SI
20B4:011B 36 SS:
20B4:011C 99 CWD
20B4:011D 00A3201E ADD [BP+DI+1E20],AH
If JMP NEAR executes like you did, this would jumo ti 20B4:FDFF instead of
20B4:100.
8. Re: x86 VM
On Sat, 11 Nov 2000 08:29:28 -0500, Darth Maul, aka Matt
<uglyfish87 at HOTMAIL.COM> wrote:
>Hold it!
>If you go into DEBUG and use the 'A' command(rest assured, debug is NOT my
>assembler), type 'JMP NEAR 100' and press enter twice, then use the 'U'
>command, you get something like this:
>
>20B4:0100 E9FDFF JMP 0100
>If JMP NEAR executes like you did, this would jumo ti 20B4:FDFF instead of
>20B4:100.
Matt:
I think you are being confused by debug.
First the opcode EB means jump short rel 8
The opcode E9 means jump near rel 16
The opcode FF means jump near indirect
etc.
When you use debug use A0:0 to assemble at 0000:0000 address
this eliminates the confusion of the offsets.
Also if you do a jump 100 that is greater than 8 bits and
debug generate a E9 rel 16. Try assembling jump 7F and
it will generate a EB rel 8 then look at that output
and you see a different type of jump.
The difference is that you are not looking at the way
an instruction is formed only at the way you think it should
jump. I think that you will have to look at how the complete
instruction is decoded before you will understand what you
are looking at.
Bernie
9. Re: x86 VM
Then would you mind explaining why NASM generates code for a relative jump(
near)?
Here's some assembly code:
Jmp lbl
Jmp short lbl
lbl:
And here's NDISASM's output:
[WINDOWS] C:\EUPHORIA>ndisasm test
00000000 E90200 jmp 0x5
00000003 EB00 jmp short 0x5
10. Re: x86 VM
On Sat, 11 Nov 2000 12:50:02 -0500, Darth Maul, aka Matt
<uglyfish87 at HOTMAIL.COM> wrote:
>Then would you mind explaining why NASM generates code for a relative jump(
>near)?
>
>Here's some assembly code:
>
>Jmp lbl
>Jmp short lbl
>lbl:
>
>And here's NDISASM's output:
>
>[WINDOWS] C:\EUPHORIA>ndisasm test
>00000000 E90200 jmp 0x5
>00000003 EB00 jmp short 0x5
First debug can not be told to use a certain instruction
so it can not be used for comparison. The above code really
would not be logical because the second instruction wouldn't
be executed, but I know what you are getting at in
your example.
The first instruction uses a E9 jmp RELATIVE 16 and the 16 bit
address following E9 is the NUMBER of bytes to junp.
Because 0200 is BYTE SWAPPED so it represents 2 BYTES ( 0002 ).
The PROGRAM COUNTER ALWAYS point to the next INSTRUCTION to be
EXECUTED which is ADDRESS 0003. The 2 byte RELATIVE offset is ADDED
to the PROGRAM COUNTER which advances to the NEXT instruction to
be executed.
The second instruction EB jmp RELATIVE 8 will ADD a RELATIVE offset
of 00 to the PROGRAM COUNTER because REMEMBER it is already pointing
to ADDRESS 5.
Take a look at the pete's ASM.E because it ENCODES instructions and
it might help to write your code.
Bernie
be ADDRESS 5.
In the second instr
11. Re: x86 VM
- Posted by mic _ <stabmaster_ at hotmail.com>
Nov 11, 2000
-
Last edited Nov 12, 2000
>Then would you mind explaining why NASM generates code for a relative jump(
>near)?
>
>Here's some assembly code:
>
>Jmp lbl
>Jmp short lbl
>lbl:
>
I have to correct myself on my last post. Near jumps *can* use relative
displacements.
"Jmp lbl" is likely to be translated into relative jump.
Here's some info from an Intel hlp-file:
EB cb JMP rel8 Jump short, relative, displacement relative to next
instruction
E9 cw JMP rel16 Jump near, relative, displacement relative to next
instruction
E9 cd JMP rel32 Jump near, relative, displacement relative to next
instruction
FF /4 JMP r/m16 Jump near, absolute indirect, address given in r/m16
FF /4 JMP r/m32 Jump near, absolute indirect, address given in r/m32
EA cd JMP ptr16:16 Jump far, absolute, address given in operand
EA cp JMP ptr16:32 Jump far, absolute, address given in operand
FF /5 JMP m16:16 Jump far, absolute indirect, address given in m16:16
FF /5 JMP m16:32 Jump far, absolute indirect, address given in m16:32
_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.
Share information about yourself, create your own public profile at
http://profiles.msn.com.