⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 operands.asm

📁 比dos下的debug更好的debug程序源码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;
; GRDP
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; Operands.asm
;
; Function: Handle 386 operands as dictated by the opcode table
;   Handle formatting output
;
; Sorry, I didn't have time to document this one yet
;
; years later:
;
; sorry, I STILL didn't have time to document this one yet :)
;
	;MASM MODE
	.MODEL SMALL
	.386

include	edispatc.inc 
include	iopcodes.inc
include	ioperand.inc
include	eoptions.inc
include	eopcom.inc

	PUBLIC TabTo, ReadOverrides, DispatchOperands
	PUBLIC	FormatDisassembly, FormatValue, Code_Address
	PUBLIC	PutDword, PutWord,PutByte
	PUBLIC	put2,put3,put4, strlen

	extrn x86pfx : byte
SZ_QWORD	=	2
SZ_TBYTE	=	4

	.DATA
code_address	dw	0		;disassembly address within segment
dest2		dw	0		;temps to aid decoding
source2		dw	0
segs		dw	0		
extraoperand	OPERAND <>		;third operand
source		OPERAND	<>		;second operand
dest		OPERAND	<>		;first operand
nmmnemonic 	db	10 DUP (?)	;mnemonic (may be modified here)
reqsPtrSizeOvride	db	0	;flag set if xxx ptr required

	.CODE

;Find the length of a string in a buffer pointed to by SI, and return that
;length in AX.  This is a strange way to do this. I think I'll change it
;just a little.
;  If SI comes in pointing to a 0, we return a string length of 0

strlen	PROC	
	push	di
	push	si
	push	cx
	mov	di,si
	mov	cx,-1
	sub	al,al
	repnz	scasb
	mov	ax,cx
	not	ax
	dec	ax
	pop	cx
	pop	si
	pop	di
	ret
strlen	ENDP	




strcpy	PROC	
strcpylp:
	lodsb
	stosb
	or	al,al
	jnz	strcpylp
	ret
strcpy	ENDP	


strcat	PROC	
	mov	al,[di]
	inc	di
	or	al,al
	jnz	strcat
	dec	di
	jmp	strcpy
strcat	ENDP	


CopyExtra	PROC	
	push	si
	push	di
	mov	si,offset extraoperand
	xchg	si,di
	mov	cx,OPERANDSIZE
	rep	movsb
	pop	di
	pop	si
	ret
CopyExtra	ENDP	



put2	PROC	
	mov	[si],ah
	inc	si
	mov	[si],al
	inc	si
	mov	BYTE PTR [si],0
	ret
put2	ENDP	


put3	PROC	
	push	eax
	shr	eax,8
	mov	[si],ah
	inc	si
	pop	eax
	call	put2
	ret
put3	ENDP	


put4	PROC	
	push	eax
	shr	eax,16
	call	put2
	pop	eax
	call	put2
	ret
put4	ENDP	


SetSeg	PROC	
	mov	[reqsPtrSizeOvride],FALSE
	mov	[di+OPERAND.code],OM_SEGMENT
	mov	[di+OPERAND.THEREG],al
	ret
SetSeg	ENDP	


SetReg	PROC	
	mov	[reqsPtrSizeOvride],FALSE
	mov	[di+OPERAND.code],OM_REG
	mov	[di+OPERAND.THEREG],al
	ret
SetReg	ENDP	


ReadRM	PROC	
	push	cx
	sub	cx,cx
	mov	cl,2
	RM	si
	mov	[di+OPERAND.THEREG],al
	MODX	si
	mov	ch,al
	cmp	ch,MOD_REG
	jnz	short notregreg
	mov	[di+OPERAND.CODE],OM_REG
	mov	[reqsPtrSizeOvride],FALSE
	sub	ax,ax
	pop	cx
	ret
notregreg:
	bt	[di+OPERAND.OEFLAGS],OMF_ADR32
	jnc	adr16
	cmp	[di+OPERAND.THEREG],RM_32_SCALED
	jnz	notscaled
	inc	cl
	RM	si+1
	mov	[di+OPERAND.THEREG],al
	REG	si+1
	mov	[di+OPERAND.SCALEREG],al
	MODX	si+1
	mov	[di+OPERAND.SCALE],al
	cmp	[di+OPERAND.SCALEREG],RM_32_STACKINDEX
	jz	hassp
	bts	[di+OPERAND.OEFLAGS],OMF_SCALED
hassp:
	cmp	[di+OPERAND.THEREG],RM_32_ABSOLUTE
	jnz	basedAndScaled
	cmp	ch,MOD_NOOFS
	jnz	short basedAndScaled
	mov	[di+OPERAND.CODE],OM_ABSOLUTE
	LONG	si+3
	mov	[di+OPERAND.ADDRESS],eax
	sub	ax,ax
	mov	al,5
	pop	cx
	ret
