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

📄 asmgen.cpp

📁 C-MINUS编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			t = p->child[0];
			x86GenExp(t);

            emitCode("\tsub\tax, 0\n");
			emitComment("if: jump to [else] if condition not true\n");

			sprintf(msg_temp, "\tje\tiLe%d\n", curL1);
			emitCode(msg_temp);
			///..... stmt_exp_list of if
			t = p->child[1];
			while (t) {
				x86GenSE(t);
				t = t->sibling;
			}

			sprintf(msg_temp, "\tjmp\tiL%d\n", curL);
			emitCode(msg_temp);

			emitComment("if: jump here if condition is not true\n");

			sprintf(msg_temp, "iLe%d:\n",curL1);
			emitCode(msg_temp);
			/// .... else part of if ... else ...
            t=p->child[2];
			if (t) {
				emitComment("== else statement of if ... else \n");				
				// ...
				//t = t->child[0];
				while (t) {
					x86GenSE(t);
					t = t->sibling;
				}
			}
			
			sprintf(msg_temp, "iL%d:\n", curL);
            emitCode(msg_temp);
            
			emitComment("<<<== if statement\n");
			break;
		case whileK:
			cL+=2;
			emitComment(">>>== while statement\n");			
			emitComment("while: jump after body comes back here\n");

			sprintf(msg_temp, "wL%d:\n", curL);
			emitCode(msg_temp);
			// ....
			x86GenExp(p->child[0]);

            emitCode("\tsub\tax, 0\n");
			sprintf(msg_temp, "\tje\twLe%d\n", curL1);
			emitCode(msg_temp);
			// ...
			t = p->child[1];
			while (t) {
				x86GenSE(t);
				t = t->sibling;
			}

			sprintf(msg_temp, "\tjmp\twL%d", curL);
			emitCode(msg_temp);

			emitComment("\n");

			sprintf(msg_temp, "wLe%d:\n", curL1);
			emitCode(msg_temp);

			emitComment("<<<== while statement\n");
			break;
		case returnK:
			emitComment("return statement!\n");
			if (p->child[0]){
				x86GenSE(p->child[0]);
				emitCode("\tmov\tre_val, ax\n");
			}
            emitCode("\tret\n");
			break;
		case callK:
			sprintf(msg_temp,"_%s_%s__",
				p->name.c_str(),
				((p->type == k_INT) ? "int" : "void"));
			funname = msg_temp;
			
			sprintf(msg_temp, "call %s(...) [%s] here\n",
				p->name.c_str(), funname.c_str());
			emitComment(msg_temp);
			
			t = p->child[0];
			while (t) {		//process argument
				x86GenExp(t);
				emitCode("\tpush\tax\n");
				t = t->sibling;
			}
			//.....
			sprintf(msg_temp, "\tcall\t%s\n\tmov\tax, re_val\n", funname.c_str());
			emitCode(msg_temp);
			break;
		default:        //bug!
			break;
		}       // end of switch
		
	}
	else
	{
		outputMsg(-1, "Warning: expection happened in function "
                "\"void asmGen::x86GenStmt(TreeNode *tree)\""
			    " parament tree get a NULL!!!");
		warn++;
		is_good_ = false;
	}
}

