miniasm32.as [ミニアセンブラモジュール]

;*********************************************************************************
; Mini Assembler module Ver1.0a  [2007.09.23]
; アセンブリ言語のマシン語を指定されたポインタ上のメモリに書き込む
;  Programmed in HSP Ver3.1 ONION software (http://hsp.tv/)
;   Copyright (C) 2007 by abo, all rights reserved.
;*********************************************************************************
/*
    xdim        p1,p2
    asmlist p1,"string"
    asm p1,{"
        ORG     0
        MOV     ECX,[ESP+04]    ; varptr(p1)
        RDTSC                   ; EDX,EAX <- TSC
        MOV     [ECX],EAX       ; data(0) <- EAX
        MOV     [ECX+04],EDX    ; data(1) <- EDX
        RET
        END
    "}
 */

#ifdef __hsp30__
#ifndef __MINIASM32__
#define global __MINIASM32__

#module "miniasm32"

#define EAX     0
#define ECX     1
#define EDX     2
#define EBX     3
#define ESP     4
#define EBP     5
#define ESI     6
#define EDI     7

#define AX      0
#define CX      1
#define DX      2
#define BX      3
#define SP      4
#define BP      5
#define SI      6
#define DI      7

#define AL      0
#define CL      1
#define DL      2
#define BL      3
#define AH      4
#define CH      5
#define DH      6
#define BH      7

#define ErrSyntax   1
#define ErrMnemonic 2
#define ErrOperand  3

;--------+---------+---------+---------+---------+---------+---------+---------+
; アセンブラオプション
;--------+---------+---------+---------+---------+---------+---------+---------+
#define global asmlist(%1=1,%2="") _asmlist %1,%2
#deffunc _asmlist int p1, str p2
    ListSw=p1 : AsmMemory=p2
    return
#deffunc _asmscreen int p1
    AsmScreenId=p1
    return

;--------+---------+---------+---------+---------+---------+---------+---------+
; 擬似命令・ラベル処理
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc AsmORG  int p1 ; マシン語の書き込むポインタを設定/初期化する。
    buf_ptr = p1
    return

#deffunc AsmLx int p1   ; ラベル処理をする。(pass1)
    LabelPtr(0,p1)=1,buf_ptr
    return

#deffunc AsmEND         ;  ラベル処理をする。(pass2)
    repeat JumpCnt
        if JumpPtr(0,cnt)=1 : poke buf,JumpPtr(1,cnt)+1,LabelPtr(1,JumpPtr(2,cnt))-JumpPtr(1,cnt)-2
        if JumpPtr(0,cnt)=4 : lpoke buf,JumpPtr(1,cnt)+1,LabelPtr(1,JumpPtr(2,cnt))-JumpPtr(1,cnt)-5
        TextPtr=instr(AsmText,0,strf("%04x",JumpPtr(1,cnt)))
        StrMchn=strf("%08x",LabelPtr(1,JumpPtr(2,cnt))-JumpPtr(1,cnt)-JumpPtr(0,cnt)-1)
        repeat JumpPtr(0,cnt) : poke AsmText,TextPtr+7+cnt*2,peek(StrMchn,6-cnt*2) : poke AsmText,TextPtr+8+cnt*2,peek(StrMchn,7-cnt*2) : loop
    loop
    return

;--------+---------+---------+---------+---------+---------+---------+---------+
; 機械語変換
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc WriteByteBuf int p1
    poke buf,buf_ptr,p1 : buf_ptr++
    return
#deffunc WriteWordBuf int p1
    wpoke buf,buf_ptr,p1 : buf_ptr+=2
    return
#deffunc WriteLongBuf int p1
    lpoke buf,buf_ptr,p1 : buf_ptr+=4
    return
#deffunc WritePrefixBuf int p1
    if p1 : poke buf,buf_ptr,p1 : buf_ptr++
    return

#deffunc WriteBufImm
    if rBitDst==8 : WriteByteBuf Imm : return
    if rBitDst==16 : WriteWordBuf Imm : return
    if rBitDst==32 : WriteLongBuf Imm : return
    return

#deffunc ModRMSIB int p1
    switch MemNo
                case 0  ;[reg1]
                case 1  ;[reg1+Disp]
                    ModRM=p1<<3|Base
                    if Base=ESP : SIB=0x20|Base
                    if MemNo=0 & Base=EBP : ModRM=ModRM|0x40 : Disp=0
                    if MemNo=1 {
                        if Disp>=-128 & Disp<=127 : Mod=0x40 : else: Mod=0x80   ; Disp
                        ModRM=ModRM|Mod
                    }
                    swbreak
                case 2  ;[reg1+reg2]
                case 3  ;[reg1+reg2+Disp]
                case 4  ;[reg2*Scale]
                case 5  ;[reg2*Scale+Disp]
                case 6  ;[reg1+reg2*Scale]
                case 7  ;[reg1+reg2*Scale+Disp]
                    if Index=ESP : ErrorAsm=1 : swbreak
                    ModRM=p1<<3|4
                    SIB=Index<<3|Base
                    if (MemNo=2|MemNo=6)&(Base=EBP) : ModRM=ModRM|0x40 : Disp=0
                    if MemNo&1 {
                        if Disp>=-128 & Disp<=127 : Mod=0x40 : else: Mod=0x80   ; Disp
                        ModRM=ModRM|Mod
                    }
                    swbreak
                case 8  ;[Disp]
                    ModRM=p1<<3|5
                    swbreak
            swend
    return

#deffunc WriteBufSIBDisp
    if (ModRM&7)=4 : WriteByteBuf SIB
    if (ModRM&0xC0)=0x40 : WriteByteBuf Disp            ; [+Disp8]
    if (ModRM&0xC0)=0x80 | MemNo=8 : WriteLongBuf Disp  ; [+Disp32]or[Disp32]
    return

#defcfunc Encodettt int p1
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="O" : return 0
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NO" : return 1
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="B" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NAE" : return 2
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NB" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="AE" : return 3
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="E" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="Z" : return 4
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NE" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NZ" : return 5
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="BE" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NA" : return 6
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NBE" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="A" : return 7

    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="S" : return 8
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NS" : return 9
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="P" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="PE" : return 10
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NP" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="PO" : return 11
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="L" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NGE" : return 12
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NL" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="GE" : return 13
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="LE" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NG" : return 14
    if strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="NLE" | strmid(Mnemonic,p1,strlen(Mnemonic)-p1)="G" : return 15

    return 0x100

; mnemonic r
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure110a int p1   ; NOT-IDIV
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    Opecode=cnd(rBitDst==8,0xF6,0xF7)
    ModRM=(0xC0|p1<<3|rNoDst)

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM

    return

#deffunc Structure110b int p1   ; INC,DEC,CALL,JMP
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if ((p1&6)=0)&(rBitDst!8) { ; INC,DEC r16/32
            Opecode=(0x40|p1<<3|rNoDst)
            WritePrefixBuf OpePrefix
            WriteByteBuf Opecode
    }
    else {
        if ((p1&6)!0)&(rBitDst=8) : ErrorAsm=(ErrorAsm|ErrOperand) : return ; Error Operand
        Opecode=cnd((p1&6)=0,0xFE,0xFF) ; INC/DEC r8 ,CALL/JMP r16/32
        ModRM=(0xC0|p1<<3|rNoDst)

        WritePrefixBuf OpePrefix
        WriteByteBuf Opecode
        WriteByteBuf ModRM
    }

    return

#deffunc Structure110c int p1   ; PUSH,POP
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if rBitDst=8 : ErrorAsm=(ErrorAsm|ErrOperand) : return  ; Error Operand
    Opecode=(p1|rNoDst)
    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode

    return

#deffunc Structure110d  ; SETcc
    if rBitDst!8 : ErrorAsm=(ErrorAsm|ErrOperand) : return  ; Error Operand
    Opecode=(0x0F|(0x90|Encodettt(3))<<8)
    if Opecode&0x10000 : ErrorAsm=(ErrorAsm|ErrMnemonic)    ; Error Mnemonic
    ModRM=(0xC0|rNoDst)
    WriteWordBuf Opecode
    WriteByteBuf ModRM

    return

#deffunc Structure110e ; BSWAP
    if rBitDst!=32 : ErrorAsm=(ErrorAsm|ErrOperand) : return    ; Error Operand
    Opecode=(0x0F|(0xC8|rNoDst)<<8)
    WriteWordBuf Opecode

    return


; mnemonic Sreg
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure120c int p1   ; PUSH,POP
    if rNoDst<4 {
        Opecode=(0x06|rNoDst<<3|p1)
        WriteByteBuf Opecode
    }
    else {
        Opecode=(0x0F|(0x80|rNoDst<<3|p1))
        WriteWordBuf Opecode
    }

    return

; mnemonic [m]
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure140a int p1   ; INC,DEC
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    Opecode=cnd(rBitDst==8,0xF6,0xF7)
    ModRMSIB p1

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp

    return

#deffunc Structure140b int p1   ; INC,DEC,CALL,JMP,PUSH
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if ((p1&6)!0)&(rBitDst=8) : ErrorAsm=(ErrorAsm|ErrOperand) : return ; Error Operand
    Opecode=cnd(((p1&6)=0)&(rBitDst=8),0xFE,0xFF)   ; INC/DEC [m8] ,INC/DEC/CALL/JMP/PUSH [m16/32]
    ModRMSIB p1

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp

    return

#deffunc Structure140c int p1   ; POP
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if SufBit=8 : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    Opecode=0x8F
    ModRMSIB p1

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp

    return

#deffunc Structure140d  ; SETcc
    if SufBit!8 : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    Opecode=(0x0F|(0x90|Encodettt(3))<<8)
    if Opecode&0x10000 : ErrorAsm=(ErrorAsm|ErrMnemonic)    ; Error Mnemonic
    ModRMSIB 0
    
    WriteWordBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp

    return

#deffunc Structure140e int p1, int p2   ; FILD
    if SufBit!32 : ErrorAsm=(ErrorAsm|ErrOperand) : return  ; Error Operand
    Opecode=p1
    ModRMSIB p2

    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp

    return

; mnemonic label
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure150a int p1   ; CALL/JMP
    if p1=0xE9 {
        Opecode=(P1|2)
        JumpPtr(0,JumpCnt)=1,buf_ptr,int(strmid(Operand,1,1)) : JumpCnt++
        WriteWordBuf Opecode
    }
    else {
        Opecode=p1
        JumpPtr(0,JumpCnt)=4,buf_ptr,int(strmid(Operand,1,1)) : JumpCnt++
        WriteByteBuf Opecode
        WriteLongBuf 0
    }
    return

#deffunc Structure150b  ; Jcc/
;   Opecode=(0x0F|(0x80|Encodettt(3))<<8)   ; rel32
    Opecode=(0x70|Encodettt(1))
    if Opecode&0x100 : ErrorAsm=(ErrorAsm|ErrMnemonic) : return ; Error Mnemonic
    JumpPtr(0,JumpCnt)=1,buf_ptr,int(strmid(Operand,1,1)) : JumpCnt++
    WriteWordBuf Opecode

    return

#deffunc Structure150c int p1   ; LOOPcc
    Opecode=p1
    JumpPtr(0,JumpCnt)=1,buf_ptr,int(strmid(Operand,1,1)) : JumpCnt++
    WriteWordBuf Opecode

    return

; mnemonic imm
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure160c int p1   ; PUSH
    Opecode=cnd((imm>=-128)&(imm<=127),p1|2,p1) ;符号拡張
    WriteByteBuf Opecode
    if Opecode&2 : WriteByteBuf Imm : else : WriteLongBuf Imm
    return

#deffunc Structure160e int p1   ; RET/INT
    if imm>cnd(p1=0xCD,0xFF,0xFFFF) : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    Opecode=p1
    WriteByteBuf Opecode
    if p1=0xCD : WriteByteBuf imm : else : WriteWordBuf imm

    return

#deffunc Structure160f int p1   ; DB/DW/DD
    if (p1!32)&(imm>>p1!0) : ErrorAsm=(ErrorAsm|ErrOperand) : return    ; Error Operand
    if p1=8 : WriteByteBuf imm
    if p1=16 : WriteWordBuf imm
    if p1=32 : WriteLongBuf imm

    return

; mnemonic r,r
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure111a int p1   ; MOV,ADD-CMP,TEST,XCHG
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if rBitDst!=rBitSrc : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    if p1=0x87 & rNoDst=EAX & rBitDst!8 {   ; XCHG rA,r
        Opecode=(0x90|rNoSrc)
        WritePrefixBuf OpePrefix
        WriteByteBuf Opecode
    }
    else {
        Opecode=cnd(rBitDst==8,p1&0xFE,p1)
        if cnd(p1=0x87,0,Opecode&2) : ModRM=(0xC0|rNoDst<<3|rNoSrc) : else : ModRM=(0xC0|rNoSrc<<3|rNoDst)
        WritePrefixBuf OpePrefix
        WriteByteBuf Opecode
        WriteByteBuf ModRM
    }
    return

#deffunc Structure111b int p1   ; BT-BTS
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if rBitDst!rBitSrc | rBitDst=8 | rBitSrc=8 : ErrorAsm=(ErrorAsm|ErrOperand) : return    ; Error Operand
    ModRM=(0xC0|rNoSrc<<3|rNoDst)
    WritePrefixBuf OpePrefix
    WriteWordBuf p1
    WriteByteBuf ModRM
    return

#deffunc Structure111c int p1   ; ROR-SAL
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if rNoSrc!CL | rBitSrc!8 : ErrorAsm=(ErrorAsm|ErrOperand) : return  ; Error Operand
    Opecode=cnd(rBitDst==8,0xD2,0xD3)
    ModRM=(0xC0|p1<<3|rNoDst)
    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    return

#deffunc Structure111d int p1   ; IN,OUT
    if cnd(p1=0xED,rBitDst,rBitSrc)==16 : OpePrefix=0x66 : else : OpePrefix=0
    if cnd(p1&2,rNoSrc,rNoDst)!EAX | cnd(p1&2,rNoDst,rNoSrc)!DX | cnd(p1&2,rBitDst,rBitSrc)!16 : ErrorAsm=(ErrorAsm|ErrOperand) : return    ; Error Operand
    Opecode=cnd(cnd(p1&2,rBitSrc,rBitDst)=8,p1&0xFE,p1)
    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    return

; mnemonic r,[m] and [m],r
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure114a int p1   ; MOV,ADD-CMP,TEST,XCHG,LEA
    if cnd(((p1&2)!0)|(p1=0x8D),rBitDst,rBitSrc)==16 : OpePrefix=0x66 : else : OpePrefix=0
    if (p1=0x8D)&(rBitDst=8) : ErrorAsm=(ErrorAsm|ErrOperand) : return  ; Error Operand
    if (p1=0x8B)&(rNoDst=EAX)&(MemNo=8) {   ; MOV rA,[num]
        Opecode=cnd(cnd(p1&2,rBitDst,rBitSrc)==8,0xA0,0xA1)
    }
    else {
        Opecode=cnd(cnd(p1&2,rBitDst,rBitSrc)==8,p1&0xFE,p1)
    }
    if ((p1&2)!0)|(p1=0x8D) : ModRMSIB rNoDst : else : ModRMSIB rNoSrc
    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    if (Opecode&0xFE)!0xA0 : WriteByteBuf ModRM
    WriteBufSIBDisp
    return

; mnemonic [m],r
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure141b int p1   ; BT-BTS
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if SufBit=8 : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    ModRMSIB rNoSrc
    WritePrefixBuf OpePrefix
    WriteWordBuf p1
    WriteByteBuf ModRM
    WriteBufSIBDisp
    return

#deffunc Structure141c int p1   ; ROR-SAL
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if rNoSrc!1 | rBitSrc!8 : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    Opecode=cnd(SufBit==8,0xD2,0xD3)
    ModRMSIB p1
    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp
    return

; mnemonic r,imm
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure116a int p1   ; MOV,TEST
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if (rBitDst!32) & (Imm>>rBitDst!0) : ErrorAsm=(ErrorAsm|ErrOperand) : return
    if (p1=0xA9)&(rNoDst!EAX) {
        Opecode=cnd(rBitDst==8,0xF6,0xF7)
        WritePrefixBuf OpePrefix
        WriteByteBuf Opecode
        ModRM=(0xC0|p1<<3|rNoDst) : WriteByteBuf ModRM
        WriteBufImm
    }
    else {  ; MOV,TEST(rA,imm)
        if p1=0xA9 : Opecode=cnd(rBitDst==8,p1&0xFE,p1) : else : Opecode=cnd(rBitDst==8,p1&0xF7|rNoDst,p1|rNoDst)
        WritePrefixBuf OpePrefix
        WriteByteBuf Opecode
        WriteBufImm
    }
    return

#deffunc Structure116b int p1   ; BT-BTS
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if Imm&0xFFFFFFE0 : ErrorAsm=(ErrorAsm|ErrOperand) : return ; Error Operand
    Opecode=0xBA0F
    ModRM=0xC0|p1<<3|rNoDst

    WritePrefixBuf OpePrefix
    WriteWordBuf Opecode
    WriteByteBuf ModRM
    WriteByteBuf Imm
    return

#deffunc Structure116c int p1   ; ROR-SAL
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if Imm>0xFF : ErrorAsm=(ErrorAsm|ErrOperand) : return
    if Imm=1 : Opecode=0xD1 : else : Opecode=0xC1
    Opecode=cnd(rBitDst==8,Opecode&0xFE,Opecode)
    ModRM=(0xC0|p1<<3|rNoDst)

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    if Imm!1 : WriteByteBuf Imm
    return

#deffunc Structure116d int p1   ; IN,OUT
    if cnd(p1=0xE5,rBitDst,rBitSrc)==16 : OpePrefix=0x66 : else : OpePrefix=0
    if cnd(p1&2,rNoSrc,rNoDst)!EAX | Imm>0xFF : ErrorAsm=(ErrorAsm|ErrOperand) : return ; Error Operand
    Opecode=cnd(cnd(p1&2,rBitSrc,rBitDst)=8,p1&0xFE,p1)

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf Imm
    return

#deffunc Structure116e int p1   ; ADD-CMP
    if rBitDst==16 : OpePrefix=0x66 : else : OpePrefix=0
    if (rBitDst!32) & (Imm>>rBitDst!0) : ErrorAsm=(ErrorAsm|ErrOperand) : return
    if (rBitDst!8)&(Imm>=-128)&(Imm<=127) {
        Opecode=0x83    ; 符号拡張
    } else {
        if rNoDst=EAX : Opecode=p1 : else : Opecode=0x81
    }
    Opecode=cnd(rBitDst==8,Opecode&0xFE,Opecode)

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    if Opecode&0x80 : ModRM=(0xC0|(p1&0x38)|rNoDst) : WriteByteBuf ModRM
    if Opecode=0x83 : WriteByteBuf Imm : else : WriteBufImm
    return

; mnemonic [m],imm
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure146a int p1   ; MOV,TEST
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if (SufBit!32) & (Imm>>SufBit!0) : ErrorAsm=(ErrorAsm|ErrOperand) : return
    Opecode=cnd(SufBit==8,p1&0xFE,p1)
    ModRMSIB 0

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp
    WriteBufImm
    return

#deffunc Structure146b int p1   ; BT-BTS
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if Imm&0xFFFFFFE0 : ErrorAsm=(ErrorAsm|ErrOperand) : return ; Error Operand
    Opecode=0xBA0F
    ModRMSIB p1

    WritePrefixBuf OpePrefix
    WriteWordBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp
    WriteByteBuf Imm
    return

#deffunc Structure146c int p1   ; ROR-SAL
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if Imm>0xFF : ErrorAsm=(ErrorAsm|ErrOperand) : return
    if Imm=1 : Opecode=0xD1 : else : Opecode=0xC1
    Opecode=cnd(rBitDst==8,Opecode&0xFE,Opecode)
    ModRMSIB p1

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp
    if Imm!1 : WriteByteBuf Imm
    return

#deffunc Structure146e int p1   ; ADD-CMP
    if SufBit==16 : OpePrefix=0x66 : else : OpePrefix=0
    if (SufBit!32) & (Imm>>SufBit!0) : ErrorAsm=(ErrorAsm|ErrOperand) : return
    if (SufBit!8)&(Imm>=-128)&(Imm<=127) {
        Opecode=0x83    ; 符号拡張
    } else {
        Opecode=0x81
    }
    Opecode=cnd(SufBit==8,Opecode&0xFE,Opecode)
    ModRMSIB p1

    WritePrefixBuf OpePrefix
    WriteByteBuf Opecode
    WriteByteBuf ModRM
    WriteBufSIBDisp
    if Opecode=0x83 {
        WriteByteBuf Imm
    } else {
        WriteBufImm
    }
    return

; mnemonic r,Sreg and Sreg,r
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure112a int p1   ; MOV 
    if rBitDst!=rBitSrc : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    Opecode=p1
    if Opecode&2 : ModRM=(0xC0|rNoDst<<3|rNoSrc) : else : ModRM=(0xC0|rNoSrc<<3|rNoDst)

    WriteByteBuf Opecode
    WriteByteBuf ModRM

    return

; mnemonic Sreg,[m] and [m],Sreg
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure124a int p1, int p2   ; MOV
    if SufBit!=16 : ErrorAsm=(ErrorAsm|ErrOperand) : return ; Error Operand
    Opecode=p1
    ModRMSIB p2

    WriteByteBuf Opecode
    WriteByteBuf ModRM
    if (ModRM&7)=4 : WriteByteBuf SIB
    if (ModRM&0xC0)=0x40 : WriteByteBuf Disp            ; [+Disp8]
    if (ModRM&0xC0)=0x80 | MemNo=8 : WriteLongBuf Disp  ; [+Disp32]or[Disp32]

    return

; mnemonic r,Creg and Creg,r
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Structure113a int p1   ; MOV
    if rBitDst!=rBitSrc : ErrorAsm=(ErrorAsm|ErrOperand) : return   ; Error Operand
    Opecode=p1
    if Opecode&0x200 : ModRM=(0xC0|rNoDst<<3|rNoSrc) : else : ModRM=(0xC0|rNoSrc<<3|rNoDst)

    WriteWordBuf Opecode
    WriteByteBuf ModRM

    return



;--------+---------+---------+---------+---------+---------+---------+---------+
; Assemble
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc assemble int p1
    ErrorAsm=0
    if Structure&0x1000 : AsmLx int(strmid(AsmLabel,1,1))
    StrBufptr=buf_ptr

    switch p1
        case 0x000  ; -
            return
        case 0x100  ; mnemonic
            if Mnemonic="AAA" : WriteByteBuf 0x37 : return          ; ASCII Adjust After Addition
            if Mnemonic="AAD" : WriteWordBuf 0x0AD5 : return        ; ASCII Adjust AX Before Division
            if Mnemonic="AAM" : WriteWordBuf 0x0AD4 : return        ; ASCII Adjust AX After Multiply
            if Mnemonic="AAS" : WriteByteBuf 0x3F : return          ; ASCII Adjust After Addition
;           if Mnemonic="BSF" : WriteWordBuf 0xBC0F : return        ; Bit Scan Forward
;           if Mnemonic="BSR" : WriteWordBuf 0xBD0F : return        ; Bit Scan Reverse
            if Mnemonic="CBW" : WriteWordBuf 0x9866 : return        ; Convert Byte to Word
            if Mnemonic="CWDE" : WriteByteBuf 0x98 : return         ; Convert Word to Doubleword
            if Mnemonic="CLC" : WriteByteBuf 0xF8 : return          ; Clear Carry Flag
            if Mnemonic="CLD" : WriteByteBuf 0xFC  : return         ; Clear Direction Flag
            if Mnemonic="CLI" : WriteByteBuf 0xFA : return          ; Clear Interrupt Flag
            if Mnemonic="CMC" : WriteByteBuf 0xF5 : return          ; Complement Carry Flag
            if Mnemonic="CMPSB" : WriteByteBuf 0xA6 : return        ; Compare String Operands
            if Mnemonic="CMPSD" : WriteByteBuf 0xA7 : return        ; Compare String Operands
            if Mnemonic="CPUID" : WriteWordBuf 0xA20F : return      ; CPU Identification
            if Mnemonic="CWD" : WriteWordBuf 0x9966 : return        ; Convert Word to Doubleword
            if Mnemonic="CDQ" : WriteByteBuf 0x99 : return          ; Convert Double to Quad
            if Mnemonic="DAA" : WriteByteBuf 0x27 : return          ; Decimal Adjust AL after Addition
            if Mnemonic="DAS" : WriteByteBuf 0x2F : return          ; Decimal Adjust AL after Subtraction
            if Mnemonic="HLT" : WriteByteBuf 0xF4 : return          ; Halt
            if Mnemonic="INSB" : WriteByteBuf 0x6C : return         ; Input from Port to String
            if Mnemonic="INSD" : WriteByteBuf 0x6D : return         ; Input from Port to String
            if Mnemonic="INT3" : WriteByteBuf 0xCC : return         ; Call to Interrupt Procedure 3
            if Mnemonic="INTO" : WriteByteBuf 0xCE : return         ; Call to Interrupt Procedure O
            if Mnemonic="IRETD" : WriteByteBuf 0xCF : return        ; Interrupt Return
            if Mnemonic="IRET" : WriteByteBuf 0xCF : return         ; Interrupt Return
            if Mnemonic="LAHF" : WriteByteBuf 0x9F : return         ; Load Status Flags into AH Register
            if Mnemonic="LEAVE" : WriteByteBuf 0xC9 : return        ; High Level Procedure Exit
            if Mnemonic="LOCK" : WriteByteBuf 0xF0 : return         ; Assert LOCK# Signal Prefix
            if Mnemonic="LODSB" : WriteByteBuf 0xAC : return        ; Load String
            if Mnemonic="LODSD" : WriteByteBuf 0xAD : return        ; Load String
            if Mnemonic="MOVSB" : WriteByteBuf 0xA4 : return        ; Move Data from String to String
            if Mnemonic="MOVSD" : WriteByteBuf 0xA5 : return        ; Move Data from String to String
            if Mnemonic="NOP" : WriteByteBuf 0x90 : return          ; No Operation
            if Mnemonic="OUTSB" : WriteByteBuf 0x6E : return        ; Output String to Port
            if Mnemonic="OUTSD" : WriteByteBuf 0x6F : return        ; Output String to Port
            if Mnemonic="POPA" : WriteByteBuf 0x61 : return         ; Pop All General-Purpose Registers
            if Mnemonic="POPAD" : WriteByteBuf 0x61 : return        ; Pop All General-Purpose Registers
            if Mnemonic="POPF" : WriteByteBuf 0x9D : return         ; Pop Stack into EFLAGS Register
            if Mnemonic="POPFD" : WriteByteBuf 0x9D : return        ; Pop Stack into EFLAGS Register
            if Mnemonic="PUSHA" : WriteByteBuf 0x60 : return        ; Push All General-Purpose Registers
            if Mnemonic="PUSHAD" : WriteByteBuf 0x60 : return       ; Push All General-Purpose Registers
            if Mnemonic="PUSHF" : WriteByteBuf 0x9C : return        ; Push Stack into EFLAGS Register
            if Mnemonic="PUSHFD" : WriteByteBuf 0x9C : return       ; Push Stack into EFLAGS Register
            if Mnemonic="RDMSR" : WriteWordBuf 0x320F : return      ; Read from Model Specific Register
            if Mnemonic="RDPMC" : WriteWordBuf 0x330F : return      ; Read Performance-Monitoring Counters
            if Mnemonic="RDTSC" : WriteWordBuf 0x310F : return      ; Read Time-Stamp Counter
            if Mnemonic="REP" : WriteByteBuf 0xF3 : return          ; Repeat String Operation Prefix (INS/MOVS/OUTS/LODS/STOS)
            if Mnemonic="REPZ" : WriteByteBuf 0xF3 : return         ; Repeat String Operation Prefix (CMPS/SCAS)
            if Mnemonic="REPE" : WriteByteBuf 0xF3 : return         ; Repeat String Operation Prefix (CMPS/SCAS)
            if Mnemonic="REPNZ" : WriteByteBuf 0xF2 : return        ; Repeat String Operation Prefix (CMPS/SCAS)
            if Mnemonic="REPNE" : WriteByteBuf 0xF2 : return        ; Repeat String Operation Prefix (CMPS/SCAS)
            if Mnemonic="RET" : WriteByteBuf 0xC3 : return          ; Return from Procedure
            if Mnemonic="SAHF" : WriteByteBuf 0x9E : return         ; Store AH into Flags
            if Mnemonic="SCASB" : WriteByteBuf 0xAE : return        ; Scan String
            if Mnemonic="SCASD" : WriteByteBuf 0xAF : return        ; Scan String
            if Mnemonic="STC" : WriteByteBuf 0xF9 : return          ; Set Carry Flag
            if Mnemonic="STD" : WriteByteBuf 0xFD : return          ; Set Direction Flag
            if Mnemonic="STI" : WriteByteBuf 0xFB : return          ; Set Interrupt Flag
            if Mnemonic="STOSB" : WriteByteBuf 0xAA : return        ; Store String
            if Mnemonic="STOSD" : WriteByteBuf 0xAB : return        ; Store String
            if Mnemonic="SYSENTER" : WriteWordBuf 0x340F : return   ; Fast System Call
            if Mnemonic="SYSEXIT" : WriteWordBuf 0x350F : return    ; Fast Return from Fast System Call
            if Mnemonic="UD2" : WriteWordBuf 0x0B0F : return        ; Undefined Instruction
            if Mnemonic="WRMSR" : WriteWordBuf 0x300F : return      ; Write to Model Specific Register
            if Mnemonic="XLATB" : WriteByteBuf 0xD7 : return        ; Table Look-up Translation

            if Mnemonic="CS:" : WriteByteBuf 0x2E : return
            if Mnemonic="SS:" : WriteByteBuf 0x36 : return
            if Mnemonic="DS:" : WriteByteBuf 0x3E : return
            if Mnemonic="ES:" : WriteByteBuf 0x26 : return
            if Mnemonic="FS:" : WriteByteBuf 0x64 : return
            if Mnemonic="GS:" : WriteByteBuf 0x65 : return

            if Mnemonic="END" : AsmEND : return                     ; END
            swbreak

        case 0x110  ; mnemonic r
            if Mnemonic="INC" : Structure110b 0 : return            ; Increment by 1
            if Mnemonic="DEC" : Structure110b 1 : return            ; Decrement by 1
            if Mnemonic="NOT" : Structure110a 2 : return            ; One's Complement Negation
            if Mnemonic="NEG" : Structure110a 3 : return            ; Two's Complement Negation
            if Mnemonic="MUL" : Structure110a 4 : return            ; Unsigned Multiply
            if Mnemonic="IMUL": Structure110a 5 : return            ; Signed Multiply
            if Mnemonic="DIV" : Structure110a 6 : return            ; Unsigned Divide
            if Mnemonic="IDIV": Structure110a 7 : return            ; Signed Divide
            if Mnemonic="PUSH": Structure110c 0x50 : return         ; Push Word or Doubleword onto the Stack
            if Mnemonic="POP" : Structure110c 0x58 : return         ; Pop a Value from the Stack
            if Mnemonic="CALL": Structure110b 2 : return            ; Call Procedure
            if Mnemonic="JMP" : Structure110b 4 : return            ; Jump
            if strmid(Mnemonic,0,3)="SET" : Structure110d : return  ; Set Byte on Condition
            if Mnemonic="BSWAP" : Structure110e : return            ; Byte Swap
            swbreak
        case 0x120  ; mnemonic Sreg
            if Mnemonic="PUSH": Structure120c 0 : return            ; Push Word or Doubleword onto the Stack
            if Mnemonic="POP" : Structure120c 1 : return            ; Pop a Value from the Stack
            swbreak
        case 0x140  ; mnemonic [m]
            if Mnemonic="INC" : Structure140b 0 : return            ; Increment by 1
            if Mnemonic="DEC" : Structure140b 1 : return            ; Decrement by 1
            if Mnemonic="NOT" : Structure140a 2 : return            ; One's Complement Negation
            if Mnemonic="NEG" : Structure140a 3 : return            ; Two's Complement Negation
            if Mnemonic="MUL" : Structure140a 4 : return            ; Unsigned Multiply
            if Mnemonic="IMUL": Structure140a 5 : return            ; Signed Multiply
            if Mnemonic="DIV" : Structure140a 6 : return            ; Unsigned Divide
            if Mnemonic="IDIV": Structure140a 7 : return            ; Signed Divide
            if Mnemonic="PUSH": Structure140b 6 : return            ; Push Word or Doubleword onto the Stack
            if Mnemonic="POP" : Structure140c 0 : return            ; Pop a Value from the Stack
            if Mnemonic="CALL": Structure140b 2 : return            ; Call Procedure
            if Mnemonic="JMP" : Structure140b 4 : return            ; Jump
            if strmid(Mnemonic,0,3)="SET" : Structure140d : return  ; Set Byte on Condition
            if Mnemonic="FILD" : Structure140e 0xDF,5 : return      ; Load Integer
            if Mnemonic="FLD"  : Structure140e 0xDD,0 : return      ; Load Real
            if Mnemonic="FISTP": Structure140e 0xDF,7 : return      ; Store Integer and Pop
            if Mnemonic="FSTP" : Structure140e 0xDD,3 : return      ; Store Real and Pop
            swbreak
        case 0x150  ; mnemonic label
            if Mnemonic="CALL": Structure150a 0xE8 : return         ; Call Procedure
            if Mnemonic="JMP" : Structure150a 0xE9 : return         ; Jump
            if strmid(Mnemonic,0,1)="J" : Structure150b : return    ; Jump if Condition Is Met (cc, JCXZ, JECXZ)
            if Mnemonic="LOOP"  : Structure150c 0xE2 : return       ; Loop According to ECX Counter[-]
            if Mnemonic="LOOPNZ": Structure150c 0xE0 : return       ; Loop According to ECX Counter[NZ(NE)]
            if Mnemonic="LOOPNE": Structure150c 0xE0 : return       ; Loop According to ECX Counter[NZ(NE)]
            if Mnemonic="LOOPZ" : Structure150c 0xE1 : return       ; Loop According to ECX Counter[Z(E)]
            if Mnemonic="LOOPE" : Structure150c 0xE1 : return       ; Loop According to ECX Counter[Z(E)]
            swbreak
        case 0x160  ; mnemonic imm
            if Mnemonic="PUSH": Structure160c 0x68 : return         ; Push Word or Doubleword onto the Stack
            if Mnemonic="RET" : Structure160e 0xC2 : return         ; Return from Procedure
            if Mnemonic="INT" : Structure160e 0xCD : return         ; Call to Interrupt Procedure
            if Mnemonic="DB"  : Structure160f 8 : return            ; Byte
            if Mnemonic="DW"  : Structure160f 16 : return           ; Word
            if Mnemonic="DD"  : Structure160f 32 : return           ; Long
            if Mnemonic="ORG" : AsmORG imm : return                 ; ORG
            swbreak

        case 0x111  ; mnemonic r,r
            if Mnemonic="MOV" : Structure111a 0x8B : return         ; Move
            if Mnemonic="ADD" : Structure111a 0x03 : return         ; Add
            if Mnemonic="ADC" : Structure111a 0x13 : return         ; Add with Carry
            if Mnemonic="SUB" : Structure111a 0x2B : return         ; Subtract
            if Mnemonic="SBB" : Structure111a 0x1B : return         ; Integer Subtraction with Borrow
            if Mnemonic="AND" : Structure111a 0x23 : return         ; Logical AND
            if Mnemonic="OR"  : Structure111a 0x0B : return         ; Logical Inclusive OR
            if Mnemonic="XOR" : Structure111a 0x33 : return         ; Logical Exclusive OR
            if Mnemonic="CMP" : Structure111a 0x3B : return         ; Compare Two Operands
            if Mnemonic="TEST": Structure111a 0x85 : return         ; Logical Compare
            if Mnemonic="XCHG": Structure111a 0x87 : return         ; Exchange Register/Memory with Register
            if Mnemonic="BT"  : Structure111b 0xA30F : return       ; Bit Test
            if Mnemonic="BTC" : Structure111b 0xBB0F : return       ; Bit Test and Complement
            if Mnemonic="BTR" : Structure111b 0xB30F : return       ; Bit Test and Reset
            if Mnemonic="BTS" : Structure111b 0xAB0F : return       ; Bit Test and Set
            if Mnemonic="ROR" : Structure111c 1 : return            ; Rotate right
            if Mnemonic="ROL" : Structure111c 0 : return            ; Rotate left
            if Mnemonic="RCR" : Structure111c 3 : return            ; Rotate through carry right
            if Mnemonic="RCL" : Structure111c 2 : return            ; Rotate through carry left
            if Mnemonic="SHR" : Structure111c 5 : return            ; Shift logical right
            if Mnemonic="SAR" : Structure111c 7 : return            ; Shift arithmetic right
            if Mnemonic="SHL" : Structure111c 4 : return            ; Shift logical left
            if Mnemonic="SAL" : Structure111c 4 : return            ; Shift arithmetic left
            if Mnemonic="IN"  : Structure111d 0xED : return         ; Input from Port
            if Mnemonic="OUT" : Structure111d 0xEF : return         ; Output to Port
            swbreak
        case 0x114  ; mnemonic r,[m]
            if Mnemonic="MOV" : Structure114a 0x8B : return         ; Move
            if Mnemonic="ADD" : Structure114a 0x03 : return         ; Add
            if Mnemonic="ADC" : Structure114a 0x13 : return         ; Add with Carry
            if Mnemonic="SUB" : Structure114a 0x2B : return         ; Subtract
            if Mnemonic="SBB" : Structure114a 0x1B : return         ; Integer Subtraction with Borrow
            if Mnemonic="AND" : Structure114a 0x23 : return         ; Logical AND
            if Mnemonic="OR"  : Structure114a 0x0B : return         ; Logical Inclusive OR
            if Mnemonic="XOR" : Structure114a 0x33 : return         ; Logical Exclusive OR
            if Mnemonic="CMP" : Structure114a 0x3B : return         ; Compare Two Operands
            if Mnemonic="XCHG": Structure114a 0x87 : return         ; Exchange Register/Memory with Register
            if Mnemonic="LEA" : Structure114a 0x8D : return         ; Load Effective Address
            swbreak
        case 0x141  ; mnemonic [m],r
            if Mnemonic="MOV" : Structure114a 0x89 : return         ; Move
            if Mnemonic="ADD" : Structure114a 0x01 : return         ; Add
            if Mnemonic="ADC" : Structure114a 0x11 : return         ; Add with Carry
            if Mnemonic="SUB" : Structure114a 0x29 : return         ; Subtract
            if Mnemonic="SBB" : Structure114a 0x19 : return         ; Integer Subtraction with Borrow
            if Mnemonic="AND" : Structure114a 0x21 : return         ; Logical AND
            if Mnemonic="OR"  : Structure114a 0x09 : return         ; Logical Inclusive OR
            if Mnemonic="XOR" : Structure114a 0x21 : return         ; Logical Exclusive OR
            if Mnemonic="CMP" : Structure114a 0x39 : return         ; Compare Two Operands
            if Mnemonic="TEST": Structure114a 0x85 : return         ; Logical Compare
            if Mnemonic="BT"  : Structure141b 0xA30F : return       ; Bit Test
            if Mnemonic="BTC" : Structure141b 0xBB0F : return       ; Bit Test and Complement
            if Mnemonic="BTR" : Structure141b 0xB30F : return       ; Bit Test and Reset
            if Mnemonic="BTS" : Structure141b 0xAB0F : return       ; Bit Test and Set
            if Mnemonic="ROR" : Structure141c 1 : return            ; Rotate right
            if Mnemonic="ROL" : Structure141c 0 : return            ; Rotate left
            if Mnemonic="RCR" : Structure141c 3 : return            ; Rotate through carry right
            if Mnemonic="RCL" : Structure141c 2 : return            ; Rotate through carry left
            if Mnemonic="SHR" : Structure141c 5 : return            ; Shift logical right
            if Mnemonic="SAR" : Structure141c 7 : return            ; Shift arithmetic right
            if Mnemonic="SHL" : Structure141c 4 : return            ; Shift logical left
            if Mnemonic="SAL" : Structure141c 4 : return            ; Shift arithmetic left
            swbreak
        case 0x116  ; mnemonic r,imm
            if Mnemonic="MOV" : Structure116a 0xB8 : return         ; Move
            if Mnemonic="ADD" : Structure116e 0x05 : return         ; Add
            if Mnemonic="ADC" : Structure116e 0x15 : return         ; Add with Carry
            if Mnemonic="SUB" : Structure116e 0x2D : return         ; Subtract
            if Mnemonic="SBB" : Structure116e 0x1D : return         ; Integer Subtraction with Borrow
            if Mnemonic="AND" : Structure116e 0x25 : return         ; Logical AND
            if Mnemonic="OR"  : Structure116e 0x0D : return         ; Logical Inclusive OR
            if Mnemonic="XOR" : Structure116e 0x35 : return         ; Logical Exclusive OR
            if Mnemonic="CMP" : Structure116e 0x3D : return         ; Compare Two Operands
            if Mnemonic="TEST": Structure116a 0xA9 : return         ; Logical Compare
            if Mnemonic="BT"  : Structure116b 4 : return            ; Bit Test
            if Mnemonic="BTC" : Structure116b 7 : return            ; Bit Test and Complement
            if Mnemonic="BTR" : Structure116b 6 : return            ; Bit Test and Reset
            if Mnemonic="BTS" : Structure116b 5 : return            ; Bit Test and Set
            if Mnemonic="ROR" : Structure116c 1 : return            ; Rotate right
            if Mnemonic="ROL" : Structure116c 0 : return            ; Rotate left
            if Mnemonic="RCR" : Structure116c 3 : return            ; Rotate through carry right
            if Mnemonic="RCL" : Structure116c 2 : return            ; Rotate through carry left
            if Mnemonic="SHR" : Structure116c 5 : return            ; Shift logical right
            if Mnemonic="SAR" : Structure116c 7 : return            ; Shift arithmetic right
            if Mnemonic="SHL" : Structure116c 4 : return            ; Shift logical left
            if Mnemonic="SAL" : Structure116c 4 : return            ; Shift arithmetic left
            if Mnemonic="IN"  : Structure116d 0xE5 : return         ; Input from Port
            swbreak
        case 0x161  ; mnemonic imm,r
            if Mnemonic="OUT" : Structure116d 0xE7 : return         ; Output to Port
            swbreak
        case 0x146  ; mnemonic [m],imm
            if Mnemonic="MOV" : Structure146a 0xC7 : return         ; Move
            if Mnemonic="ADD" : Structure146e 0 : return            ; Add
            if Mnemonic="ADC" : Structure146e 2 : return            ; Add with Carry
            if Mnemonic="SUB" : Structure146e 5 : return            ; Subtract
            if Mnemonic="SBB" : Structure146e 3 : return            ; Integer Subtraction with Borrow
            if Mnemonic="AND" : Structure146e 4 : return            ; Logical AND
            if Mnemonic="OR"  : Structure146e 1 : return            ; Logical Inclusive OR
            if Mnemonic="XOR" : Structure146e 6 : return            ; Logical Exclusive OR
            if Mnemonic="CMP" : Structure146e 7 : return            ; Compare Two Operands
            if Mnemonic="TEST": Structure146a 0xF7 : return         ; Logical Compare
            if Mnemonic="BT"  : Structure146b 4 : return            ; Bit Test
            if Mnemonic="BTC" : Structure146b 7 : return            ; Bit Test and Complement
            if Mnemonic="BTR" : Structure146b 6 : return            ; Bit Test and Reset
            if Mnemonic="BTS" : Structure146b 5 : return            ; Bit Test and Set
            if Mnemonic="ROR" : Structure146c 1 : return            ; Rotate right
            if Mnemonic="ROL" : Structure146c 0 : return            ; Rotate left
            if Mnemonic="RCR" : Structure146c 3 : return            ; Rotate through carry right
            if Mnemonic="RCL" : Structure146c 2 : return            ; Rotate through carry left
            if Mnemonic="SHR" : Structure146c 5 : return            ; Shift logical right
            if Mnemonic="SAR" : Structure146c 7 : return            ; Shift arithmetic right
            if Mnemonic="SHL" : Structure146c 4 : return            ; Shift logical left
            if Mnemonic="SAL" : Structure146c 4 : return            ; Shift arithmetic left
            swbreak
        case 0x112  ; mnemonic r,Sreg
            if Mnemonic="MOV" : Structure112a 0x8C : return         ; Move
            swbreak
        case 0x121  ; mnemonic Sreg,r
            if Mnemonic="MOV" : Structure112a 0x8E : return         ; Move
            swbreak
        case 0x124  ; mnemonic Sreg,[m]
            if Mnemonic="MOV" : Structure124a 0x8E,rNoDst : return  ; Move
            swbreak
        case 0x142  ; mnemonic [m],Sreg
            if Mnemonic="MOV" : Structure124a 0x8C,rNoSrc : return  ; Move
            swbreak
        case 0x113  ; mnemonic r,Creg
            if Mnemonic="MOV" : Structure113a 0x200F : return       ; Move
            swbreak
        case 0x131  ; mnemonic Creg,r
            if Mnemonic="MOV" : Structure113a 0x220F : return       ; Move
            swbreak
        default
            ErrorAsm=(ErrorAsm|ErrSyntax) : return  ; Error Syntax
            swbreak
    swend
    ErrorAsm=(ErrorAsm|ErrMnemonic) : return    ; Error Mnemonic

#deffunc StructureReg var p1

    if p1="EAX" : rNo=EAX : rBit=32 : return 1
    if p1="ECX" : rNo=ECX : rBit=32 : return 1
    if p1="EDX" : rNo=EDX : rBit=32 : return 1
    if p1="EBX" : rNo=EBX : rBit=32 : return 1
    if p1="ESP" : rNo=ESP : rBit=32 : return 1
    if p1="EBP" : rNo=EBP : rBit=32 : return 1
    if p1="ESI" : rNo=ESI : rBit=32 : return 1
    if p1="EDI" : rNo=EDI : rBit=32 : return 1

    if p1="AX" : rNo=AX : rBit=16 : return 1
    if p1="CX" : rNo=CX : rBit=16 : return 1
    if p1="DX" : rNo=DX : rBit=16 : return 1
    if p1="BX" : rNo=BX : rBit=16 : return 1
    if p1="SP" : rNo=SP : rBit=16 : return 1
    if p1="BP" : rNo=BP : rBit=16 : return 1
    if p1="SI" : rNo=SI : rBit=16 : return 1
    if p1="DI" : rNo=DI : rBit=16 : return 1

    if p1="AL" : rNo=AL : rBit=8 : return 1
    if p1="CL" : rNo=CL : rBit=8 : return 1
    if p1="DL" : rNo=DL : rBit=8 : return 1
    if p1="BL" : rNo=BL : rBit=8 : return 1
    if p1="AH" : rNo=AH : rBit=8 : return 1
    if p1="CH" : rNo=CH : rBit=8 : return 1
    if p1="DH" : rNo=DH : rBit=8 : return 1
    if p1="BH" : rNo=BH : rBit=8 : return 1

    if p1="ES" : rNo=0 : rBit=16 : return 2
    if p1="CS" : rNo=1 : rBit=16 : return 2
    if p1="SS" : rNo=2 : rBit=16 : return 2
    if p1="DS" : rNo=3 : rBit=16 : return 2
    if p1="FS" : rNo=4 : rBit=16 : return 2
    if p1="GS" : rNo=5 : rBit=16 : return 2

    if p1="CR0" : rNo=0 : rBit=32 : return 3
    if p1="CR2" : rNo=2 : rBit=32 : return 3
    if p1="CR3" : rNo=3 : rBit=32 : return 3
    if p1="CR4" : rNo=4 : rBit=32 : return 3

    return 15

#deffunc StructureNum str p1
    i=p1
    if strmid(i,0,1)!"+" & strmid(i,0,1)!"-" : i="+"+i
    if strmid(i,1,1)="$" : getstr num,i,1,'' : num=int(strmid(i,0,1)+str(int(num))) : return 6
    if strmid(i,1,2)="0X" : getstr num,i,3,'' : num=int(strmid(i,0,1)+str(int("$"+num))) : return 6
    if peek(i,1)>='0' & peek(i,1)<='9' : num=int(i) : return 6
    return 0

#defcfunc SearchToken var p1, var p2
    while
        Char=strmid(p1,p2,1)
        if Char!" " & Char!"\t" :  _break
        p2++
    wend
    i=p2
    while
        Char=strmid(p1,i,1)
        if Char=="" | Char==";" | Char==" " | Char=="\t" :  _break
        i++
    wend
    return i

#defcfunc SearchOperator var p1, int p2
    i=p2
    while
        Char=strmid(p1,i,1)
        if Char=="" | Char="[" | Char="+" | Char="-" | Char="*" | Char="]" : _break
        i++
    wend
    return i

;--------+---------+---------+---------+---------+---------+---------+---------+
; 字句解析(Operand)
;--------+---------+---------+---------+---------+---------+---------+---------+
#defcfunc Lxean str p1, int p2
    Operand=p1 : getstr Distination,Operand,0,',' : getstr Source,Operand,strsize,''
    if p2 : tmpstr=Source : else : tmpstr=Distination

    if tmpstr="" : return 0
    if instr(tmpstr,0,"L")==0 : return 5
    if instr(tmpstr,0,"[")==0 {
        SufBit=32
        if instr(tmpstr,0,".")!=-1 {
;           if p2 : return 15   ; Error
            Prefix=strmid(tmpstr,-1,1)
            switch Prefix
                case "D"
                    swbreak
                case "W"
                    SufBit=16
                    swbreak
                case "B"
                    SufBit=8
                    swbreak
                default
                    return 15   ; Error
            swend
        }
        CharStrt=1
        CharEnd=SearchOperator(tmpstr,CharStrt)
        switch Char
            case "]"
                MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                StructureNum MemBuf : if stat=6 : Disp=num : MemNo=8 : return 4 ; [Disp]
                StructureReg MemBuf
                if stat!=1 | rBit!=32 : return 15   ; Error
                Base=rNo : MemNo=0 : return 4   ; [reg1]
            case "+"
            case "-"
                MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                StructureReg MemBuf
                if stat!=1 | rBit!=32 : return 15   ; Error
                Base=rNo
                CharStrt=CharEnd+1 : Sign=Char
                CharEnd=SearchOperator(tmpstr,CharStrt)
                switch Char
                    case "]"
                    case "+"
                    case "-"
                        MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                        StructureNum Sign+MemBuf
                        if stat=6 & Char="]" {
                            Disp=num : MemNo=1 : return 4   ; [reg1+Disp]
                        }
                        StructureReg MemBuf
                        if stat!=1 | rBit!=32 : return 15   ; Error
                        Index=rNo : if Char="]" : MemNo=2 : return 4    ; [reg1+reg2]

                        CharStrt=CharEnd+1 : Sign=Char
                        CharEnd=SearchOperator(tmpstr,CharStrt)
                        switch Char
                            case "]"
                                MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                                StructureNum Sign+MemBuf : if stat!=6 : return 15   ; Error
                                Disp=num : MemNo=3 : return 4   ; [reg2*reg2+Disp]
                            default
                                return 15   ; Error
                        swend
                    case "*"
                        MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                        StructureReg MemBuf
                        if stat!=1 | rBit!=32 : return 15   ; Error
                        Index=rNo   ; [reg1+reg2*...]
                        CharStrt=CharEnd+1
                        CharEnd=SearchOperator(tmpstr,CharStrt)
                        switch Char
                            case "]"
                            case "+"
                            case "-"
                                MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                                StructureNum MemBuf
                                if stat!=6|(num!=2&num!=4&num!=8) : return 15   ; Error
                                Scale=num : if Char="]" : MemNo=6 : return 4    ; [reg1+reg2*Scale]

                                CharStrt=CharEnd+1 : Sign=Char
                                CharEnd=SearchOperator(tmpstr,CharStrt)
                                switch Char
                                    case "]"
                                        MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                                        StructureNum Sign+MemBuf : if stat!=6 : return 15   ; Error
                                        Disp=num : MemNo=7 : return 4   ; [reg1+reg2*Scale+Disp]
                                    default
                                        return 15   ; Error
                                swend
                            default
                                return 15   ; Error
                        swend
                    default
                        return 15   ; Error
                swend
            case "*"
                MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                StructureReg MemBuf
                if stat!=1 | rBit!=32 : return 15   ; Error
                Index=rNo   ; [reg2*...]
                CharStrt=CharEnd+1
                CharEnd=SearchOperator(tmpstr,CharStrt)
                switch Char
                    case "]"
                    case "+"
                    case "-"
                        MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                        StructureNum MemBuf
                        if stat!=6|(num!=2&num!=4&num!=8) : return 15   ; Error
                        Scale=num : if Char="]" : MemNo=4 : return 4    ; [reg2*Scale]

                        CharStrt=CharEnd+1 : Sign=Char
                        CharEnd=SearchOperator(tmpstr,CharStrt)
                        switch Char
                            case "]"
                                MemBuf=strmid(tmpstr,CharStrt,CharEnd-CharStrt)
                                StructureNum Sign+MemBuf : if stat!=6 : return 15   ; Error
                                Disp=num : MemNo=5 : return 4   ; [reg2*Scale+Disp]
                            default
                                return 15   ; Error
                        swend
                    default
                        return 15   ; Error
                swend
            default
                return 15   ; Error
        swend
    }
    StructureNum tmpstr : if stat=6 : Imm=num : return 6
    StructureReg tmpstr : return stat

;--------+---------+---------+---------+---------+---------+---------+---------+
; 構文解析
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc Parse var p1
    CharStrt=0 : Structure=0 : AsmLabel="" : Mnemonic="" : Operand=""
    CharEnd=SearchToken(p1,CharStrt)
    if CharEnd=3 {
        switch strmid(p1,2,1)
            case ":"
                if strmid(p1,0,1)="L" {
                    getstr AsmLabel,p1,CharStrt,':'
                    Structure=0x1000 : CharStrt=CharEnd
                }
                swbreak
        swend
    }

    CharEnd=SearchToken(p1,CharStrt)
    switch strmid(p1,CharStrt,1)
            case ""
            case ";"
                if Structure=0 : Structure=0x2000
                swbreak
            default
                Mnemonic=StrUpper(strmid(p1,CharStrt,CharEnd-CharStrt))
                CharStrt=CharEnd : CharEnd=SearchToken(p1,CharStrt)
                    switch strmid(p1,CharStrt,1)
                        case ""
                        case ";"
                            Structure=(Structure|0x100)
                            swbreak
                        default
                            Operand=StrUpper(strmid(p1,CharStrt,CharEnd-CharStrt))
                            CharStrt=CharEnd : CharEnd=SearchToken(p1,CharStrt)
                                switch strmid(p1,CharStrt,1)
                                    case ""
                                    case ";"
                                        Structure=(Structure|0x100)
                                        swbreak
                                    default
                                        swbreak
                                swend
                            swbreak
                    swend
                swbreak
        swend
    Structure=Lxean(Operand,1)|Structure    ; Source Operand
    rNoSrc=rNo : rBitSrc=rBit
    Structure=Lxean(Operand,0)<<4|Structure ; Distination Operand
    rNoDst=rNo : rBitDst=rBit

    return

;--------+---------+---------+---------+---------+---------+---------+---------+
; HSP asm
;--------+---------+---------+---------+---------+---------+---------+---------+
#deffunc asm var p1, str p2
    dupptr buf, varptr(p1), length(p1)*4, 4
    buf_ptr = 0 : error = 0
    AsmText = p2
    notesel AsmText
    dim LabelPtr,2,10 : dim JumpPtr,3,256 : JumpCnt=0

    repeat notemax
        noteget TextBuf,cnt
        Parse TextBuf
        assemble Structure&0x1FF
        
        if ListSw {
            if (Structure&0x3000)=0 : TextBuf="\t"+TextBuf
            if ErrorAsm {
                repeat 1 : TextBuf=" "+TextBuf : loop : TextBuf="--- Error"+str(ErrorAsm)+" ---"+TextBuf
            }
            else {
                repeat cnd(Mnemonic="ORG",15,15-(buf_ptr-StrBufptr)*2) : TextBuf=" "+TextBuf : loop
                repeat cnd(Mnemonic="ORG",0,(buf_ptr-StrBufptr)),1
                    TextBuf=strf("%02x",peek(buf,buf_ptr-cnt))+TextBuf
                loop
            }
            TextBuf=strf("%04x",StrBufptr)+" "+TextBuf
            if ListSw&4 : TextBuf=strf("[%05x]",Structure)+" "+TextBuf
        }
        noteadd TextBuf,cnt,1
    loop

    if ListSw {
        if ListSw&2 {
            repeat (buf_ptr/16+1)*4
                if (cnt&3)=0 : AsmText="\n"+AsmText
                AsmText="0x"+strf("%08x",lpeek(buf,((buf_ptr/16+1)*4-cnt-1)*4))+AsmText
                if (cnt&3)!3 : AsmText=","+AsmText
                if (cnt&3)=3 : AsmText=AsmMemory+"(0x"+strf("%02x",((buf_ptr/16+1)*4-cnt-1))+")="+AsmText 
            loop
        }
        if ginfo_sel!AsmScreenId : screen AsmScreenId : font msgothic,16 : objmode 2
        mesbox AsmText,640,150,4 : hwAsmMbx=objinfo_hwnd(stat) : MesTab=16 : mesboxtab hwAsmMbx,MesTab
        ListSw=0
    }

    noteunsel
    return

#global

    _asmscreen nAsmScreen

#endif
#endif