diff --git a/asm.jrt b/asm.jrt index f52c87d..4bbdee9 100755 --- a/asm.jrt +++ b/asm.jrt @@ -6,6 +6,8 @@ var target var op-encode var lastop +var is-byteptr : byteptr 1 is-byteptr ! ; + var current-oparg var opargs-remaining array oparg1 3 cells allot @@ -35,7 +37,8 @@ array oparg2 3 cells allot ( ie. inc [bx] vs inc byte [bx]?? ) ( or do we just say incb? ) -: bytearg? ( -- f ) oparg-breg? swap-args oparg-breg? or swap-args ; +: byteop? ( -- f ) + oparg-breg? swap-args oparg-breg? or swap-args is-byteptr @ or ; : byteval? ( v -- f ) 0xff00 & dup 0xff00 = swap 0 = or ; : operror ( err -- ) lastop @ wordname type s" : " type type cr ; @@ -79,6 +82,7 @@ array oparg2 3 cells allot 0x25 reg es 0x27 reg ss 0x2d reg cs 0x2f reg ds : start-op ( does-ptr argcount -- ) + 0 is-byteptr ! opargs-remaining @ if s" not enough arguments" operror then opargs-remaining ! cell - lastop ! arg1 ; : prefix create , does> @ >t ; @@ -118,16 +122,16 @@ array oparg2 3 cells allot ( convention: words ending in * mean "will return if matched" ) : disp>t oparg-val @ memarg>dispsize dup 1 = if drop >t else 2 = if w>t else drop then then ; -: imm?>t oparg-imm? if oparg-val @ dup byteval? if >t else w>t then then ; +: imm?>t oparg-imm? if oparg-val @ byteop? if >t else w>t then then ; : >wreg+op* ( base -- ) oparg-wreg? if oparg-val @ | >t rdrop else drop then ; : >segreg+op* ( off -- ) oparg-segreg? if oparg-val @ 0x0f & 1 << + >t rdrop else drop then ; -: >mem* ( reg op -- ) - oparg-mem? if - >t memarg>mod+rm modrm>t disp>t swap-args imm?>t rdrop - else 2drop then ; +: >mem ( reg op -- ) >t memarg>mod+rm modrm>t disp>t swap-args imm?>t ; +: >mem* oparg-mem? byteop? not and if >mem rdrop else 2drop then ; +: >bmem* oparg-mem? byteop? and if >mem rdrop else 2drop then ; + : >regreg ( reg op -- ) >t regarg>mod+rm modrm>t ; : >byte-regreg* ( reg op -- ) oparg-breg? if >regreg rdrop else 2drop then ; : >regreg* ( reg op -- ) oparg-wreg? if >regreg rdrop else 2drop then ; @@ -158,9 +162,47 @@ array oparg2 3 cells allot 1 0xfe >byte-regreg* 1 0xff >regreg* 0 0xff >mem* + 1 0xfe >bmem* invalid-args ; -1 :op decb - 1 0xfe >byte-regreg* - 1 0xfe >mem* - invalid-args ; +1 :op int + oparg-imm? if oparg-val @ dup 3 = if drop 0xcc t> else 0xcd t> t> then + else invalid-args then ; +: diffaddr ( addr opsize -- diff ) target @ + - ; +: >short-jmp* ( op -- ) oparg-type @ 3 = if oparg-base @ -1 = if + oparg-val @ 2 diffaddr dup byteval? if swap >t >t rdrop return else drop + then then then drop ; + +1 :op jo 0x70 >short-jmp* invalid-args ; +1 :op jno 0x71 >short-jmp* invalid-args ; +1 :op jb 0x72 >short-jmp* invalid-args ; +1 :op jnb 0x73 >short-jmp* invalid-args ; +1 :op jz 0x74 >short-jmp* invalid-args ; +1 :op jnz 0x75 >short-jmp* invalid-args ; +1 :op jbe 0x76 >short-jmp* invalid-args ; +1 :op ja 0x77 >short-jmp* invalid-args ; +1 :op js 0x78 >short-jmp* invalid-args ; +1 :op jns 0x79 >short-jmp* invalid-args ; +1 :op jpe 0x7a >short-jmp* invalid-args ; +1 :op jpo 0x7b >short-jmp* invalid-args ; +1 :op jl 0x7c >short-jmp* invalid-args ; +1 :op jge 0x7d >short-jmp* invalid-args ; +1 :op jle 0x7e >short-jmp* invalid-args ; +1 :op jg 0x7f >short-jmp* invalid-args ; +1 :op loopnz 0xe0 >short-jmp* invalid-args ; +1 :op loopz 0xe1 >short-jmp* invalid-args ; +1 :op loop 0xe2 >short-jmp* invalid-args ; +1 :op jcxz 0xe3 >short-jmp* invalid-args ; + +2 :op xchg + arg2 oparg-reg? oparg-val @ 0x00 = arg1 oparg-wreg? and + if 0x90 >wreg+op* then + invalid-args ; +2 :op mov + arg2 oparg-imm? arg1 if + oparg-wreg? if oparg-val @ 0xb8 | >t arg2 oparg-val @ w>t return then + oparg-breg? if oparg-val @ 0x0f & 0xb0 | >t arg2 oparg-val @ >t return then + 0 0xc6 >bmem* + 0 0xc7 >mem* + then + invalid-args ;