notscaled:
	
	cmp	ch,MOD_NOOFS
	jnz	basedAndScaled
	cmp	[di+OPERAND.THEREG], RM_32_ABSOLUTE
	jnz	basedAndScaled
	mov	[di+OPERAND.CODE], OM_ABSOLUTE
	LONG	si+2
	mov	[di+OPERAND.ADDRESS],eax
	sub	ax,ax
	sub	ax,ax
	mov	al,4
	pop	cx
	ret
adr16:
	movzx	esi,si
	cmp	ch,MOD_NOOFS
	jnz	basedAndScaled
	cmp	[di+OPERAND.THEREG], RM_16_ABSOLUTE
	jnz	basedAndScaled
	mov	[di+OPERAND.CODE], OM_ABSOLUTE
	UINT	si+2
	mov	[di+OPERAND.ADDRESS],eax
	sub	ax,ax
	mov	al,2
	pop	cx
	ret
basedAndScaled:
	mov	[di+OPERAND.CODE], OM_BASED
	cmp	ch,MOD_ADDR
	jnz	short checksigned
	bts	[di+OPERAND.OEFLAGS], OMF_WORD_OFFSET
	push	cx
	sub	ch,ch
	movzx	ecx,cl
	mov	eax,fs:[esi+ecx]
	pop	cx
	bt	[di+OPERAND.OEFLAGS], OMF_ADR32
	jc	dwordx
	and	eax,0ffffh
	sub	cl,2
dwordx:
	mov	[di+OPERAND.ADDRESS],eax
	add	cl,4
	jmp	short readrmdone
checksigned:
	cmp	ch, MOD_SIGNED
	jnz	short readrmdone
	bts	[di+OPERAND.OEFLAGS],OMF_SIGNED_OFFSET
	movzx	ecx,cl
	movzx	eax,byte ptr fs:[esi+ecx]
	mov	[di+OPERAND.ADDRESS],eax
	inc	cl
readrmdone:
	movzx	ax,cl
	sub	al,2
	pop	cx
	ret
ReadRM	ENDP	


RegRM	PROC	
	mov	di,[dest2]
	REG	si
	call	SetReg
	mov	di,[source2]
	call	ReadRM
	ret
RegRM	ENDP	


Immediate	PROC	
	push	cx
	sub	cx,cx
	mov	[di+OPERAND.CODE],OM_IMMEDIATE
	bt	[di+OPERAND.OEFLAGS],OMF_BYTE
	jnc	short inotbyte
	inc	cl
	sub	ax,ax
	mov	al,fs:[si]
	jmp	short i_ret
inotbyte:
	bt	[di+OPERAND.OEFLAGS], OMF_OP32
	jnc	iword
	add	cl,4
	LONG	si
	jmp	short i_ret
iword:
	add	cl,2
	UINT	si
i_ret:
	mov	[di+OPERAND.ADDRESS],eax
	mov	ax,cx
	pop	cx
	ret
Immediate	ENDP	

;Find a binary 0, stick whatever is in AL there, and put a 0 after that.

MnemonicChar	PROC	
	push	di
	mov	di,offset nmmnemonic
mc2:
	inc	di
	cmp	BYTE PTR [di-1],0
	jnz	mc2
	mov	[di-1],al
	mov	BYTE PTR [di],0
	pop	di
	ret
MnemonicChar	ENDP	



;/* op 1- word reg from bits 0 - 2 of opcode */

op1	PROC	
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	mov	al,fs:[si]
	B02
	call	SetReg
	sub	ax,ax
	ret
op1	ENDP	


;/* Op2 acc, reg bits 0-2 of opcode */
op2	PROC	
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	btr	[bx+OPERAND.OEFLAGS],OMF_BYTE
	mov	al,REG_EAX
	call	SetReg
	mov	di,bx
	mov	al,fs:[si]
	and	al,7
	call	SetReg
	sub	ax,ax
	ret
op2	ENDP	


;/* op3 - seg from b3-5 of opcode */
Op3	PROC	
	mov	al,fs:[si]
	B35
	call	SetSeg
	sub	ax,ax
	ret
op3	ENDP	


;/* op4 - REGRM with b1 of opcode set reg is dest else source */
op4	PROC	
	bt	DWORD PTR fs:[si],1
	jc	short op4nox
	xchg	bx,di
op4nox:
	mov	[dest2],di
	mov	[source2],bx
	call	RegRM
	ret
op4	ENDP	


;/* op5 - use RM only */
op5	PROC	
	call	ReadRM
	ret
op5	ENDP	


;/* op6 READRM for shift */
op6	PROC	
	call	ReadRM
	sub	cx,cx
	mov	cl,al
	mov	di,bx
	mov	[di+OPERAND.CODE],OM_SHIFT
	bt	DWORD PTR fs:[si],4
	jnc	short op6cnt
	bt	DWORD PTR fs:[si],1
	jnc	op61
	bts	[di+OPERAND.OEFLAGS],OMF_CL
	jmp	short op6done
op61:
	mov	[di+OPERAND.ADDRESS],1
	jmp	short op6done
op6cnt:
	movzx	ecx,cx
	movzx	esi,si
	movzx	eax,BYTE PTR fs:[esi+ecx+2]
	inc	cl
	mov	[di+OPERAND.ADDRESS],eax
op6done:
	mov	ax,cx
	ret
op6	ENDP	


;/* op 7 regrm with reg dest */
op7	PROC	
	mov	[dest2],di
	mov	[source2],bx
	call	RegRM
	ret
op7	ENDP	


;/* OP8 - word regrm with reg dest */
op8	PROC	
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	btr	[bx+OPERAND.OEFLAGS],OMF_BYTE
	jmp	op7
op8	ENDP	


;/* op 9 - interrupts */
op9	PROC	
	mov	[reqsPtrSizeOvride],FALSE
	sub	eax,eax
	mov	al,3
	bt	DWORD PTR fs:[si],0
	jnc	short op9int3
	mov	al,fs:[si+1]
op9int3:
	mov	[di+OPERAND.ADDRESS],eax
	mov	BYTE PTR [di+OPERAND.CODE],OM_INT
	sub	al,al
	ret
op9	ENDP	


;/* op 10, short relative branch */
op10	PROC	
	mov	[reqsPtrSizeOvride],FALSE
	mov	[di+OPERAND.CODE],OM_SHORTBRANCH
	movsx	eax,BYTE PTR fs:[si+1]
	inc	ax
	inc	ax
	add	ax,[code_address]
	mov	[di+OPERAND.ADDRESS],eax
	bt	[di+OPERAND.OEFLAGS],OMF_OP32
	jc	short op10notword
	and	[di+OPERAND.ADDRESS],0ffffh
op10notword:
	sub	ax,ax
	ret
op10	ENDP	


;/* op 11 RM, immediate */
op11	PROC	
	call	ReadRM
	movzx	cx,al
	mov	di,bx
	push	si
	add	si,cx
	add	si,2
	call	Immediate
	add	cl,al
	pop	si
	mov	ax,cx
	ret
op11	ENDP	


;/* op 12 - acc, immediate */
op12	PROC	
	mov	al,REG_EAX
	call	SetReg
	mov	di,bx
	inc	si
	call	Immediate
	dec	si
	ret
op12	ENDP	


;/* op 13 absolute, acc*/
op13	PROC	
	sub	cx,cx
	mov	[di+OPERAND.CODE],OM_ABSOLUTE
	bt	[di+OPERAND.OEFLAGS],OMF_ADR32
	jnc	short op13word
	LONG	si+1
	inc	cl
	inc	cl
	jmp	short op13fin
op13word:
	UINT	si+1
op13fin:
	mov	[di+OPERAND.ADDRESS],eax
	mov	di,bx
	mov	al,REG_EAX
	call	SetReg
	mov	ax,cx
	ret
op13	ENDP	


;/* op 14 - RM, immediate, b01 of opcode != 1 for byte */
op14	PROC	
	call	ReadRM
	movzx	cx,al
	mov	al,fs:[si]
	B01
	jnz	short op14checkbyte
	bts	[bx+OPERAND.OEFLAGS],OMF_BYTE
	bts	[di+OPERAND.OEFLAGS],OMF_BYTE
	jmp	short op14source
op14checkbyte:
	btr	[bx+OPERAND.OEFLAGS],OMF_BYTE
	cmp	al,1
	jz	short op14check2
	bts	[bx+OPERAND.OEFLAGS],OMF_BYTE
op14check2:
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
op14source:
	mov	di,bx
	push	si
	add	si,cx
	add	si,2
	call	Immediate
	pop	si
	add	cl,al
	mov	al,fs:[si]
	B01
	cmp	al,3
	jnz	op14done
	bt	[di+OPERAND.OEFLAGS],OMF_BYTE
	jnc	op14done
	bts	[di+OPERAND.OEFLAGS],OMF_SIGNED
	movzx	eax,byte ptr [di+OPERAND.ADDRESS]
	mov	[di+OPERAND.ADDRESS],eax
op14done:
	mov	ax,cx
	ret
op14	ENDP	


;/* op 15 - acc, immediate, B3 of opcode clear for byte */
op15	PROC	
	mov	al,fs:[si]
	B02
	call	SetReg
	bt	DWORD PTR fs:[si],3
	jnc	op15byte
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	btr	[bx+OPERAND.OEFLAGS],OMF_BYTE
	jmp	short op15source
op15byte:
	bts	[di+OPERAND.OEFLAGS],OMF_BYTE
	bts	[bx+OPERAND.OEFLAGS],OMF_BYTE
op15source:
	mov	di,bx
	inc	si
	call	Immediate
	dec	si
	ret
op15	ENDP	


;/* op 16 - seg,readrm, if B1 of opcode seg is dest else source */
op16	PROC	
	bt	DWORD PTR fs:[si],1
	jc	noswap
	xchg	bx,di
noswap:
	REG	si
	call	SetSeg
	mov	di,bx
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	call	ReadRM
	ret
op16	ENDP	


;/* op 17, far return */
op17	PROC	
	mov	[reqsPtrSizeOvride],false
	mov	[di+OPERAND.CODE],OM_RETURN
	btr	[di+OPERAND.OEFLAGS],OMF_ADR32
	btr	[di+OPERAND.OEFLAGS],OMF_OP32
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	UINT	si+1
	mov	[di+OPERAND.ADDRESS],eax
	sub	ax,ax
	ret
op17	ENDP	


;/* op 18, far branch/call */
op18	PROC	
	sub	cx,cx
	mov	[reqsPtrSizeOvride],FALSE
	mov	[di+OPERAND.CODE],OM_FARBRANCH
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	bt	[di+OPERAND.OEFLAGS],OMF_OP32
	jnc	short op18word
	inc	cl
	inc	cl
	LONG	si+1
	jmp	short	op18fin
op18word:
	UINT	si+1
op18fin:
	mov	[di+OPERAND.ADDRESS],eax
	movzx	ecx,cx
	movzx	esi,si
	UINT	esi+ecx+3
	mov	[di+OPERAND.OESEG],ax
	mov	ax,cx
	ret
op18	ENDP	


;/* op 19 - ESC, mnem of bits 0-2 of opcode, imm,readrm */
op19	PROC	
	mov	[di+OPERAND.CODE],OM_IMMEDIATE
	bts	[di+OPERAND.OEFLAGS],OMF_BYTE
	mov	al,fs:[si]
	and	al,7
	shl	al,3
	mov	ah,fs:[si+1]
	shr	ah,3
	and	ah,7
	or	al,ah
	sub	ah,ah
	cwde
	mov	[di+ OPERAND.ADDRESS],eax
	mov	di,bx
	call	ReadRM
	ret
op19	ENDP	


;/* op 20 - long branch */
op20	PROC	
	sub	eax,eax
	mov	[reqsPtrSizeOvride],FALSE
	sub	cx,cx
	mov	[di+OPERAND.CODE],OM_LONGBRANCH
	bt	[di+OPERAND.OEFLAGS],OMF_OP32
	jnc	short op20word
	LONG	si+1
	inc	cl
	inc	cl
	jmp	short op20fin
op20word:
	UINT	si+1
op20fin:
	add	ax,[code_address]
	test	[segs],SG_TWOBYTEOP
	jz	op20xx
	inc	ax
op20xx:
	add	ax,cx
	add	ax,3
	bt	[di+OPERAND.OEFLAGS],OMF_OP32
	jc	op20done
	and	eax,0ffffh
op20done:
	mov	[di+OPERAND.ADDRESS],eax
	mov	ax,cx
	ret
op20	ENDP	


;/* op21 acc,dx */
op21	PROC	
	mov	al,REG_EAX
	call	SetReg
	mov	di,bx
	btr	[di+OPERAND.OEFLAGS],OMF_OP32
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	mov	al,REG_DX
	call	SetReg
	sub	ax,ax
	ret
op21	ENDP	


;/* op22 - dx,acc */
op22	PROC	
	btr	[di+OPERAND.OEFLAGS],OMF_OP32
	btr	[di+OPERAND.OEFLAGS],OMF_BYTE
	mov	al,REG_DX
	call	SetReg
	mov	di,bx
	mov	al,REG_EAX
	call	SetReg
	sub	ax,ax
	ret
op22	ENDP	


;/* op23 - port,acc where B1 of opcode set is port dest */
op23	PROC	
	bt	DWORD PTR fs:[si],1
	jc	short op20NoSwap
	xchg	bx,di
op20noswap:
	bts	[di+OPERAND.OEFLAGS],OMF_BYTE
	mov	[di+OPERAND.CODE],OM_PORT
	movzx	eax,BYTE PTR fs:[si+1]
	mov	[di+OPERAND.ADDRESS],eax
	mov	di,bx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -