mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-29 17:15:47 +00:00
1264 lines
34 KiB
NASM
1264 lines
34 KiB
NASM
|
TITLE DEBASM
|
|||
|
|
|||
|
; Code for the ASSEMble command in the debugger
|
|||
|
|
|||
|
.xlist
|
|||
|
.xcref
|
|||
|
INCLUDE DEBEQU.ASM
|
|||
|
INCLUDE DOSSYM.ASM
|
|||
|
.cref
|
|||
|
.list
|
|||
|
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC BYTE 'CODE'
|
|||
|
CODE ENDS
|
|||
|
|
|||
|
CONST SEGMENT PUBLIC BYTE
|
|||
|
|
|||
|
EXTRN DBMN:BYTE,CSSAVE:WORD,REG8:BYTE,REG16:BYTE,SIZ8:BYTE
|
|||
|
EXTRN SYNERR:BYTE,OPTAB:BYTE,MAXOP:ABS
|
|||
|
|
|||
|
CONST ENDS
|
|||
|
|
|||
|
DATA SEGMENT PUBLIC BYTE
|
|||
|
|
|||
|
EXTRN HINUM:WORD,LOWNUM:WORD,ASSEM_CNT:BYTE
|
|||
|
EXTRN ASSEM1:BYTE,ASSEM2:BYTE,ASSEM3:BYTE,ASSEM4:BYTE,ASSEM5:BYTE
|
|||
|
EXTRN ASSEM6:BYTE,OPBUF:BYTE,OPCODE:WORD,REGMEM:BYTE,INDEX:WORD
|
|||
|
EXTRN ASMADD:BYTE,ASMSP:WORD,MOVFLG:BYTE,SEGFLG:BYTE,TSTFLG:BYTE
|
|||
|
EXTRN NUMFLG:BYTE,DIRFLG:BYTE,BYTEBUF:BYTE,F8087:BYTE,DIFLG:BYTE
|
|||
|
EXTRN SIFLG:BYTE,BXFLG:BYTE,BPFLG:BYTE,NEGFLG:BYTE,MEMFLG:BYTE
|
|||
|
EXTRN REGFLG:BYTE,AWORD:BYTE,MIDFLD:BYTE,MODE:BYTE
|
|||
|
|
|||
|
DATA ENDS
|
|||
|
|
|||
|
DG GROUP CODE,CONST,DATA
|
|||
|
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC BYTE 'CODE'
|
|||
|
ASSUME CS:DG,DS:DG,ES:DG,SS:DG
|
|||
|
|
|||
|
PUBLIC ASSEM
|
|||
|
PUBLIC DB_OPER,DW_OPER,ASSEMLOOP,GROUP2,AA_OPER,DCINC_OPER
|
|||
|
PUBLIC GROUP1,ESC_OPER,FGROUPP,FGROUPX,FDE_OPER,FGROUPZ
|
|||
|
PUBLIC FD9_OPER,FGROUP,FDB_OPER,FGROUPB,FGROUP3,FGROUP3W
|
|||
|
PUBLIC FGROUPDS,INT_OPER,IN_OPER,DISP8_OPER,JMP_OPER,NO_OPER
|
|||
|
PUBLIC OUT_OPER,L_OPER,MOV_OPER,POP_OPER,PUSH_OPER,ROTOP
|
|||
|
PUBLIC TST_OPER,EX_OPER,GET_DATA16,CALL_OPER
|
|||
|
|
|||
|
EXTRN INBUF:NEAR,SCANB:NEAR,SCANP:NEAR,GETHX:NEAR,GET_ADDRESS:NEAR
|
|||
|
EXTRN DEFAULT:NEAR,OUTDI:NEAR,BLANK:NEAR,PRINTMES:NEAR,TAB:NEAR
|
|||
|
|
|||
|
;
|
|||
|
; Line by line assembler
|
|||
|
;
|
|||
|
|
|||
|
ASSEM:
|
|||
|
MOV BP,[CSSAVE] ; Default code segment
|
|||
|
MOV DI,OFFSET DG:ASMADD ; Default address
|
|||
|
CALL DEFAULT
|
|||
|
MOV WORD PTR [ASMADD],DX ; Displacement of disassembly
|
|||
|
MOV WORD PTR [ASMADD+2],AX ; Segment
|
|||
|
MOV [ASMSP],SP ; Save sp in case of error
|
|||
|
|
|||
|
ASSEMLOOP:
|
|||
|
MOV SP,[ASMSP] ; Restore sp in case of error
|
|||
|
LES DI,DWORD PTR ASMADD ; GET PC
|
|||
|
CALL OUTDI ; OUTPUT ADDRESS
|
|||
|
CALL BLANK ; SKIP A SPACE
|
|||
|
PUSH CS
|
|||
|
POP ES
|
|||
|
CALL INBUF ; GET A BUFFER
|
|||
|
CALL SCANB
|
|||
|
JNZ OPLOOK
|
|||
|
RET ; IF EMPTY JUST RETURN
|
|||
|
;
|
|||
|
; At this point ds:si points to the opcode mnemonic...
|
|||
|
;
|
|||
|
OPLOOK: XOR CX,CX ; OP-CODE COUNT = 0
|
|||
|
MOV DI,OFFSET DG:DBMN
|
|||
|
OPSCAN: XOR BX,BX
|
|||
|
OPLOOP: MOV AL,[DI+BX]
|
|||
|
AND AL,7FH
|
|||
|
CMP AL,[SI+BX]
|
|||
|
JZ OPMATCH
|
|||
|
INC CX ; INCREMENT OP-CODE COUNT
|
|||
|
CMP CX,MAXOP ; CHECK FOR END OF LIST
|
|||
|
JB OP1
|
|||
|
JMP ASMERR
|
|||
|
OP1: INC DI ; SCAN FOR NEXT OP-CODE...
|
|||
|
TEST BYTE PTR [DI-1],80H
|
|||
|
JZ OP1
|
|||
|
JMP OPSCAN
|
|||
|
|
|||
|
OPMATCH:INC BX ; COMPARE NEXT CHAR
|
|||
|
TEST BYTE PTR [DI+BX-1],80H ; ARE WE DONE?
|
|||
|
JZ OPLOOP ; ..IF NOT KEEP COMPARING
|
|||
|
XCHG BX,CX
|
|||
|
MOV AX,BX
|
|||
|
SHL AX,1
|
|||
|
ADD AX,BX
|
|||
|
ADD AX,OFFSET DG:OPTAB
|
|||
|
MOV BX,AX
|
|||
|
;
|
|||
|
; CX = COUNT OF CHARS IN OPCODE
|
|||
|
; BX = POINTER INTO OPCODE TABLE
|
|||
|
;
|
|||
|
XOR AX,AX
|
|||
|
MOV BYTE PTR [AWORD],AL
|
|||
|
MOV WORD PTR [MOVFLG],AX ; MOVFLG + TSTFLG
|
|||
|
MOV BYTE PTR [SEGFLG],AL ; ZERO SEGMENT REGISTER FLAG
|
|||
|
MOV AH,00001010B ; SET UP FOR AA_OPER
|
|||
|
MOV AL,BYTE PTR [BX]
|
|||
|
MOV WORD PTR [ASSEM1],AX
|
|||
|
MOV BYTE PTR [ASSEM_CNT],1
|
|||
|
|
|||
|
ADD SI,CX ; SI POINTS TO OPERAND
|
|||
|
JMP WORD PTR [BX+1]
|
|||
|
;
|
|||
|
; 8087 INSTRUCTIONS WITH NO OPERANDS
|
|||
|
;
|
|||
|
FDE_OPER:
|
|||
|
MOV AH,0DEH
|
|||
|
JMP SHORT FDX_OPER
|
|||
|
FDB_OPER:
|
|||
|
MOV AH,0DBH
|
|||
|
JMP SHORT FDX_OPER
|
|||
|
FD9_OPER:
|
|||
|
MOV AH,0D9H
|
|||
|
FDX_OPER:
|
|||
|
XCHG AL,AH
|
|||
|
MOV WORD PTR [ASSEM1],AX
|
|||
|
;
|
|||
|
; aad and aam instrucions
|
|||
|
;
|
|||
|
AA_OPER:INC BYTE PTR [ASSEM_CNT]
|
|||
|
;
|
|||
|
; instructions with no operands
|
|||
|
;
|
|||
|
NO_OPER:
|
|||
|
CALL STUFF_BYTES
|
|||
|
CALL SCANP
|
|||
|
PUSH CS
|
|||
|
POP ES
|
|||
|
JNZ OPLOOK
|
|||
|
JMP ASSEMLOOP
|
|||
|
;
|
|||
|
; push instruction
|
|||
|
;
|
|||
|
PUSH_OPER:
|
|||
|
MOV AH,11111111B
|
|||
|
JMP SHORT POP1
|
|||
|
;
|
|||
|
; pop instruction
|
|||
|
;
|
|||
|
POP_OPER:
|
|||
|
MOV AH,10001111B
|
|||
|
POP1: MOV [ASSEM1],AH
|
|||
|
MOV [MIDFLD],AL
|
|||
|
INC BYTE PTR [MOVFLG] ; ALLOW SEGMENT REGISTERS
|
|||
|
MOV BYTE PTR [AWORD],2 ; MUST BE 16 BITS
|
|||
|
CALL GETREGMEM
|
|||
|
CALL BUILDIT
|
|||
|
MOV AL,[DI+2]
|
|||
|
CMP AL,11000000B
|
|||
|
JB DATRET
|
|||
|
MOV BYTE PTR [DI],1
|
|||
|
CMP BYTE PTR [MOVFLG],2
|
|||
|
JNZ POP2
|
|||
|
AND AL,00011000B
|
|||
|
OR AL,00000110B
|
|||
|
CMP BYTE PTR [MIDFLD],0
|
|||
|
JNZ POP3
|
|||
|
OR AL,00000001B
|
|||
|
JMP SHORT POP3
|
|||
|
|
|||
|
POP2: AND AL,111B
|
|||
|
OR AL,01010000B
|
|||
|
CMP BYTE PTR [MIDFLD],0
|
|||
|
JNZ POP3
|
|||
|
OR AL,01011000B
|
|||
|
POP3: MOV BYTE PTR [DI+1],AL
|
|||
|
JMP ASSEM_EXIT
|
|||
|
;
|
|||
|
; ret and retf instructions
|
|||
|
;
|
|||
|
GET_DATA16:
|
|||
|
CALL SCANB
|
|||
|
MOV CX,4
|
|||
|
CALL GETHX
|
|||
|
JC DATRET
|
|||
|
DEC BYTE PTR [ASSEM1] ; CHANGE OP-CODE
|
|||
|
ADD BYTE PTR [ASSEM_CNT],2 ; UPDATE LENGTH
|
|||
|
MOV WORD PTR [ASSEM2],DX ; SAVE OFFSET
|
|||
|
DATRET: JMP ASSEM_EXIT
|
|||
|
;
|
|||
|
; int instruction
|
|||
|
;
|
|||
|
INT_OPER:
|
|||
|
CALL SCANB
|
|||
|
MOV CX,2
|
|||
|
CALL GETHX
|
|||
|
JC ERRV1
|
|||
|
MOV AL,DL
|
|||
|
CMP AL,3
|
|||
|
JZ DATRET
|
|||
|
INC BYTE PTR [ASSEM1]
|
|||
|
JMP DISPX
|
|||
|
;
|
|||
|
; in instruction
|
|||
|
;
|
|||
|
IN_OPER:
|
|||
|
CALL SCANB
|
|||
|
LODSW
|
|||
|
CMP AX,"A"+4C00H ; "AL"
|
|||
|
JZ IN_1
|
|||
|
CMP AX,"A"+5800H ; "AX"
|
|||
|
JZ IN_0
|
|||
|
ERRV1: JMP ASMERR
|
|||
|
IN_0: INC BYTE PTR [ASSEM1]
|
|||
|
IN_1: CALL SCANP
|
|||
|
CMP WORD PTR [SI],"D"+5800H ; "DX"
|
|||
|
JZ DATRET
|
|||
|
MOV CX,2
|
|||
|
CALL GETHX
|
|||
|
JC ERRV1
|
|||
|
AND BYTE PTR [ASSEM1],11110111B
|
|||
|
MOV AL,DL
|
|||
|
JMP DISPX
|
|||
|
;
|
|||
|
; out instruction
|
|||
|
;
|
|||
|
OUT_OPER:
|
|||
|
CALL SCANB
|
|||
|
CMP WORD PTR [SI],"D"+5800H ; "DX"
|
|||
|
JNZ OUT_0
|
|||
|
INC SI
|
|||
|
INC SI
|
|||
|
JMP SHORT OUT_1
|
|||
|
OUT_0: AND BYTE PTR [ASSEM1],11110111B
|
|||
|
MOV CX,2
|
|||
|
CALL GETHX
|
|||
|
JC ERRV1
|
|||
|
INC BYTE PTR [ASSEM_CNT]
|
|||
|
MOV BYTE PTR [ASSEM2],DL
|
|||
|
OUT_1: CALL SCANP
|
|||
|
LODSW
|
|||
|
CMP AX,"A"+4C00H ; "AL"
|
|||
|
JZ DATRET
|
|||
|
CMP AX,"A"+5800H ; "AX"
|
|||
|
JNZ ERRV1
|
|||
|
INC BYTE PTR [ASSEM1]
|
|||
|
JMP DATRET
|
|||
|
|
|||
|
;
|
|||
|
; jump instruction
|
|||
|
;
|
|||
|
JMP_OPER:
|
|||
|
INC BYTE PTR [TSTFLG]
|
|||
|
;
|
|||
|
; call instruction
|
|||
|
;
|
|||
|
CALL_OPER:
|
|||
|
MOV BYTE PTR [ASSEM1],11111111B
|
|||
|
MOV BYTE PTR [MIDFLD],AL
|
|||
|
CALL GETREGMEM
|
|||
|
CALL BUILD3
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JNZ CALLJ1
|
|||
|
CMP BYTE PTR [REGMEM],-1
|
|||
|
JZ CALLJ2
|
|||
|
;
|
|||
|
; INDIRECT JUMPS OR CALLS
|
|||
|
;
|
|||
|
CALLJ1: CMP BYTE PTR [AWORD],1
|
|||
|
ERRZ4: JZ ERRV1
|
|||
|
CMP BYTE PTR [AWORD],4
|
|||
|
JNZ ASMEX4
|
|||
|
OR BYTE PTR [DI+2],1000B
|
|||
|
JMP SHORT ASMEX4
|
|||
|
;
|
|||
|
; DIRECT JUMPS OR CALLS
|
|||
|
;
|
|||
|
CALLJ2: MOV AX,[LOWNUM]
|
|||
|
MOV DX,[HINUM]
|
|||
|
MOV BL,[AWORD]
|
|||
|
CMP BYTE PTR [NUMFLG],0
|
|||
|
JZ ERRZ4
|
|||
|
|
|||
|
; BL = NUMBER OF BYTES IN JUMP
|
|||
|
; DX = OFFSET
|
|||
|
; AX = SEGMENT
|
|||
|
|
|||
|
CALLJ3:
|
|||
|
MOV BYTE PTR [DI],5
|
|||
|
MOV [DI+2],AX
|
|||
|
MOV [DI+4],DX
|
|||
|
|
|||
|
MOV AL,10011010B ; SET UP INTER SEGMENT CALL
|
|||
|
CMP BYTE PTR [TSTFLG],0
|
|||
|
JZ CALLJ5
|
|||
|
MOV AL,11101010B ; FIX UP FOR JUMP
|
|||
|
CALLJ5: MOV BYTE PTR [DI+1],AL
|
|||
|
CMP BL,4 ; FAR SPECIFIED?
|
|||
|
JZ ASMEX4
|
|||
|
OR BL,BL
|
|||
|
JNZ CALLJ6
|
|||
|
CMP DX,WORD PTR [ASMADD+2] ; DIFFERENT SEGMENT?
|
|||
|
JNZ ASMEX4
|
|||
|
|
|||
|
CALLJ6: MOV BYTE PTR [DI],3
|
|||
|
MOV AL,11101000B ; SET UP FOR INTRASEGMENT
|
|||
|
OR AL,[TSTFLG]
|
|||
|
MOV BYTE PTR [DI+1],AL
|
|||
|
|
|||
|
MOV AX,[LOWNUM]
|
|||
|
SUB AX,WORD PTR [ASMADD]
|
|||
|
SUB AX,3
|
|||
|
MOV [DI+2],AX
|
|||
|
CMP BYTE PTR [TSTFLG],0
|
|||
|
JZ ASMEX4
|
|||
|
CMP BL,2
|
|||
|
JZ ASMEX4
|
|||
|
|
|||
|
INC AX
|
|||
|
MOV CX,AX
|
|||
|
CBW
|
|||
|
CMP AX,CX
|
|||
|
JNZ ASMEX3
|
|||
|
MOV BYTE PTR [DI+1],11101011B
|
|||
|
MOV [DI+2],AX
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
ASMEX4: JMP ASSEM_EXIT
|
|||
|
;
|
|||
|
; conditional jumps and loop instructions
|
|||
|
;
|
|||
|
DISP8_OPER:
|
|||
|
MOV BP,WORD PTR [ASMADD+2] ; GET DEFAULT DISPLACEMENT
|
|||
|
CALL GET_ADDRESS
|
|||
|
SUB DX,WORD PTR [ASMADD]
|
|||
|
DEC DX
|
|||
|
DEC DX
|
|||
|
CALL CHKSIZ
|
|||
|
CMP CL,1
|
|||
|
JNZ ERRV2
|
|||
|
DISPX: INC [ASSEM_CNT]
|
|||
|
MOV BYTE PTR [ASSEM2],AL
|
|||
|
ASMEX3: JMP ASSEM_EXIT
|
|||
|
;
|
|||
|
; lds, les, and lea instructions
|
|||
|
;
|
|||
|
L_OPER:
|
|||
|
CALL SCANB
|
|||
|
LODSW
|
|||
|
MOV CX,8
|
|||
|
MOV DI,OFFSET DG:REG16
|
|||
|
CALL CHKREG
|
|||
|
JZ ERRV2 ; CX = 0 MEANS NO REGISTER
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
MOV BYTE PTR [MIDFLD],AL
|
|||
|
CALL SCANP
|
|||
|
CALL GETREGMEM
|
|||
|
CMP BYTE PTR [AWORD],0
|
|||
|
JNZ ERRV2
|
|||
|
CALL BUILD2
|
|||
|
JMP SHORT ASEXV
|
|||
|
;
|
|||
|
; dec and inc instructions
|
|||
|
;
|
|||
|
DCINC_OPER:
|
|||
|
MOV BYTE PTR [ASSEM1],11111110B
|
|||
|
MOV BYTE PTR [MIDFLD],AL
|
|||
|
CALL GETREGMEM
|
|||
|
CALL BUILDIT
|
|||
|
TEST BYTE PTR [DI+1],1
|
|||
|
JZ ASEXV
|
|||
|
MOV AL,[DI+2]
|
|||
|
CMP AL,11000000B
|
|||
|
JB ASEXV
|
|||
|
AND AL,1111B
|
|||
|
OR AL,01000000B
|
|||
|
MOV [DI+1],AL
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
ASEXV: JMP ASSEM_EXIT
|
|||
|
|
|||
|
ERRV2: JMP ASMERR
|
|||
|
;
|
|||
|
; esc instruction
|
|||
|
;
|
|||
|
ESC_OPER:
|
|||
|
INC BYTE PTR [AWORD]
|
|||
|
CALL SCANB
|
|||
|
MOV CX,2
|
|||
|
CALL GETHX
|
|||
|
CMP DX,64
|
|||
|
JAE ERRV2
|
|||
|
CALL SCANP
|
|||
|
MOV AX,DX
|
|||
|
MOV CL,3
|
|||
|
SHR DX,CL
|
|||
|
OR [ASSEM1],DL
|
|||
|
AND AL,111B
|
|||
|
SHL AL,CL
|
|||
|
JMP GROUPE
|
|||
|
;
|
|||
|
; 8087 arithmetic instuctions
|
|||
|
;
|
|||
|
|
|||
|
;
|
|||
|
; OPERANDS THAT ALLOW THE REVERSE BIT
|
|||
|
;
|
|||
|
FGROUPDS:
|
|||
|
CALL SETMID
|
|||
|
CALL GETREGMEM2
|
|||
|
CALL BUILD3
|
|||
|
CMP BYTE PTR [MODE],11000000B
|
|||
|
JNZ FGROUP1
|
|||
|
MOV AL,[DIRFLG]
|
|||
|
OR AL,AL
|
|||
|
JZ FEXIT
|
|||
|
OR [DI+1],AL ; IF D=1...
|
|||
|
XOR BYTE PTR [DI+2],00001000B ; ...REVERSE THE SENSE OF R
|
|||
|
JMP SHORT FEXIT
|
|||
|
|
|||
|
;
|
|||
|
; Here when instruction could have memory or register operand
|
|||
|
;
|
|||
|
FGROUPX:
|
|||
|
CALL SETMID ; THIS ENTRY POINT FOR 1 MEM OPER
|
|||
|
MOV BYTE PTR [DIRFLG],0
|
|||
|
JMP SHORT FGRP2
|
|||
|
FGROUP:
|
|||
|
CALL SETMID
|
|||
|
FGRP2:
|
|||
|
CALL GETREGMEM2
|
|||
|
CALL BUILD3
|
|||
|
CMP BYTE PTR [MODE],11000000B
|
|||
|
JNZ FGROUP1
|
|||
|
MOV AL,[DIRFLG]
|
|||
|
OR [DI+1],AL
|
|||
|
JMP SHORT FEXIT
|
|||
|
FGROUP1:CALL SETMF
|
|||
|
FEXIT: JMP ASSEM_EXIT
|
|||
|
;
|
|||
|
; These 8087 instructions require a memory operand
|
|||
|
;
|
|||
|
FGROUPB:
|
|||
|
MOV AH,5 ; MUST BE TBYTE
|
|||
|
JMP SHORT FGROUP3E
|
|||
|
FGROUP3W:
|
|||
|
MOV AH,2 ; MUST BE WORD
|
|||
|
JMP SHORT FGROUP3E
|
|||
|
FGROUP3:
|
|||
|
MOV AH,-1 ; SIZE CANNOT BE SPECIFIED
|
|||
|
FGROUP3E:
|
|||
|
MOV [AWORD],AH
|
|||
|
CALL SETMID
|
|||
|
CALL GETREGMEM
|
|||
|
CMP BYTE PTR [MODE],11000000B
|
|||
|
JZ FGRPERR
|
|||
|
FGRP:
|
|||
|
CALL BUILD3
|
|||
|
JMP FEXIT
|
|||
|
;
|
|||
|
; These 8087 instructions require a register operand
|
|||
|
;
|
|||
|
FGROUPP: ; 8087 POP OPERANDS
|
|||
|
MOV BYTE PTR [AWORD],-1
|
|||
|
CALL SETMID
|
|||
|
CALL GETREGMEM2
|
|||
|
CMP BYTE PTR [DIRFLG],0
|
|||
|
JNZ FGRP
|
|||
|
FGRPERR:JMP ASMERR
|
|||
|
|
|||
|
FGROUPZ: ; ENTRY POINT WHERE ARG MUST BE MEM
|
|||
|
CALL SETMID
|
|||
|
MOV BYTE PTR [DIRFLG],0
|
|||
|
CALL GETREGMEM
|
|||
|
CMP BYTE PTR [MODE],11000000B
|
|||
|
JZ FGRPERR
|
|||
|
CALL BUILD3
|
|||
|
CALL SETMF
|
|||
|
JMP FEXIT
|
|||
|
;
|
|||
|
; not, neg, mul, imul, div, and idiv instructions
|
|||
|
;
|
|||
|
GROUP1:
|
|||
|
MOV [ASSEM1],11110110B
|
|||
|
GROUPE:
|
|||
|
MOV BYTE PTR [MIDFLD],AL
|
|||
|
CALL GETREGMEM
|
|||
|
CALL BUILDIT
|
|||
|
JMP FEXIT
|
|||
|
;
|
|||
|
; shift and rotate instructions
|
|||
|
;
|
|||
|
ROTOP:
|
|||
|
MOV [ASSEM1],11010000B
|
|||
|
MOV BYTE PTR [MIDFLD],AL
|
|||
|
CALL GETREGMEM
|
|||
|
CALL BUILDIT
|
|||
|
CALL SCANP
|
|||
|
CMP BYTE PTR [SI],"1"
|
|||
|
JZ ASMEXV1
|
|||
|
CMP WORD PTR [SI],"LC" ; CL
|
|||
|
JZ ROTOP1
|
|||
|
ROTERR: JMP ASMERR
|
|||
|
ROTOP1: OR BYTE PTR [ASSEM1],10B
|
|||
|
ASMEXV1:JMP ASSEM_EXIT
|
|||
|
;
|
|||
|
; xchg instruction
|
|||
|
;
|
|||
|
EX_OPER:
|
|||
|
INC BYTE PTR [TSTFLG]
|
|||
|
;
|
|||
|
; test instruction
|
|||
|
;
|
|||
|
TST_OPER:
|
|||
|
INC BYTE PTR [TSTFLG]
|
|||
|
JMP SHORT MOVOP
|
|||
|
;
|
|||
|
; mov instruction
|
|||
|
;
|
|||
|
MOV_OPER:
|
|||
|
INC BYTE PTR [MOVFLG]
|
|||
|
MOVOP: XOR AX,AX
|
|||
|
JMP SHORT GROUPM
|
|||
|
;
|
|||
|
; add, adc, sub, sbb, cmp, and, or, xor instructions
|
|||
|
;
|
|||
|
GROUP2:
|
|||
|
MOV BYTE PTR [ASSEM1],10000000B
|
|||
|
GROUPM:
|
|||
|
MOV BYTE PTR [MIDFLD],AL
|
|||
|
|
|||
|
PUSH AX
|
|||
|
CALL GETREGMEM
|
|||
|
CALL BUILD2
|
|||
|
CALL SCANP ; POINT TO NEXT OPERAND
|
|||
|
MOV AL,BYTE PTR [ASSEM_CNT]
|
|||
|
PUSH AX
|
|||
|
CALL GETREGMEM
|
|||
|
POP AX
|
|||
|
MOV BYTE PTR [DI],AL
|
|||
|
POP AX
|
|||
|
MOV BL,BYTE PTR [AWORD]
|
|||
|
OR BL,BL
|
|||
|
JZ ERRV5
|
|||
|
DEC BL
|
|||
|
AND BL,1
|
|||
|
OR BYTE PTR [DI+1],BL
|
|||
|
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JNZ G21V
|
|||
|
CMP BYTE PTR [NUMFLG],0 ; TEST FOR IMMEDIATE DATA
|
|||
|
JZ G21V
|
|||
|
CMP BYTE PTR [SEGFLG],0
|
|||
|
JNZ ERRV5
|
|||
|
CMP BYTE PTR [TSTFLG],2 ; XCHG?
|
|||
|
JNZ IMMED1
|
|||
|
ERRV5: JMP ASMERR
|
|||
|
G21V: JMP GRP21
|
|||
|
;
|
|||
|
; SECOND OPERAND WAS IMMEDIATE
|
|||
|
;
|
|||
|
IMMED1: MOV AL,BYTE PTR [DI+2]
|
|||
|
CMP BYTE PTR [MOVFLG],0
|
|||
|
JZ NOTMOV1
|
|||
|
AND AL,11000000B
|
|||
|
CMP AL,11000000B
|
|||
|
JNZ GRP23 ; not to a register
|
|||
|
; MOVE IMMEDIATE TO REGISTER
|
|||
|
MOV AL,BYTE PTR [DI+1]
|
|||
|
AND AL,1 ; SET SIZE
|
|||
|
PUSHF
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
OR AL,BYTE PTR [DI+2] ; SET REGISTER
|
|||
|
AND AL,00001111B
|
|||
|
OR AL,10110000B
|
|||
|
MOV BYTE PTR [DI+1],AL
|
|||
|
MOV AX,WORD PTR [LOWNUM]
|
|||
|
MOV WORD PTR [DI+2],AX
|
|||
|
POPF
|
|||
|
JZ EXVEC
|
|||
|
INC BYTE PTR [DI]
|
|||
|
EXVEC: JMP GRPEX
|
|||
|
|
|||
|
NOTMOV1:AND AL,11000111B
|
|||
|
CMP AL,11000000B
|
|||
|
JZ IMMACC ; IMMEDIATE TO ACC
|
|||
|
|
|||
|
CMP BYTE PTR [TSTFLG],0
|
|||
|
JNZ GRP23
|
|||
|
CMP BYTE PTR [MIDFLD],1*8 ; OR?
|
|||
|
JZ GRP23
|
|||
|
CMP BYTE PTR [MIDFLD],4*8 ; AND?
|
|||
|
JZ GRP23
|
|||
|
CMP BYTE PTR [MIDFLD],6*8 ; XOR?
|
|||
|
JZ GRP23
|
|||
|
TEST BYTE PTR [DI+1],1 ; TEST IF BYTE OPCODE
|
|||
|
JZ GRP23
|
|||
|
|
|||
|
MOV AX,[LOWNUM]
|
|||
|
MOV BX,AX
|
|||
|
CBW
|
|||
|
CMP AX,BX
|
|||
|
JNZ GRP23 ; SMALL ENOUGH?
|
|||
|
|
|||
|
MOV BL,[DI]
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
OR BYTE PTR [DI+1],10B
|
|||
|
JMP SHORT GRP23X
|
|||
|
|
|||
|
IMMACC: MOV AL,BYTE PTR [DI+1]
|
|||
|
AND AL,1
|
|||
|
CMP BYTE PTR [TSTFLG],0
|
|||
|
JZ NOTTST
|
|||
|
OR AL,10101000B
|
|||
|
JMP SHORT TEST1
|
|||
|
NOTTST: OR AL,BYTE PTR [MIDFLD]
|
|||
|
OR AL,100B
|
|||
|
TEST1: MOV BYTE PTR [DI+1],AL
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
|
|||
|
GRP23: MOV BL,BYTE PTR [DI]
|
|||
|
GRP23X: XOR BH,BH
|
|||
|
ADD BX,DI
|
|||
|
INC BX
|
|||
|
MOV AX,WORD PTR [LOWNUM]
|
|||
|
MOV WORD PTR [BX],AX
|
|||
|
INC BYTE PTR [DI]
|
|||
|
TEST BYTE PTR [DI+1],1
|
|||
|
JZ GRPEX1
|
|||
|
INC BYTE PTR [DI]
|
|||
|
GRPEX1: JMP GRPEX
|
|||
|
;
|
|||
|
; SECOND OPERAND WAS MEMORY OR REGISTER
|
|||
|
;
|
|||
|
GRP21:
|
|||
|
CMP BYTE PTR [SEGFLG],0
|
|||
|
JZ GRP28 ; FIRST OPERAND WAS A SEGMENT REG
|
|||
|
MOV AL,BYTE PTR [REGMEM]
|
|||
|
TEST AL,10000B
|
|||
|
JZ NOTSEG1
|
|||
|
ERRV3: JMP ASMERR
|
|||
|
NOTSEG1:AND AL,111B
|
|||
|
OR BYTE PTR [DI+2],AL
|
|||
|
AND BYTE PTR [DI+1],11111110B
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JNZ G22V
|
|||
|
JMP GRPEX
|
|||
|
|
|||
|
GRP28: AND BYTE PTR [DI+2],11000111B
|
|||
|
MOV AL,BYTE PTR [DI+1] ; GET FIRST OPCODE
|
|||
|
AND AL,1B
|
|||
|
CMP BYTE PTR [MOVFLG],0
|
|||
|
JZ NOTMOV2
|
|||
|
OR AL,10001000B
|
|||
|
JMP SHORT MOV1
|
|||
|
NOTMOV2:CMP BYTE PTR [TSTFLG],0
|
|||
|
JZ NOTTST2
|
|||
|
OR AL,10000100B
|
|||
|
CMP BYTE PTR [TSTFLG],2
|
|||
|
JNZ NOTTST2
|
|||
|
OR AL,10B
|
|||
|
NOTTST2:OR AL,BYTE PTR [MIDFLD] ; MIDFLD IS ZERO FOR TST
|
|||
|
MOV1: MOV BYTE PTR [DI+1],AL
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
G22V: JNZ GRP22
|
|||
|
;
|
|||
|
; SECOND OPERAND WAS A REGISTER
|
|||
|
;
|
|||
|
MOV AL,BYTE PTR [REGMEM]
|
|||
|
TEST AL,10000B ; SEGMENT REGISTER?
|
|||
|
JZ NOTSEG
|
|||
|
CMP BYTE PTR [MOVFLG],0
|
|||
|
JZ ERRV3
|
|||
|
MOV BYTE PTR [DI+1],10001100B
|
|||
|
|
|||
|
NOTSEG: AND AL,111B
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
OR BYTE PTR [DI+2],AL
|
|||
|
;
|
|||
|
; SPECIAL FORM OF THE EXCHANGE COMMAND
|
|||
|
;
|
|||
|
CMP BYTE PTR [TSTFLG],2
|
|||
|
JNZ GRPEX
|
|||
|
TEST BYTE PTR [DI+1],1
|
|||
|
JZ GRPEX
|
|||
|
PUSH AX
|
|||
|
MOV AL,BYTE PTR [DI+2]
|
|||
|
AND AL,11000000B
|
|||
|
CMP AL,11000000B ; MUST BE REGISTER TO REGISTER
|
|||
|
POP AX
|
|||
|
JB GRPEX
|
|||
|
OR AL,AL
|
|||
|
JZ SPECX
|
|||
|
MOV AL,[DI+2]
|
|||
|
AND AL,00000111B
|
|||
|
JNZ GRPEX
|
|||
|
MOV CL,3
|
|||
|
SHR BYTE PTR [DI+2],CL
|
|||
|
SPECX: MOV AL,[DI+2]
|
|||
|
AND AL,00000111B
|
|||
|
OR AL,10010000B
|
|||
|
MOV BYTE PTR [DI+1],AL
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
JMP SHORT GRPEX
|
|||
|
;
|
|||
|
; SECOND OPERAND WAS A MEMORY REFERENCE
|
|||
|
;
|
|||
|
GRP22: CMP BYTE PTR [TSTFLG],0
|
|||
|
JNZ TST2
|
|||
|
OR BYTE PTR [DI+1],10B
|
|||
|
TST2: MOV AL,BYTE PTR [DI+2]
|
|||
|
CMP AL,11000000B ; MUST BE A REGISTER
|
|||
|
JB ASMERR
|
|||
|
CMP BYTE PTR [SEGFLG],0
|
|||
|
JZ GRP223
|
|||
|
AND AL,00011000B
|
|||
|
JMP SHORT GRP222
|
|||
|
GRP223: AND AL,111B
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
GRP222: OR AL,BYTE PTR [MODE]
|
|||
|
OR AL,BYTE PTR [REGMEM]
|
|||
|
MOV BYTE PTR [DI+2],AL
|
|||
|
MOV AX,WORD PTR [LOWNUM]
|
|||
|
MOV WORD PTR [DI+3],AX
|
|||
|
GRPSIZ: MOV BYTE PTR [DI],2
|
|||
|
MOV AL,BYTE PTR [DI+2]
|
|||
|
AND AL,11000111B
|
|||
|
CMP AL,00000110B
|
|||
|
JZ GRP24
|
|||
|
AND AL,11000000B
|
|||
|
CMP AL,01000000B
|
|||
|
JZ GRP25
|
|||
|
CMP AL,10000000B
|
|||
|
JNZ GRPEX
|
|||
|
GRP24: INC BYTE PTR [DI]
|
|||
|
GRP25: INC BYTE PTR [DI]
|
|||
|
|
|||
|
GRPEX: CMP BYTE PTR [MOVFLG],0
|
|||
|
JZ ASSEM_EXIT
|
|||
|
;
|
|||
|
; TEST FOR SPECIAL FORM OF MOV AX,[MEM] OR MOV [MEM],AX
|
|||
|
;
|
|||
|
MOV AL,[DI+1] ; GET OP-CODE
|
|||
|
AND AL,11111100B
|
|||
|
CMP AL,10001000B
|
|||
|
JNZ ASSEM_EXIT
|
|||
|
CMP BYTE PTR [DI+2],00000110B ; MEM TO AX OR AX TO MEM
|
|||
|
JNZ ASSEM_EXIT
|
|||
|
MOV AL,BYTE PTR [DI+1]
|
|||
|
AND AL,11B
|
|||
|
XOR AL,10B
|
|||
|
OR AL,10100000B
|
|||
|
MOV BYTE PTR [DI+1],AL
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
MOV AX,[DI+3]
|
|||
|
MOV WORD PTR [DI+2],AX
|
|||
|
|
|||
|
ASSEM_EXIT:
|
|||
|
CALL STUFF_BYTES
|
|||
|
JMP ASSEMLOOP
|
|||
|
|
|||
|
; Assem error. SI points to character in the input buffer
|
|||
|
; which caused error. By subtracting from start of buffer,
|
|||
|
; we will know how far to tab over to appear directly below
|
|||
|
; it on the terminal. Then print "^ Error".
|
|||
|
|
|||
|
ASMERR:
|
|||
|
SUB SI,OFFSET DG:(BYTEBUF-10) ; How many char processed so far?
|
|||
|
MOV CX,SI ; Parameter for TAB in CX
|
|||
|
CALL TAB ; Directly below bad char
|
|||
|
MOV SI,OFFSET DG:SYNERR ; Error message
|
|||
|
CALL PRINTMES
|
|||
|
JMP ASSEMLOOP
|
|||
|
;
|
|||
|
; assemble the different parts into an instruction
|
|||
|
;
|
|||
|
BUILDIT:
|
|||
|
MOV AL,BYTE PTR [AWORD]
|
|||
|
OR AL,AL
|
|||
|
JNZ BUILD1
|
|||
|
BLDERR: JMP ASMERR
|
|||
|
|
|||
|
BUILD1: DEC AL
|
|||
|
OR BYTE PTR [DI+1],AL ; SET THE SIZE
|
|||
|
|
|||
|
BUILD2: CMP BYTE PTR [NUMFLG],0 ; TEST FOR IMMEDIATE DATA
|
|||
|
JZ BUILD3
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JZ BLDERR
|
|||
|
|
|||
|
BUILD3: MOV AL,BYTE PTR [REGMEM]
|
|||
|
CMP AL,-1
|
|||
|
JZ BLD1
|
|||
|
TEST AL,10000B ; TEST IF SEGMENT REGISTER
|
|||
|
JZ BLD1
|
|||
|
CMP BYTE PTR [MOVFLG],0
|
|||
|
JZ BLDERR
|
|||
|
MOV WORD PTR [DI+1],10001110B
|
|||
|
INC BYTE PTR [MOVFLG]
|
|||
|
INC BYTE PTR [SEGFLG]
|
|||
|
AND AL,00000011B
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
OR AL,BYTE PTR 11000000B
|
|||
|
MOV BYTE PTR [DI+2],AL
|
|||
|
RET
|
|||
|
|
|||
|
BLD1: AND AL,00000111B
|
|||
|
BLD4: OR AL,BYTE PTR [MODE]
|
|||
|
OR AL,BYTE PTR [MIDFLD]
|
|||
|
MOV BYTE PTR [DI+2],AL
|
|||
|
MOV AX,WORD PTR [LOWNUM]
|
|||
|
MOV WORD PTR [DI+3],AX
|
|||
|
RET
|
|||
|
|
|||
|
GETREGMEM:
|
|||
|
MOV BYTE PTR [F8087],0
|
|||
|
GETREGMEM2:
|
|||
|
CALL SCANP
|
|||
|
XOR AX,AX
|
|||
|
MOV WORD PTR [LOWNUM],AX ; OFFSET
|
|||
|
MOV WORD PTR [DIFLG],AX ; DIFLG+SIFLG
|
|||
|
MOV WORD PTR [BXFLG],AX ; BXFLG+BPFLG
|
|||
|
MOV WORD PTR [NEGFLG],AX ; NEGFLG+NUMFLG
|
|||
|
MOV WORD PTR [MEMFLG],AX ; MEMFLG+REGFLG
|
|||
|
DEC AL
|
|||
|
CMP BYTE PTR [F8087],0
|
|||
|
JZ PUTREG
|
|||
|
MOV AL,1 ; DEFAULT 8087 REG IS 1
|
|||
|
PUTREG: MOV BYTE PTR [REGMEM],AL
|
|||
|
|
|||
|
GETLOOP:MOV BYTE PTR [NEGFLG],0
|
|||
|
GETLOOP1:
|
|||
|
MOV AX,WORD PTR [SI]
|
|||
|
CMP AL,','
|
|||
|
JZ GOMODE
|
|||
|
CMP AL,13
|
|||
|
JZ GOMODE
|
|||
|
CMP AL,';'
|
|||
|
JZ GOMODE
|
|||
|
CMP AL,9
|
|||
|
JZ GETTB
|
|||
|
CMP AL,' '
|
|||
|
JNZ GOGET
|
|||
|
GETTB: INC SI
|
|||
|
JMP GETLOOP1
|
|||
|
GOGET: JMP GETINFO
|
|||
|
;
|
|||
|
; DETERMINE THE MODE BITS
|
|||
|
;
|
|||
|
GOMODE: MOV DI,OFFSET DG:ASSEM_CNT
|
|||
|
MOV BYTE PTR [MODE],11000000B
|
|||
|
MOV BYTE PTR [ASSEM_CNT],2
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JNZ GOMODE1
|
|||
|
MOV AL,[NUMFLG]
|
|||
|
OR AL,[REGFLG]
|
|||
|
JNZ MORET
|
|||
|
OR AL,[F8087]
|
|||
|
JZ ERRET
|
|||
|
MOV AL,[DI+1]
|
|||
|
OR AL,[DIRFLG]
|
|||
|
CMP AL,0DCH ; ARITHMETIC?
|
|||
|
JNZ MORET
|
|||
|
MOV BYTE PTR [DI+1],0DEH ; ADD POP TO NULL ARG 8087
|
|||
|
MORET: RET
|
|||
|
ERRET: JMP ASMERR
|
|||
|
|
|||
|
GOMODE1:MOV BYTE PTR [MODE],0
|
|||
|
CMP BYTE PTR [NUMFLG],0
|
|||
|
JZ GOREGMEM
|
|||
|
|
|||
|
MOV BYTE PTR [DI],4
|
|||
|
MOV AX,WORD PTR [DIFLG]
|
|||
|
OR AX,WORD PTR [BXFLG]
|
|||
|
JNZ GOMODE2
|
|||
|
MOV BYTE PTR [REGMEM],00000110B
|
|||
|
RET
|
|||
|
|
|||
|
GOMODE2:MOV BYTE PTR [MODE],10000000B
|
|||
|
CALL CHKSIZ1
|
|||
|
CMP CL,2
|
|||
|
JZ GOREGMEM
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
MOV BYTE PTR [MODE],01000000B
|
|||
|
;
|
|||
|
; DETERMINE THE REG-MEM BITS
|
|||
|
;
|
|||
|
GOREGMEM:
|
|||
|
MOV BX,WORD PTR [BXFLG]
|
|||
|
MOV CX,WORD PTR [DIFLG]
|
|||
|
XOR DX,DX
|
|||
|
GOREG0:
|
|||
|
MOV AL,BL ; BX
|
|||
|
ADD AL,CH ; SI
|
|||
|
CMP AL,2
|
|||
|
JZ GOGO
|
|||
|
INC DL
|
|||
|
MOV AL,BL
|
|||
|
ADD AL,CL
|
|||
|
CMP AL,2
|
|||
|
JZ GOGO
|
|||
|
INC DL
|
|||
|
MOV AL,BH
|
|||
|
ADD AL,CH
|
|||
|
CMP AL,2
|
|||
|
JZ GOGO
|
|||
|
INC DL
|
|||
|
MOV AL,BH
|
|||
|
ADD AL,CL
|
|||
|
CMP AL,2
|
|||
|
JZ GOGO
|
|||
|
INC DL
|
|||
|
OR CH,CH
|
|||
|
JNZ GOGO
|
|||
|
INC DL
|
|||
|
OR CL,CL
|
|||
|
JNZ GOGO
|
|||
|
INC DL ; BP+DISP
|
|||
|
OR BH,BH
|
|||
|
JZ GOREG1
|
|||
|
CMP BYTE PTR [MODE],0
|
|||
|
JNZ GOGO
|
|||
|
MOV BYTE PTR [MODE],01000000B
|
|||
|
INC BYTE PTR [DI]
|
|||
|
DEC DL
|
|||
|
GOREG1: INC DL ; BX+DISP
|
|||
|
GOGO: MOV BYTE PTR [REGMEM],DL
|
|||
|
RET
|
|||
|
|
|||
|
GETINFO:CMP AX,'EN' ; NEAR
|
|||
|
JNZ GETREG3
|
|||
|
GETREG0:MOV DL,2
|
|||
|
GETRG01:CALL SETSIZ1
|
|||
|
GETREG1:CALL SCANS
|
|||
|
MOV AX,WORD PTR [SI]
|
|||
|
CMP AX,"TP" ; PTR
|
|||
|
JZ GETREG1
|
|||
|
JMP GETLOOP
|
|||
|
|
|||
|
GETREG3:MOV CX,5
|
|||
|
MOV DI,OFFSET DG:SIZ8
|
|||
|
CALL CHKREG ; LOOK FOR BYTE, WORD, DWORD, ETC.
|
|||
|
JZ GETREG41
|
|||
|
INC AL
|
|||
|
MOV DL,AL
|
|||
|
JMP GETRG01
|
|||
|
|
|||
|
GETREG41:
|
|||
|
MOV AX,[SI]
|
|||
|
CMP BYTE PTR [F8087],0
|
|||
|
JZ GETREG5
|
|||
|
CMP AX,"TS" ; 8087 STACK OPERAND
|
|||
|
JNZ GETREG5
|
|||
|
CMP BYTE PTR [SI+2],","
|
|||
|
JNZ GETREG5
|
|||
|
MOV BYTE PTR [DIRFLG],0
|
|||
|
ADD SI,3
|
|||
|
JMP GETLOOP
|
|||
|
|
|||
|
GETREG5:CMP AX,"HS" ; SHORT
|
|||
|
JZ GETREG1
|
|||
|
|
|||
|
CMP AX,"AF" ; FAR
|
|||
|
JNZ GETRG51
|
|||
|
CMP BYTE PTR [SI+2],"R"
|
|||
|
JNZ GETRG51
|
|||
|
ADD SI,3
|
|||
|
MOV DL,4
|
|||
|
JMP GETRG01
|
|||
|
|
|||
|
GETRG51:CMP AL,'['
|
|||
|
JNZ GETREG7
|
|||
|
GETREG6:INC BYTE PTR [MEMFLG]
|
|||
|
INC SI
|
|||
|
JMP GETLOOP
|
|||
|
|
|||
|
GETREG7:CMP AL,']'
|
|||
|
JZ GETREG6
|
|||
|
CMP AL,'.'
|
|||
|
JZ GETREG6
|
|||
|
CMP AL,'+'
|
|||
|
JZ GETREG6
|
|||
|
CMP AL,'-'
|
|||
|
JNZ GETREG8
|
|||
|
INC BYTE PTR [NEGFLG]
|
|||
|
INC SI
|
|||
|
JMP GETLOOP1
|
|||
|
|
|||
|
GETREG8: ; LOOK FOR A REGISTER
|
|||
|
CMP BYTE PTR [F8087],0
|
|||
|
JZ GETREGREG
|
|||
|
CMP AX,"TS"
|
|||
|
JNZ GETREGREG
|
|||
|
CMP BYTE PTR [SI+2],"("
|
|||
|
JNZ GETREGREG
|
|||
|
CMP BYTE PTR [SI+4],")"
|
|||
|
JNZ ASMPOP
|
|||
|
MOV AL,[SI+3]
|
|||
|
SUB AL,"0"
|
|||
|
JB ASMPOP
|
|||
|
CMP AL,7
|
|||
|
JA ASMPOP
|
|||
|
MOV [REGMEM],AL
|
|||
|
INC BYTE PTR [REGFLG]
|
|||
|
ADD SI,5
|
|||
|
CMP WORD PTR [SI],"S,"
|
|||
|
JNZ ZLOOP
|
|||
|
CMP BYTE PTR [SI+2],"T"
|
|||
|
JNZ ZLOOP
|
|||
|
ADD SI,3
|
|||
|
ZLOOP: JMP GETLOOP
|
|||
|
|
|||
|
GETREGREG:
|
|||
|
MOV CX,20
|
|||
|
MOV DI,OFFSET DG:REG8
|
|||
|
CALL CHKREG
|
|||
|
JZ GETREG12 ; CX = 0 MEANS NO REGISTER
|
|||
|
MOV BYTE PTR [REGMEM],AL
|
|||
|
INC BYTE PTR [REGFLG] ; TELL EVERYONE WE FOUND A REG
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JNZ NOSIZE
|
|||
|
CALL SETSIZ
|
|||
|
INCSI2: ADD SI,2
|
|||
|
JMP GETLOOP
|
|||
|
|
|||
|
NOSIZE: CMP AL,11 ; BX REGISTER?
|
|||
|
JNZ GETREG9
|
|||
|
CMP WORD PTR [BXFLG],0
|
|||
|
JZ GETOK
|
|||
|
ASMPOP: JMP ASMERR
|
|||
|
|
|||
|
GETOK: INC BYTE PTR [BXFLG]
|
|||
|
JMP INCSI2
|
|||
|
GETREG9:
|
|||
|
CMP AL,13 ; BP REGISTER?
|
|||
|
JNZ GETREG10
|
|||
|
CMP WORD PTR [BXFLG],0
|
|||
|
JNZ ASMPOP
|
|||
|
INC BYTE PTR [BPFLG]
|
|||
|
JMP INCSI2
|
|||
|
GETREG10:
|
|||
|
CMP AL,14 ; SI REGISTER?
|
|||
|
JNZ GETREG11
|
|||
|
CMP WORD PTR [DIFLG],0
|
|||
|
JNZ ASMPOP
|
|||
|
INC BYTE PTR [SIFLG]
|
|||
|
JMP INCSI2
|
|||
|
GETREG11:
|
|||
|
CMP AL,15 ; DI REGISTER?
|
|||
|
JNZ ASMPOP ; *** error
|
|||
|
CMP WORD PTR [DIFLG],0
|
|||
|
JNZ ASMPOP
|
|||
|
INC BYTE PTR [DIFLG]
|
|||
|
JMP INCSI2
|
|||
|
|
|||
|
GETREG12: ; BETTER BE A NUMBER!
|
|||
|
MOV BP,WORD PTR [ASMADD+2]
|
|||
|
CMP BYTE PTR [MEMFLG],0
|
|||
|
JZ GTRG121
|
|||
|
GTRG119:MOV CX,4
|
|||
|
GTRG120:CALL GETHX
|
|||
|
JMP SHORT GTRG122
|
|||
|
GTRG121:MOV CX,2
|
|||
|
CMP BYTE PTR [AWORD],1
|
|||
|
JZ GTRG120
|
|||
|
CMP BYTE PTR [AWORD],CL
|
|||
|
JZ GTRG119
|
|||
|
CALL GET_ADDRESS
|
|||
|
GTRG122:JC ASMPOP
|
|||
|
MOV [HINUM],AX
|
|||
|
CMP BYTE PTR [NEGFLG],0
|
|||
|
JZ GETREG13
|
|||
|
NEG DX
|
|||
|
GETREG13:
|
|||
|
ADD WORD PTR [LOWNUM],DX
|
|||
|
INC BYTE PTR [NUMFLG]
|
|||
|
GETLOOPV:
|
|||
|
JMP GETLOOP
|
|||
|
|
|||
|
CHKREG: PUSH CX
|
|||
|
INC CX
|
|||
|
REPNZ SCASW
|
|||
|
POP AX
|
|||
|
SUB AX,CX
|
|||
|
OR CX,CX
|
|||
|
RET
|
|||
|
|
|||
|
STUFF_BYTES:
|
|||
|
PUSH SI
|
|||
|
LES DI,DWORD PTR ASMADD
|
|||
|
MOV SI,OFFSET DG:ASSEM_CNT
|
|||
|
XOR AX,AX
|
|||
|
LODSB
|
|||
|
MOV CX,AX
|
|||
|
JCXZ STUFFRET
|
|||
|
REP MOVSB
|
|||
|
MOV WORD PTR [ASMADD],DI
|
|||
|
STUFFRET:
|
|||
|
POP SI
|
|||
|
RET
|
|||
|
|
|||
|
SETSIZ:
|
|||
|
MOV DL,1
|
|||
|
TEST AL,11000B ; 16 BIT OR SEGMENT REGISTER?
|
|||
|
JZ SETSIZ1
|
|||
|
INC DL
|
|||
|
SETSIZ1:
|
|||
|
CMP BYTE PTR [AWORD],0
|
|||
|
JZ SETSIZ2
|
|||
|
CMP BYTE PTR [AWORD],DL
|
|||
|
JZ SETSIZ2
|
|||
|
SETERR: POP DX
|
|||
|
JMP ASMPOP
|
|||
|
SETSIZ2:MOV BYTE PTR [AWORD],DL
|
|||
|
RET
|
|||
|
;
|
|||
|
; DETERMINE IF NUMBER IN AX:DX IS 8 BITS, 16 BITS, OR 32 BITS
|
|||
|
;
|
|||
|
CHKSIZ: MOV CL,4
|
|||
|
CMP AX,BP
|
|||
|
JNZ RETCHK
|
|||
|
CHKSIZ1:MOV CL,2
|
|||
|
MOV AX,DX
|
|||
|
CBW
|
|||
|
CMP AX,DX
|
|||
|
JNZ RETCHK
|
|||
|
DEC CL
|
|||
|
RETCHK: RET
|
|||
|
;
|
|||
|
; get first character after first space
|
|||
|
;
|
|||
|
SCANS: CMP BYTE PTR [SI],13
|
|||
|
JZ RETCHK
|
|||
|
CMP BYTE PTR [SI],"["
|
|||
|
JZ RETCHK
|
|||
|
LODSB
|
|||
|
CMP AL," "
|
|||
|
JZ SCANBV
|
|||
|
CMP AL,9
|
|||
|
JNZ SCANS
|
|||
|
SCANBV: JMP SCANB
|
|||
|
;
|
|||
|
; Set up for 8087 op-codes
|
|||
|
;
|
|||
|
SETMID:
|
|||
|
MOV BYTE PTR [ASSEM1],0D8H
|
|||
|
MOV AH,AL
|
|||
|
AND AL,111B ; SET MIDDLE BITS OF SECOND BYTE
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
SHL AL,1
|
|||
|
MOV [MIDFLD],AL
|
|||
|
MOV AL,AH ; SET LOWER BITS OF FIRST BYTE
|
|||
|
SHR AL,1
|
|||
|
SHR AL,1
|
|||
|
SHR AL,1
|
|||
|
OR [ASSEM1],AL
|
|||
|
MOV BYTE PTR [F8087],1 ; INDICATE 8087 OPERAND
|
|||
|
MOV BYTE PTR [DIRFLG],100B
|
|||
|
RET
|
|||
|
;
|
|||
|
; Set MF bits for 8087 op-codes
|
|||
|
;
|
|||
|
SETMF: MOV AL,[AWORD]
|
|||
|
TEST BYTE PTR [DI+1],10B
|
|||
|
JNZ SETMFI
|
|||
|
AND BYTE PTR [DI+1],11111001B ; CLEAR MF BITS
|
|||
|
CMP AL,3 ; DWORD?
|
|||
|
JZ SETMFRET
|
|||
|
CMP AL,4 ; QWORD?
|
|||
|
JZ SETMFRET2
|
|||
|
TEST BYTE PTR [DI+1],1
|
|||
|
JZ SETMFERR
|
|||
|
CMP AL,5 ; TBYTE?
|
|||
|
JZ SETMFRET3
|
|||
|
JMP SHORT SETMFERR
|
|||
|
|
|||
|
SETMFI: CMP AL,3 ; DWORD?
|
|||
|
JZ SETMFRET
|
|||
|
CMP AL,2 ; WORD?
|
|||
|
JZ SETMFRET2
|
|||
|
TEST BYTE PTR [DI+1],1
|
|||
|
JZ SETMFERR
|
|||
|
CMP AL,4 ; QWORD?
|
|||
|
JNZ SETMFERR
|
|||
|
OR BYTE PTR [DI+1],111B
|
|||
|
SETMFRET3:
|
|||
|
OR BYTE PTR [DI+1],011B
|
|||
|
OR BYTE PTR [DI+2],101000B
|
|||
|
JMP SHORT SETMFRET
|
|||
|
SETMFRET2:
|
|||
|
OR BYTE PTR [DI+1],100B
|
|||
|
SETMFRET:
|
|||
|
RET
|
|||
|
|
|||
|
SETMFERR:
|
|||
|
JMP ASMPOP
|
|||
|
|
|||
|
|
|||
|
DW_OPER:
|
|||
|
MOV BP,1
|
|||
|
JMP SHORT DBEN
|
|||
|
|
|||
|
DB_OPER:
|
|||
|
XOR BP,BP
|
|||
|
DBEN: MOV DI,OFFSET DG:ASSEM_CNT
|
|||
|
DEC BYTE PTR [DI]
|
|||
|
INC DI
|
|||
|
DB0: XOR BL,BL
|
|||
|
CALL SCANP
|
|||
|
JNZ DB1
|
|||
|
DBEX: JMP ASSEM_EXIT
|
|||
|
DB1: OR BL,BL
|
|||
|
JNZ DB3
|
|||
|
MOV BH,BYTE PTR [SI]
|
|||
|
CMP BH,"'"
|
|||
|
JZ DB2
|
|||
|
CMP BH,'"'
|
|||
|
JNZ DB4
|
|||
|
DB2: INC SI
|
|||
|
INC BL
|
|||
|
DB3: LODSB
|
|||
|
CMP AL,13
|
|||
|
JZ DBEX
|
|||
|
CMP AL,BH
|
|||
|
JZ DB0
|
|||
|
STOSB
|
|||
|
INC BYTE PTR [ASSEM_CNT]
|
|||
|
JMP DB3
|
|||
|
DB4: MOV CX,2
|
|||
|
CMP BP,0
|
|||
|
JZ DB41
|
|||
|
MOV CL,4
|
|||
|
DB41: PUSH BX
|
|||
|
CALL GETHX
|
|||
|
POP BX
|
|||
|
JNC DB5
|
|||
|
JMP ASMERR
|
|||
|
DB5: MOV AX,DX
|
|||
|
CMP BP,0
|
|||
|
JZ DB6
|
|||
|
STOSW
|
|||
|
INC BYTE PTR [ASSEM_CNT]
|
|||
|
JMP SHORT DB7
|
|||
|
DB6: STOSB
|
|||
|
DB7: INC BYTE PTR [ASSEM_CNT]
|
|||
|
JMP DB0
|
|||
|
|
|||
|
CODE ENDS
|
|||
|
END ASSEM
|
|||
|
|