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

📄 assembl.cpp

📁 实现了屏幕截取
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Free Disassembler and Assembler -- Assembler
//
// Copyright (C) 2001 Oleh Yuschuk
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// 16.01.2002 - corrected error in processing of immediate constants.


#define STRICT

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include <dir.h>
#include <math.h>
#include <float.h>
#pragma hdrstop

#include "disasm.h"

#pragma   warning(disable:4996)//关闭旧函数声明警告
////////////////////////////////////////////////////////////////////////////////
///////////////////////////// ASSEMBLER FUNCTIONS //////////////////////////////

// Scanner modes.
#define SA_NAME        0x0001          // Don't try to decode labels
#define SA_IMPORT      0x0002          // Allow import pseudolabel

// Types of input tokens reported by scanner.
#define SCAN_EOL       0               // End of line
#define SCAN_REG8      1               // 8-bit register
#define SCAN_REG16     2               // 16-bit register
#define SCAN_REG32     3               // 32-bit register
#define SCAN_SEG       4               // Segment register
#define SCAN_FPU       5               // FPU register
#define SCAN_MMX       6               // MMX register
#define SCAN_CR        7               // Control register
#define SCAN_DR        8               // Debug register
#define SCAN_OPSIZE    9               // Operand size modifier
#define SCAN_JMPSIZE   10              // Jump size modifier
#define SCAN_LOCAL     11              // Address on stack in form LOCAL.decimal
#define SCAN_ARG       12              // Address on stack in form ARG.decimal
#define SCAN_PTR       20              // PTR in MASM addressing statements
#define SCAN_REP       21              // REP prefix
#define SCAN_REPE      22              // REPE prefix
#define SCAN_REPNE     23              // REPNE prefix
#define SCAN_LOCK      24              // LOCK prefix
#define SCAN_NAME      25              // Command or label
#define SCAN_ICONST    26              // Hexadecimal constant
#define SCAN_DCONST    27              // Decimal constant
#define SCAN_OFS       28              // Undefined constant
#define SCAN_FCONST    29              // Floating-point constant
#define SCAN_EIP       30              // Register EIP
#define SCAN_SIGNED    31              // Keyword "SIGNED" (in expressions)
#define SCAN_UNSIGNED  32              // Keyword "UNSIGNED" (in expressions)
#define SCAN_CHAR      33              // Keyword "CHAR" (in expressions)
#define SCAN_FLOAT     34              // Keyword "FLOAT" (in expressions)
#define SCAN_DOUBLE    35              // Keyword "DOUBLE" (in expressions)
#define SCAN_FLOAT10   36              // Keyword "FLOAT10" (in expressions)
#define SCAN_STRING    37              // Keyword "STRING" (in expressions)
#define SCAN_UNICODE   38              // Keyword "UNICODE" (in expressions)
#define SCAN_MSG       39              // Pseudovariable MSG (in expressions)

#define SCAN_SYMB      64              // Any other character
#define SCAN_IMPORT    65              // Import pseudolabel
#define SCAN_ERR       255             // Definitely bad item

// Definition used by Assembler to report command matching errors.
#define MA_JMP         0x0001          // Invalid jump size modifier
#define MA_NOP         0x0002          // Wrong number of operands
#define MA_TYP         0x0004          // Bad operand type
#define MA_NOS         0x0008          // Explicit operand size expected
#define MA_SIZ         0x0010          // Bad operand size
#define MA_DIF         0x0020          // Different operand sizes
#define MA_SEG         0x0040          // Invalid segment register
#define MA_RNG         0x0080          // Constant out of expected range

typedef struct t_asmoperand 
{
	int            type;                 // Operand type, see beginning of file
	int            size;                 // Operand size or 0 if yet unknown
	int            index;                // Index or other register
	int            scale;                // Scale
	int            base;                 // Base register if present
	long           offset;               // Immediate value or offset
	int            anyoffset;            // Offset is present but undefined
	int            segment;              // Segment in address if present
	int            jmpmode;              // Specified jump size
} t_asmoperand;

static char      *asmcmd;              // Pointer to 0-terminated source line
static int       scan;                 // Type of last scanned element
static int       prio;                 // Priority of operation (0: highest)
static char      sdata[TEXTLEN];       // Last scanned name (depends on type)
static long      idata;                // Last scanned value
static long      double fdata;         // Floating-point number
static char      *asmerror;            // Explanation of last error, or NULL

// Simple and slightly recursive scanner shared by Assemble(). The scanner is
// straightforward and ineffective, but high speed is not a must here. As
// input, it uses global pointer to source line asmcmd. On exit, it fills in
// global variables scan, prio, sdata, idata and/or fdata. If some error is
// detected, asmerror points to error message, otherwise asmerror remains
// unchanged.
static void Scanasm(int mode) 
{
	int i,j,base,maxdigit;
	long decimal,hex;
	long double floating,divisor;
	char s[TEXTLEN],*pcmd;
	sdata[0]='\0';
	idata=0;
	if (asmcmd==NULL) 
	{
		asmerror="NULL input line";
		scan=SCAN_ERR;
		return; 
	};
	while (*asmcmd==' ' || *asmcmd=='\t')
		asmcmd++;                          // Skip leading spaces
	if (*asmcmd=='\0' || *asmcmd==';') 
	{
		scan=SCAN_EOL; 
		return;
	};          // Empty line
	if (isalpha(*asmcmd) || *asmcmd=='_' || *asmcmd=='@')
	{
		sdata[0]=*asmcmd++; i=1;           // Some keyword or identifier
		while ((isalnum(*asmcmd) || *asmcmd=='_' || *asmcmd=='@') && i<sizeof(sdata))
			sdata[i++]=*asmcmd++;
		if (i>=sizeof(sdata)) 
		{
			asmerror="Too long identifier";
			scan=SCAN_ERR; 
			return;
		};
		sdata[i]='\0';
		while (*asmcmd==' ' || *asmcmd=='\t')
			asmcmd++;                        // Skip trailing spaces
		strcpy(s,sdata); _strupr_s(s);
		for (j=0; j<=8; j++)
		{             // j==8 means "any register"
			if (strcmp(s,regname[0][j])!=0) 
				continue;
			idata=j; 
			scan=SCAN_REG8;         // 8-bit register
			return; 
		};
		for (j=0; j<=8; j++)
		{
			if (strcmp(s,regname[1][j])!=0)
				continue;
			idata=j;
			scan=SCAN_REG16;        // 16-bit register
			return; 
		};
		for (j=0; j<=8; j++)
		{
			if (strcmp(s,regname[2][j])!=0)
				continue;
			idata=j; 
			scan=SCAN_REG32;        // 32-bit register
			return;
		};
		for (j=0; j<6; j++)
		{
			if (strcmp(s,segname[j])!=0)
				continue;
			idata=j; 
			scan=SCAN_SEG;          // Segment register
			while (*asmcmd==' ' || *asmcmd=='\t')
				asmcmd++;                      // Skip trailing spaces
			return;
		};
		if (strcmp(s,"ST")==0)
		{
			pcmd=asmcmd;
			Scanasm(SA_NAME);   // FPU register
			if (scan!=SCAN_SYMB || idata!='(')
			{
				asmcmd=pcmd;                   // Undo last scan
				idata=0; scan=SCAN_FPU; 
				return;
			};
			Scanasm(SA_NAME);
			j=idata;
			if ((scan!=SCAN_ICONST && scan!=SCAN_DCONST) || idata<0 || idata>7)
			{
				asmerror="FPU registers have indexes 0 to 7";
				scan=SCAN_ERR;
				return;
			};
			Scanasm(SA_NAME);
			if (scan!=SCAN_SYMB || idata!=')')
			{
				asmerror="Closing parenthesis expected";
				scan=SCAN_ERR;
				return;
			};
			idata=j; scan=SCAN_FPU;
			return; 
		};
		for (j=0; j<=8; j++)
		{

			if (strcmp(s,fpuname[j])!=0) 
				continue;
			idata=j; 
			scan=SCAN_FPU;          // FPU register (alternative coding)
			return; 
		};
		for (j=0; j<=8; j++)
		{
			if (strcmp(s,mmxname[j])!=0) 
				continue;
			idata=j; scan=SCAN_MMX;          // MMX register
			return;
		};
		for (j=0; j<=8; j++) 
		{
			if (strcmp(s,crname[j])!=0)
				continue;
			idata=j;
			scan=SCAN_CR;           // Control register
			return;
		};
		for (j=0; j<=8; j++) 
		{
			if (strcmp(s,drname[j])!=0) 
				continue;
			idata=j;
			scan=SCAN_DR;           // Debug register
			return;
		};
		for (j=0; j<sizeof(sizename)/sizeof(sizename[0]); j++) 
		{
			if (strcmp(s,sizename[j])!=0) 
				continue;
			pcmd=asmcmd; Scanasm(SA_NAME);
			if (scan!=SCAN_PTR)              // Fetch non-functional "PTR"
				asmcmd=pcmd;
			idata=j;
			scan=SCAN_OPSIZE;       // Operand (data) size in bytes
			return;
		};
		if (strcmp(s,"EIP")==0)
		{          // Register EIP
			scan=SCAN_EIP;
			idata=0; 
			return; 
		};
		if (strcmp(s,"SHORT")==0) 
		{        // Relative jump has 1-byte offset
			scan=SCAN_JMPSIZE; idata=1;
			return;
		};
		if (strcmp(s,"LONG")==0) 
		{         // Relative jump has 4-byte offset
			scan=SCAN_JMPSIZE; idata=2;
			return;
		};
		if (strcmp(s,"NEAR")==0) 
		{         // Jump within same code segment
			scan=SCAN_JMPSIZE; idata=4;
			return; 
		};
		if (strcmp(s,"FAR")==0) 
		{          // Jump to different code segment
			scan=SCAN_JMPSIZE; idata=8;
			return; 
		};
		if (strcmp(s,"LOCAL")==0 && *asmcmd=='.') {
			asmcmd++;
			while (*asmcmd==' ' || *asmcmd=='\t')
				asmcmd++;                      // Skip trailing spaces
			if (!isdigit(*asmcmd))
			{
				asmerror="Integer number expected";
				scan=SCAN_ERR;
				return; 
			};
			while (isdigit(*asmcmd))         // LOCAL index is decimal number!
				idata=idata*10+(*asmcmd++)-'0';
			scan=SCAN_LOCAL;
			return; 
		};
		if (strcmp(s,"ARG")==0 && *asmcmd=='.') 
		{
			asmcmd++;
			while (*asmcmd==' ' || *asmcmd=='\t')
				asmcmd++;                      // Skip trailing spaces
			if (!isdigit(*asmcmd)) 
			{
				asmerror="Integer number expected";
				scan=SCAN_ERR; return; 
			};
			while (isdigit(*asmcmd))         // ARG index is decimal number!
				idata=idata*10+(*asmcmd++)-'0';
			scan=SCAN_ARG; 
			return;
		};
		if (strcmp(s,"REP")==0) 
		{
			scan=SCAN_REP; 
			return; 
		};        // REP prefix
		if (strcmp(s,"REPE")==0 || strcmp(s,"REPZ")==0) 
		{
			scan=SCAN_REPE;
			return;
		};       // REPE prefix
		if (strcmp(s,"REPNE")==0 || strcmp(s,"REPNZ")==0) 
		{
			scan=SCAN_REPNE;
			return;
		};      // REPNE prefix
		if (strcmp(s,"LOCK")==0) 
		{
			scan=SCAN_LOCK; 
			return;
		};       // LOCK prefix
		if (strcmp(s,"PTR")==0)
		{
			scan=SCAN_PTR; 
			return;
		};        // PTR in MASM addressing statements
		if (strcmp(s,"CONST")==0 || strcmp(s,"OFFSET")==0)
		{
			scan=SCAN_OFS;
			return;
		};        // Present but undefined offset/constant
		if (strcmp(s,"SIGNED")==0) 
		{
			scan=SCAN_SIGNED;
			return; 
		};     // Keyword "SIGNED" (in expressions)
		if (strcmp(s,"UNSIGNED")==0) 
		{
			scan=SCAN_UNSIGNED; 
			return;
		};   // Keyword "UNSIGNED" (in expressions)
		if (strcmp(s,"CHAR")==0)
		{
			scan=SCAN_CHAR; return;
		};       // Keyword "CHAR" (in expressions)
		if (strcmp(s,"FLOAT")==0) 
		{
			scan=SCAN_FLOAT; 
			return;
		};      // Keyword "FLOAT" (in expressions)
		if (strcmp(s,"DOUBLE")==0) 
		{
			scan=SCAN_DOUBLE; 
			return; 
		};     // Keyword "DOUBLE" (in expressions)
		if (strcmp(s,"FLOAT10")==0) 
		{
			scan=SCAN_FLOAT10; 
			return;
		};    // Keyword "FLOAT10" (in expressions)
		if (strcmp(s,"STRING")==0) 
		{
			scan=SCAN_STRING; 
			return; 
		};     // Keyword "STRING" (in expressions)
		if (strcmp(s,"UNICODE")==0) 
		{
			scan=SCAN_UNICODE;
			return; 
		};    // Keyword "UNICODE" (in expressions)
		if (strcmp(s,"MSG")==0)
		{
			scan=SCAN_MSG;
			return;
		};        // Pseudovariable MSG (in expressions)
		if (mode & SA_NAME) 
		{
			idata=i;
			scan=SCAN_NAME;         // Don't try to decode symbolic label
			return; 
		}
		asmerror="Unknown identifier";
		scan=SCAN_ERR; 
		return; 
	}
	else if (isdigit(*asmcmd))
	{         // Constant
		base=0; maxdigit=0; decimal=hex=0L; floating=0.0;
		if (asmcmd[0]=='0' && toupper(asmcmd[1])=='X')
		{
			base=16; asmcmd+=2;
		};           // Force hexadecimal number
		while (1) 
		{
			if (isdigit(*asmcmd))
			{
				decimal=decimal*10+(*asmcmd)-'0';
				floating=floating*10.0+(*asmcmd)-'0';
				hex=hex*16+(*asmcmd)-'0';
				if (maxdigit==0)
					maxdigit=9;
				asmcmd++; 
			}
			else if (isxdigit(*asmcmd)) 
			{
				hex=hex*16+toupper(*asmcmd++)-'A'+10;
				maxdigit=15; 
			}
			else
				break; 
		};
		if (maxdigit==0) 
		{
			asmerror="Hexadecimal digits after 0x... expected";
			scan=SCAN_ERR; 
			return;
		};
		if (toupper(*asmcmd)=='H')
		{       // Force hexadecimal number
			if (base==16) 
			{
				asmerror="Please don't mix 0xXXXX and XXXXh forms";
				scan=SCAN_ERR;
				return;

⌨️ 快捷键说明

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