/**:	Fun: asmGen::x86GenExp(TreeNode *tree)
&
*	generate expression_list code in functions
*
*	author:	lonelyforest
*	data:	2006.5.10
*/
//-----------------------------------------------------------------------------
void asmGen::x86GenExp(TreeNode *tree)
{
	if (tree){
		TreeNode *p = tree;
		TreeNode *t = NULL;
		//string funname = "_??????_????__";
		
		string op_name = p->name;
		switch (p->kind.exp){
		case OpK:
			if (op_name == "=") {
				emitComment("==> assign statement\n");
				x86GenSE(p->child[1]);

				t = p->child[0];
				if (t->bArr) {
                    if (isLeft(t)) {
                        sprintf(msg_temp, "\tmov\tbx, %s_%s_\n",
                            t->scope.c_str(), t->name.c_str());
                        emitCode(msg_temp);
                    }
                    else {
                        sprintf(msg_temp, "\tlea\tbx, %s_%s_\n",
                            t->scope.c_str(), t->name.c_str());
                        emitCode(msg_temp);
                    }
                    emitCode("\tpush\tax\n");
					x86GenSE(t->child[0]);
					emitCode("\tmov\tsi, ax\n\tadd\tsi, si\n\tpop\tax\n"
					        "\tmov\t[bx + si], ax\n");
				}
				else
				{
					sprintf(msg_temp, "\tmov\t%s_%s_, ax\n", t->scope.c_str(), t->name.c_str());
					emitCode(msg_temp);
				}
				emitComment("<== assign statement\n");
				break;
			}
			
			emitComment("==> OP\t");
			emitCode(op_name.c_str());
			emitCode("\n");

			x86GenSE(p->child[0]);
			emitCode("\tmov\tbx, ax\n\tpush\tbx\n");
			// ...
			x86GenSE(p->child[1]);
			// ...
			emitCode("\tpop\tbx\n\txchg\tax, bx\n");
			// switch (p->type) { fuck! why is alaways zore????
			if (op_name == "+") {
				emitCode("\tadd\tax, bx\n");
			}else if (op_name == "-") {
				emitCode("\tsub\tax, bx\n");
			}else if (op_name == "*") {
				emitCode("\timul\tbx\n");
			}else if (op_name == "/") {
                emitCode("\tpush\tdx\n\tsub\tdx, dx\n");
				emitCode("\tidiv\tbx\n");
				emitCode("\tpop\tdx\n");
			}else if (op_name == "%") {
                emitCode("\tpush\tdx\n\tsub\tdx, dx\n");
				emitCode("\tdiv\tbx\n");
				emitCode("\tmov\tax, dx\n\tpop\tdx\n");
			}else if (op_name == "<" ) {
                cL++;
                emitCode("\tcmp\tax, bx\n");
                sprintf(msg_temp,
                        "\tjl\tLog%d__\n\tmov\tax, 0\n"
                            "\tjmp\tLoge%d__\nLog%d__:\n"
                            "\tmov\tax, 1\nLoge%d__:\n",
                        cL, cL, cL, cL);
                emitCode(msg_temp);
                //...
            }else if( op_name == ">" ) {
                cL++;
                emitCode("\tcmp\tax, bx\n");
                sprintf(msg_temp,
                        "\tjg\tLog%d__\n\tmov\tax, 0\n"
                            "\tjmp\tLoge%d__\nLog%d__:\n"
                            "\tmov\tax, 1\nLoge%d__:\n",
                        cL, cL, cL, cL);
                emitCode(msg_temp);
            }else if ( op_name == "==") {
                cL++;
                emitCode("\t\tcmp\tax, bx\n\tje");
                sprintf(msg_temp,
                        "\tLoge%d__\n\tmov\tax, 0\n"
                            "\tjmp\tLog%d__\nLoge%d__:\n"
                            "\tmov\tax, 1\nLog%d__:\n" ,
                        cL, cL, cL, cL);
                emitCode(msg_temp);
            } else if (op_name == "!=" ) {
                cL++;
                emitCode("\tcmp\tax, bx\n\tje");
                sprintf(msg_temp,
                        "\tLoge%d__\n\tmov\tax, 1\nLoge%d__:\n",
                        cL, cL);
                emitCode(msg_temp);
            } else if ( op_name == "<=") {
                cL++;
                emitCode("\tcmp\tax, bx\n");
                sprintf(msg_temp,
                        "\tjle\tLog%d__\n\tmov\tax, 0\n"
                            "\tjmp\tLoge%d__\nLog%d__:\n"
                            "\tmov\tax, 1\nLoge%d__:\n",
                        cL, cL, cL, cL);
                emitCode(msg_temp);
            } else if ( op_name == ">=") {
				cL++;
                emitCode("\tcmp\tax, bx\n");
                sprintf(msg_temp,
                        "\tjge\tLog%d__\n\tmov\tax, 0\n"
                            "\tjmp\tLoge%d__\nLog%d__:\n"
                            "\tmov\tax, 1\nLoge%d__:\n",
                        cL, cL, cL, cL);
                emitCode(msg_temp);
			}else {
				sprintf(msg_temp,
					"Warning: BUG!  unknown operator! %s = %d\n",
					op_name.c_str(), p->type);
				emitComment(msg_temp);
			}
			
			emitComment("<== OP\t");
			emitCode(op_name.c_str());
			emitCode("\n");
			break;
		case ConstK:
			sprintf(msg_temp, "\tmov\tax, %s\n", op_name.c_str());
			emitCode(msg_temp);
			break;
		case IDK:
			if (p->bArr){ // a[.]
                if ( isLeft(p) ) {
                    sprintf(msg_temp, "\tmov\tbx, %s_%s_\n", p->scope.c_str(), p->name.c_str());
                    emitCode(msg_temp);
                }
                else {
                    sprintf(msg_temp, "\tlea\tbx, %s_%s_\n", p->scope.c_str(), p->name.c_str());
                    emitCode(msg_temp);
                }

                if (p->father && p->father->nodekind == stmtK && p->father->kind.stmt == callK)
                {
                    emitCode("\tmov\tax, bx\n");
                }
                else
                {
                    emitCode("\tpush\tbx\n");
                    x86GenExp(p->child[0]);
                    emitCode("\tmov\tsi, ax\n\tadd\tsi, si\n"
                             "\tpop\tbx\n\tmov\tax, [bx + si]\n");
                }

			}
			else
			{
				sprintf(msg_temp, "\tmov\tax, %s_%s_\n", p->scope.c_str(), p->name.c_str());
				emitCode(msg_temp);
			}

			break;
		default:        //bug;
			break;
		}
		
	}
	else {  // bug!
		outputMsg(-1, "Warning: expection happened in function "
                "\"void asmGen::x86GenExp(TreeNode *tree)\""
			    " parament tree get a NULL!!!");
		warn++;
		is_good_ = false;
	}
}

bool    asmGen::isLeft(TreeNode *node)
{
     if (node && node->nodekind !=  expK &&    node->nodekind != varK )
     {
        TreeNode *t = node->father;
        while (t && t->nodekind != funK ) t = t->father;
        t = t->child[0];
        while (t)
        {
            if (t->bArr && t->name == node->name)  return true;
            t = t->sibling;
        }
		
		return false;
     }
     else      return false;
}


/**:	Fun: asmGen::read_int()
&
*	read(int) completed by ASM, also it's have bug
*       can not input negative numbers!!
*
*	author:	lonelyforest
*	data:	2006.4.26
*/
//-----------------------------------------------------------------------------
void asmGen::read_int()
{
	string  codeStr =
		";\n"
		";-----------------------------------------------------------------------------\n"
		";			__read_int_\n"
		";		==========================\n"
		";\n"
		";Proc For Read a int decimal, result in BX\n"
		";-----------------------------------------------------------------------------\n"
        "__read_int_	proc    near\n"
        "       local   minus:byte, count:byte\n"
        ";minus is falg to input number\n"
        ";initial\n"
        "       push	ax\n"
        "       push	cx\n"
		"       push	dx\n"
        "       mov	minus, '+'			;flag, +\n"
        "       mov 	bx, 0\n"
        "       mov	count, 5d			;number of digits\n"
        ";\n"
        "_new_char_:\n"
        "       mov	ah, 1				;input from keyboard\n"
        "       int	21h				;call DOS\n"
        ";\n"
        "       cmp	al, '+'\n"
        "       je	_new_char_			;maybe have bug!\n"
		"       cmp	al, '-'\n"
		"       jne	_continue_read_\n"
		"       mov	minus, '-'\n"
		"       jmp	_new_char_\n"
		";\n"
		"_continue_read_:\n"
		"       sub	al, 30h				;ASCII to Binary\n"
        "       jl	_exit_read_			;jump exit if < 0\n"
        "       cmp	al, 9d				;is it > 9d ?\n"
        "       jg	_exit_read_			;yes\n"
        "       cbw					;byte in al to word in ax\n"
        ";digit now in (ax)\n"
        "       xchg	ax,bx				;trade digit & number\n"
        "       mov	cx, 10d\n"
        "       mul	cx\n"
        "       xchg	ax,bx				;trade number & digit\n"
        ";Add digit in AX to number in BX\n"
        "       add	bx, ax				;add digit to number\n"
        "       dec	count\n"
        "       jnz	_new_char_			;get next digit if < 5\n"
        "_exit_read_:					;should process minus!!!\n"
        "       cmp     minus, '-'\n"
        "       jne     not_negative_r\n"
        "       neg     bx                              ;negetive\n"
        "not_negative_r:\n"
        "       mov	ah, 2h\n"
        "       mov	dl, 0ah				;linefeed\n"
        "       int	21h\n"
        "       mov	dl, 0dh				;carriage return after read\n"
        "       int	21h\n"
        ";\n"
        "       pop	dx				;recover registers\n"
        "       pop	cx\n"
        "       pop	ax\n"
        ";result number in bx\n"
        "       ret\n"
        "__read_int_    endp				;end of proc __read_int_\n";
	
	emitCode(codeStr.c_str());
}

/**:	Fun: asmGen::write_int()
&
*	write(int) completed by ASM, also it's have bug
*       can not output negative numbers!!
*
*	author:	lonelyforest
*	data:	2006.4.26
*/
//-----------------------------------------------------------------------------
void asmGen::write_int()
{
	string codeStr =
		";\n"
		";-----------------------------------------------------------------------------\n"
		";			__write_int_\n"
		";		==========================\n"
		";\n"
		";Proc For write a int decimal to screen, int data in BX\n"
		";-----------------------------------------------------------------------------\n"
		"__write_int_   proc    near\n"
		"       push	cx\n"
		"       push	ax\n"
		";process if negtive\n"
		"       mov     ax, bx\n"
		"       not	ax\n"
		"       test    ah, 10000000B\n"
		"       jne     not_negative_w			;not negative\n"
		"       mov     dl, '-'\n"
		"       mov     ah, 02h\n"
		"       int     21h\n"
		"       neg     bx\n"
		"not_negative_w:\n"
		"       mov	cx, 10000d			;divide by 10000\n"
		"       mov	ax, bx				;data in bx, mov to ax\n"
		"       call	__dec_div_\n"
		"       mov	cx, 1000d\n"
		"       mov	ax, bx\n"
		"       call	__dec_div_\n"
		"       mov	cx, 100d\n"
		"       mov	ax, bx\n"
		"       call	__dec_div_\n"
		"       mov	cx, 10d\n"
		"       mov	ax, bx\n"
		"       call	__dec_div_\n"
		"       mov	cx, 1d\n"
		"       mov	ax, bx\n"
		"       call	__dec_div_\n"
		";linefeed and carriage after out put a data\n"
		"       mov	ah, 2h\n"
        "       mov	dl, 0ah				;linefeed\n"
        "       int	21h\n"
        "       mov	dl, 0dh				;carriage return after read\n"
        "       int	21h\n"
		";\n"
		"       pop	ax\n"
		"       pop	cx\n"
		"       ret					;return form _write_int_\n";
	
	emitCode(codeStr.c_str());
	
	codeStr =
		";-----------------------------------------------------------------------------\n"
		";			__dec_div_\n"
		";		==========================\n"
		";\n"
		";Subroutine to divide number in BX by number in CX\n"
		";print quotient on screen, (numberator in DX+AX, denom in CX)\n"
		";-----------------------------------------------------------------------------\n"
		"__dec_div_     proc    near\n"
		";\n"
		"       mov	ax, bx                          ;number low half\n"
		"       mov	dx, 0                           ;zero out high half\n"
		"       div	cx                              ;divide by CX\n"
		"       mov	bx, dx                          ;remainder into BX\n"
		"       mov	dl, al				;quotient into DL\n"
		";print the contents of DL on screen\n"
		"       add	dl, 30h                         ;convert to ASCII\n"
		"       mov	ah, 2h\n"
		"       int	21h\n"
		"       ret\n"
		"__dec_div_     endp                            ;end of proc __dec_div_\n"
		";-----------------------------------------------------------------------------\n"
		"__write_int_   endp                            ;end of proc __write_int_\n";
	
	emitCode(codeStr.c_str());
}

/**:	Fun: asmGen::emitComment(const char *)
&
*	This program to write to 80x86 asm file comment
*
*	author:	lonelyforest
*	data:	2006.4.24
*/
//-----------------------------------------------------------------------------
void asmGen::emitComment(const char *eCmt)
{
	if (code_)	code_ <<  ";" << eCmt;
	else{
        is_good_ = false;
		err++;
		sprintf(msg_temp, "failed write to ASM file \"%s\" the code: \"%s\"...",
			codefile.c_str(), eCmt);
		outputMsg(-1, msg_temp);
	}
}

/**:	Fun: asmGen::emitCode(const char *)
&
*	This program to write into 80x86 asm file code
*
*	author:	lonelyforest
*	data:	2006.4.24
*/
//-----------------------------------------------------------------------------
void asmGen::emitCode(const char *eCde)
{
	if (code_)    code_ << eCde;
	else {
        is_good_ = false;
		err++;
		sprintf(msg_temp, "failed write to ASM file \"%s\" the code: \"%s\"...",
			codefile.c_str(), eCde);
		outputMsg(-1, msg_temp);
	}
}
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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