编译原理项目——C++实现C语言编译器输出为8086级汇编(代码/报告材料)

本文主要是介绍编译原理项目——C++实现C语言编译器输出为8086级汇编(代码/报告材料),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

完整的材料 代码见文章末尾 以下为核心内容和部分结果

项目介绍

一个小型的c语言编译器,实现的功能如下:

  1. 可以定义多个变量,并且能初始化。
  2. 可以支持基本的加减乘除运算。
  3. 可以支持带括号的多个变量的四则混合运算。
  4. 可以支持单行注释和多行注释。
  5. 可以输出%d格式的整数。
  6. 可以定义int 类型。
  7. 可以输出字符串。
  8. 可以输出2位整数
  9. 可以支持简单的if{}else{}语句。(大于和小于比较条件)
  10. 以上支持的语法可以混合在同一个源程序中。
  11. 部分错误语法可以报错。

环境

  • 汇编器、MASM
  • 汇编语言:8086汇编
  • 源代码:C++,用VS2019

用masm打开生成的asm文件直接运行

设计流程

扫源代码 --> 词法分析 --> 语法分析 -->目标代码 --> 汇编代码

词法分析器的实现:使用正则表达式或有限状态机(Finite State Machine, FSM)来识别和生成词法单元。

语法分析器的实现:使用递归下降分析或者其他方法(如LR分析)构建语法分析器,生成抽象语法树。

语义分析:检查类型、作用域等语义信息,确保生成的代码符合语言规范。

中间代码生成:根据抽象语法树生成中间表示形式,如三地址码或四元式。

目标代码生成:将中间代码翻译为8086汇编代码,考虑寄存器分配、指令选择等。

汇编代码生成:将生成的汇编代码输出为文件,或直接进行后续的汇编和链接操作。

部分核心代码展示(asm文件)

#include"asm.h"
#include"define.h"
extern vector<Target>  target_code;
extern vector<Variable>   var_table;
extern char lab;
string  asmfile(string source)
{if (source.size() == 0){cout << "源文件名不能为空" << endl;exit(-1);}string temp = "";int i, j;j = source.size();for (i = j - 1; i >= 0; i--){//		if(source[i] == '\\' || source[i]== '/')//			break;if (source[i] == '.'){j = i;break;}}temp = source.substr(0, j) + ".asm";return temp;
}
void add_target_code(string dsf, string op, string dst, string dsc, string mark, string step)
{Target  tmp;tmp.dsf = dsf;tmp.op = op;tmp.dst = dst;tmp.dsc = dsc;tmp.mark = mark;tmp.step = step;target_code.push_back(tmp);
}
void addsub_asm(ofstream& out, string dsf, string op, string dst, string dsc)
{out << "    mov BL," << dst << endl;if (op == "+")out << "    add BL," << dsc << endl;elseout << "    sub BL," << dsc << endl;out << "    mov " << dsf << ",BL" << endl;
}
void mul_asm(ofstream& out, string dsf, string dst, string dsc)
{out << "    mov AL," << dst << endl;out << "    mov BH," << dsc << endl;out << "    mul BH" << endl;out << "    mov BL,1" << endl;out << "    div BL" << endl;out << "    mov " << dsf << ",AL" << endl;
}
void div_asm(ofstream& out, string dsf, string dst, string dsc)
{out << "    mov AL," << dst << endl;out << "    CBW" << endl;out << "    mov BL," << dsc << endl;out << "    div BL" << endl;out << "    mov " << dsf << ",AL" << endl;
}
void sign_asm(ofstream& out, string dsf, string dst)
{out << "    mov BL," << dst << endl;out << "    mov " << dsf << ",BL" << endl;
}
void print_asm(ofstream& out, string dsf, string mark)
{//以字符格式输出if (mark == "%c"){out << "    mov DL," << dsf << endl;out << "    mov AH,02H" << endl;out << "    int 21H" << endl;}//以整数格式输出else if (mark == "%d"){out << "    mov AL," << dsf << endl;out << "    CBW" << endl;out << "    mov BL,10" << endl;out << "    DIV BL" << endl;out << "    mov BH,AH" << endl;out << "    add BH,30H" << endl;out << "    add AL,30H" << endl;out << "    CMP AL,48" << endl;//确定十位是否是0lab = lab + 2;string step2 = "step" + char_to_str(lab);out << "    JE " << step2 << endl;string step1 = "step" + char_to_str(lab - 1);out << "  " << step1 << ":" << endl;out << "    mov DL,AL" << endl;out << "    mov AH,2" << endl;out << "    int 21H" << endl;//输出个位out << "  " << step2 << ":" << endl;out << "    mov DL,BH" << endl;out << "    mov AH,2" << endl;out << "    int 21H" << endl;}//字符串输出else{out << "    LEA DX," << mark << endl;out << "    mov AH,09" << endl;out << "    int 21H" << endl;}
}
void if_asm(ofstream& out, string dst, string dsc, string mark, string step)
{out << "    mov AL," << dst << endl;out << "    CMP AL," << dsc << endl;if (mark == ">")out << "    JG " << step << endl;else if (mark == "<")out << "    JL " << step << endl;else{cout << "暂不支持其他条件判断" << endl;exit(-1);}
}
void create_asm(string file)
{//变量声明ofstream   wfile(file.c_str());if (!wfile.is_open())cout << "无法创建汇编文件" << endl;vector<Variable>::iterator  it_var;wfile << "ASSUME CS:codesg,DS:datasg" << endl;//数据段wfile << "datasg segment" << endl;for (it_var = var_table.begin(); it_var != var_table.end(); it_var++){wfile << "    " << it_var->var << " DB ";if (it_var->value != "")wfile << it_var->value << endl;elsewfile << "\'?\'" << endl;}wfile << "datasg ends" << endl;//代码段wfile << "codesg segment" << endl;wfile << "  start:" << endl;wfile << "    mov AX,datasg" << endl;wfile << "    mov DS,AX" << endl;vector<Target>::iterator     it;Target        tmp;for (it = target_code.begin(); it != target_code.end(); it++){//加减法转化if (it->op == "+" || it->op == "-")addsub_asm(wfile, it->dsf, it->op, it->dst, it->dsc);//乘法转换else if (it->op == "*")mul_asm(wfile, it->dsf, it->dst, it->dsc);//除法转换else if (it->op == "/")div_asm(wfile, it->dsf, it->dst, it->dsc);//赋值运算else if (it->op == "=")sign_asm(wfile, it->dsf, it->dst);//输出操作else if (it->op == "p")print_asm(wfile, it->dsf, it->mark);//if语法分析else if (it->op == "if"){if_asm(wfile, it->dst, it->dsc, it->mark, it->step);}else if (it->op == "else"){cout << "else 没有找到匹配的 if" << endl;exit(-1);}//跳转语句else if (it->op == "jmp"){wfile << "    JMP " << it->step << endl;}//跳转语句段标识else if (it->op == "pstep"){wfile << "  " << it->step << ":" << endl;}//其他else{cout << "编译器暂不支持该语法操作" << endl;exit(-1);}}//代码段结束wfile << "    mov ax,4C00H" << endl;wfile << "    int 21H" << endl;wfile << "codesg ends" << endl;wfile << "  end start" << endl;wfile.close();
}

asmfile,生成汇编文件的名称。

执行逻辑:

  • 检查源文件名是否为空,如果为空则报错退出。
  • 从源文件名中去掉扩展名,并添加.asm作为新文件名的扩展名。
  • 返回生成的汇编文件名。

add_target_code,将目标代码添加到目标代码向量中。

执行逻辑:

  • 创建一个临时的Target结构体,赋值各个字段。
  • 将该结构体添加到目标代码向量中。

addsub_asm,生成加法和减法的汇编代码。

执行逻辑:

  • 将目的操作数加载到寄存器BL。
  • 根据操作符执行加法或减法运算。
  • 将结果存储到目标操作数中。

mul_asm,生成乘法的汇编代码。

执行逻辑:

  • 将目的操作数加载到寄存器AL。
  • 将源操作数加载到寄存器BH。
  • 执行乘法运算,并将结果存储在AL中。
  • 将结果存储到目标操作数中。

div_asm,生成除法的汇编代码。

执行逻辑:

  • 将目的操作数加载到寄存器AL。
  • 执行符号扩展(CBW)。
  • 将源操作数加载到寄存器BL。
  • 执行除法运算,并将结果存储在AL中。
  • 将结果存储到目标操作数中。

sign_asm,生成赋值运算的汇编代码。

执行逻辑:

  • 将源操作数加载到寄存器BL。
  • 将结果存储到目标操作数中。

print_asm,生成输出操作的汇编代码。

执行逻辑:

  • 根据标记符(%c或%d)判断输出格式。
  • 如果是字符输出,加载字符到寄存器DL并调用中断21H。
  • 如果是整数输出,执行整数的转换和输出。
  • 如果是字符串输出,加载字符串地址到寄存器DX并调用中断21H。

if_asm,生成if语句的汇编代码。

执行逻辑:

  • 将目的操作数加载到寄存器AL。
  • 比较目的操作数和源操作数。
  • 根据条件标记符(>或<)生成相应的条件跳转指令。

create_asm,生成汇编文件。

执行逻辑:

  • 打开汇编文件进行写操作。
  • 写入数据段和代码段的开始部分。
  • 遍历目标代码向量,生成相应的汇编代码(加法、减法、乘法、除法、赋值、输出、if语句、跳转等)。
  • 写入代码段的结束部分,并关闭文件。

结果展示

测试文件如下:

main()
{int a,b;a = 4;b = 2;if(a>b){a = a+1;}if(b<1){b = b-1;}else{b = b+1;}printf("a=%d b=%d",a,b);
}

8086汇编如下:

ASSUME CS:codesg,DS:datasg
datasg segmenta DB '?'b DB '?'tmpB DB '?'tmpC DB '?'tmpD DB '?'tmpE DB 'a=$'tmpF DB ' b=$'
datasg ends
codesg segmentstart:mov AX,datasgmov DS,AXmov BL,4mov a,BLmov BL,2mov b,BLmov AL,aCMP AL,bJG stepBJMP stepCstepB:mov BL,aadd BL,1mov tmpB,BLmov BL,tmpBmov a,BLJMP stepCstepC:mov AL,bCMP AL,1JL stepDmov BL,badd BL,1mov tmpC,BLmov BL,tmpCmov b,BLJMP stepEstepD:mov BL,bsub BL,1mov tmpD,BLmov BL,tmpDmov b,BLJMP stepEstepE:LEA DX,tmpEmov AH,09int 21Hmov AL,aCBWmov BL,10DIV BLmov BH,AHadd BH,30Hadd AL,30HCMP AL,48JE stepGstepF:mov DL,ALmov AH,2int 21HstepG:mov DL,BHmov AH,2int 21HLEA DX,tmpFmov AH,09int 21Hmov AL,bCBWmov BL,10DIV BLmov BH,AHadd BH,30Hadd AL,30HCMP AL,48JE stepIstepH:mov DL,ALmov AH,2int 21HstepI:mov DL,BHmov AH,2int 21Hmov ax,4C00Hint 21H
codesg endsend start

获取方式

点这里 只需要一点点辛苦费,不需要你写材料 报告。

在这里插入图片描述

这篇关于编译原理项目——C++实现C语言编译器输出为8086级汇编(代码/报告材料)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1136937

相关文章

linux批量替换文件内容的实现方式

《linux批量替换文件内容的实现方式》本文总结了Linux中批量替换文件内容的几种方法,包括使用sed替换文件夹内所有文件、单个文件内容及逐行字符串,强调使用反引号和绝对路径,并分享个人经验供参考... 目录一、linux批量替换文件内容 二、替换文件内所有匹配的字符串 三、替换每一行中全部str1为st

SpringBoot集成MyBatis实现SQL拦截器的实战指南

《SpringBoot集成MyBatis实现SQL拦截器的实战指南》这篇文章主要为大家详细介绍了SpringBoot集成MyBatis实现SQL拦截器的相关知识,文中的示例代码讲解详细,有需要的小伙伴... 目录一、为什么需要SQL拦截器?二、MyBATis拦截器基础2.1 核心接口:Interceptor

SpringBoot集成EasyPoi实现Excel模板导出成PDF文件

《SpringBoot集成EasyPoi实现Excel模板导出成PDF文件》在日常工作中,我们经常需要将数据导出成Excel表格或PDF文件,本文将介绍如何在SpringBoot项目中集成EasyPo... 目录前言摘要简介源代码解析应用场景案例优缺点分析类代码方法介绍测试用例小结前言在日常工作中,我们经

基于Python实现简易视频剪辑工具

《基于Python实现简易视频剪辑工具》这篇文章主要为大家详细介绍了如何用Python打造一个功能完备的简易视频剪辑工具,包括视频文件导入与格式转换,基础剪辑操作,音频处理等功能,感兴趣的小伙伴可以了... 目录一、技术选型与环境搭建二、核心功能模块实现1. 视频基础操作2. 音频处理3. 特效与转场三、高

Python实现中文文本处理与分析程序的示例详解

《Python实现中文文本处理与分析程序的示例详解》在当今信息爆炸的时代,文本数据的处理与分析成为了数据科学领域的重要课题,本文将使用Python开发一款基于Python的中文文本处理与分析程序,希望... 目录一、程序概述二、主要功能解析2.1 文件操作2.2 基础分析2.3 高级分析2.4 可视化2.5

Java实现预览与打印功能详解

《Java实现预览与打印功能详解》在Java中,打印功能主要依赖java.awt.print包,该包提供了与打印相关的一些关键类,比如PrinterJob和PageFormat,它们构成... 目录Java 打印系统概述打印预览与设置使用 PageFormat 和 PrinterJob 类设置页面格式与纸张

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho