📄 asmgen.cpp
字号:
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 + -