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

new topic     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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.

new topic     » goto parent     » topic index » view message » categorize

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.

new topic     » goto parent     » topic index » view message » categorize

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?

new topic     » goto parent     » topic index » view message » categorize

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.

new topic     » goto parent     » topic index » view message » categorize

7. Re: x86 VM

er, FFFD smile

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

11. 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:
>

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.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu