📄 basm.asm
字号:
include basm.inc
extrn GetAsmSymbol:far
extrn GetAsmLabel:far
extrn EmitByte:far
extrn EmitFixup:far
extrn EmitJump:far
extrn EmitFloat:far
.code Basm_Text
Argm Text,dword,1
Argm Len,word,1
Argm Options,word,1
Loc Dummy,word,1
Loc SaveSI,word,1
Loc SaveDI,word,1
Loc StackLimit,word,1
Loc Prefixes,byte,6
Loc TextPtr,dword,1
Loc SaveTextPtr,word,1
Loc Oper1TextPtr,word,1
Loc Oper2TextPtr,word,1
Loc Mode,byte,1
Loc DataLength,byte,1
Loc InOpcode,byte,1
Loc OperCount,byte,1
Loc OpcodePtr,word,1
Loc RegNum,word,1
Loc Oper2Size,word,1
Loc HashValue,byte,1
Loc Opcode,byte,1
Loc Pending,byte,1
Loc RMBits,byte,1
Loc FixupAddr,dword,1
Loc PureMemFlag,byte,1
Loc SizeBit,byte,1
Loc DirectionBit,byte,1
Loc DefPrefix,byte,1
Loc FixupOffs,word,1
Loc DwordFixup,byte,1
Loc Dummy2,byte,1
Loc Value,dword,1
Loc Symbol,byte,<size TSymbol>
Loc IdentBuf,byte,34
Loc UpCaseIdent,byte,34
Loc StringBuf,byte,128
Loc CodeCount,word,1
Loc CodeBuffer,byte,<11*size TCodeBuffer>
Loc TempAddr,dword,1
Loc Operand1,byte,<size TAsmSymbol>
Loc Operand2,byte,<size TAsmSymbol>
Loc Operand3,byte,<size TAsmSymbol>
Loc Limit,word,1
Entry Assemble
call Init
mov InOpcode,1
call GetToken
mov ax,TextPtr.offs
mov SaveTextPtr,ax
call ProcessLabel
call ProcessPrefix
dec InOpcode
call ProcessData
jz @@2
mov al,';'
call CheckToken
jz @@1
call PutPrefixes
jmp short @@2
@@1: mov al,tOPCODE
call NeedToken
call ProcessOperands
call ProcessCommand
@@2: call Flush
xor ax,ax
@Exit: mov cx,TextPtr.Offs
lds bx,Text
mov [bx],cx
mov si,SaveSI
mov di,SaveDI
Exit
Init proc near
mov SaveSI,si
mov SaveDI,di
lea ax,Limit[-1000]
mov StackLimit,ax
les bx,Text
les bx,es:[bx]
mov TextPtr.Offs,bx
mov TextPtr.Segm,es
xor ax,ax
mov SaveTextPtr,ax
mov Symbol.sParent.Offs,ax
mov Symbol.sParent.Segm,ax
mov word ptr Prefixes[0],ax
mov CodeCount,ax
mov Pending,al
ret
Init endp
Flush proc near
lea si,CodeBuffer
@@1: sub CodeCount,size TCodeBuffer
jc @@7
cld
push si
xor ax,ax
lodsb
mov bx,ax
lodsb
mov cx,ax
lodsw
xchg ax,dx
lodsw
xchg ax,dx
dec bx
js @@2
jz @@3
dec bx
jz @@4
push ax
mov ax,cx
and cl,0feh
push cx
and al,1
push ax
call EmitFloat
jmp short @@5
@@2: push ax
call EmitByte
jmp short @@5
@@3: push cx dword ptr [si] dx ax
call EmitFixup
jmp short @@5
@@4: push ax dword ptr [si]
call EmitJump
@@5: or ax,ax
jz @@6
jmp Error
@@6: pop si
add si,size TCodeBuffer
jmp @@1
@@7: mov CodeCount,0
ret
Flush endp
ProcessPrefix proc near
@@1: cmp dh,tOPCODE
jne @@3
mov bx,OpcodePtr
cmp byte ptr cs:[bx],80h+cPrefix
jne @@3
mov al,cs:[bx+2]
mov cx,5
lea bx,Prefixes[-1]
@@2: inc bx
cmp byte ptr [bx],0
loopne @@2
mov ah,0
mov [bx],ax
call GetToken
jmp @@1
@@3: ret
ProcessPrefix endp
ProcessData proc near
cmp dh,tOPCODE
jne @@3
mov bx,OpcodePtr
mov ax,cs:[bx]
cmp al,80h+cDB
jne @@3
mov DataLength,ah
cmp word ptr Prefixes[0],0
je @@1
jmp SyntaxErr
@@1: call GetToken
@@2: lea si,Operand1
call Expression
push dx
call ProcessDataElem
call Flush
pop dx
mov al,','
call CheckToken
jnz @@2
mov al,';'
call NeedToken
xor ax,ax
@@3: ret
ProcessData endp
ProcessDataElem proc near
mov di,si
mov ax,[si].aValue.W0
mov dx,[si].aValue.W2
mov cx,[si].aAddr.Offs
or cx,[si].aAddr.Segm
cmp DataLength,2
je @@5
ja @@7
or cx,cx
jz @@1
jmp InvOperErr2
@@1: lea si,StringBuf
cmp byte ptr [si],0
jne @@2
call ByteOperand
jnz @@13
jmp short @@11
@@2: xor ax,ax
cld
lodsb
xchg ax,cx
jcxz @@4
@@3: cld
lodsb
push si cx
call @@11
call Flush
pop cx si
loop @@3
@@4: ret
@@5: cmp StringBuf[0],2
ja @@14
call WordOperand
jcxz @@10
mov bx,fOffs*256+eFixup
cmp [si].aHalf,bh
jb @@6
mov bh,[si].aHalf
@@6: xchg ax,cx
mov ax,Operand1.aAddr.Offs
mov TempAddr.Offs,ax
mov ax,Operand1.aAddr.Segm
mov TempAddr.Segm,ax
jmp Put
@@7: cmp StringBuf[0],4
ja @@14
jcxz @@8
xchg ax,cx
mov bx,fPtr*256+eFixup
cmp [si].aHalf,0
je @@12
mov bh,[si].aHalf
mov ax,Operand1.aAddr.Offs
mov TempAddr.Offs,ax
mov ax,Operand1.aAddr.Segm
mov TempAddr.Segm,ax
call Put
jmp short @@9
@@8: call @@10
@@9: xchg ax,dx
@@10: call @@11
xchg al,ah
@@11: mov bl,eByte
mov cx,ax
@@12: call Put
ret
@@13: jmp OutOfRangeErr
@@14: jmp StringConstErr
ProcessDataElem endp
ProcessLabel proc near
call FilterChar
cmp al,':'
jne @@1
lea bx,IdentBuf
push ss bx
call GetAsmLabel
jnz Error
call GetToken
mov al,':'
call NeedToken
@@1: ret
ProcessLabel endp
ProcessOperands proc near
mov OperCount,0
mov ax,SaveTextPtr
mov Oper1TextPtr,ax
mov al,';'
call CheckToken
jnz @@3
lea si,Operand1
call Expression
inc OperCount
mov al,';'
call CheckToken
jnz @@3
mov al,','
call NeedToken
mov ax,SaveTextPtr
mov Oper2TextPtr,ax
lea si,Operand2
call Expression
inc OperCount
lea si,Operand1
lea di,Operand2
mov ax,[si].aSize
mov cx,[di].aSize
mov Oper2Size,cx
jcxz @@1
or ax,ax
jnz @@2
xchg cx,[si].aSize
jmp short @@2
@@1: xchg ax,[di].aSize
@@2: mov al,';'
call CheckToken
jnz @@3
mov al,','
call NeedToken
lea si,Operand3
call Expression
inc OperCount
mov al,';'
call NeedToken
@@3: ret
ProcessOperands endp
@Err: cbw
Error label near
push SaveTextPtr
pop TextPtr.offs
jmp @Exit
FieldErr label near
mov al,-15
jmp @Err
ZeroDivErr label near
mov al,-14
jmp @Err
Not286Err label near
mov al,-13
jmp @Err
InvOperErr label near
mov al,-12
jmp @Err
IntConstErr label near
mov al,-11
jmp @Err
StringConstErr label near
mov al,-10
jmp @Err
OutOfRangeErr label near
mov al,-9
jmp @Err
InvRegErr label near
mov al,-8
jmp @Err
RelSymErr label near
mov al,-7
jmp @Err
TypeErr label near
mov al,-6
jmp @Err
ConstErr label near
mov al,-5
jmp @Err
MemRefErr label near
mov al,-4
jmp @Err
InvOperErr2 label near
mov al,-3
jmp @Err
OutOfMemErr label near
mov al,-2
jmp @Err
SyntaxErr label near
mov al,-1
jmp @Err
CheckStack proc near
cmp sp,StackLimit
jbe OutOfMemErr
ret
CheckStack endp
include asmexpr.inc
include asmlex.inc
include asminstr.inc
extrn OpcodeTable:near
extrn ResWordTable:near
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -