G中英文翻译软件件用不成

助记符翻译
程序地址分配
替换程序地址
数据地址替换
宏定义的展开
输入文件格式
纯文本文件,允许行首有多个空格或者制表符。同一行内,语句之间用一个或者多个空格或者制表符隔开。
不区分大小写。
注释以“”开始,占单独一行。处理的时候丢弃注释行。
以“”开始,以“”结束,占单独一行。主要用于表示跳转的目的地址。
立即数以“”开始,以进制表示。
立即程序地址和立即数据地址都以“”开始,以进制表示。
输出文件格式
16’h程序地址:
所有立即数据地址,每行一个。
助记符翻译
阴影文字不做翻译,直接输出。为的低位。
b1, `regs}
b1, `regs}
立即数据地址
立即数据地址
程序地址分配,Label程序地址替换
每一行有效语句分配一个位进制的程序地址。对于注释行不分配;对于行,其表示的是下一行有效语句的地址。
源程序内跳转指令中的跳转目标地址会使用表示,汇编器把替换为表示的实际地址的低位。把跳转指令之前的“”替换为表示的实际地址的高位。
数据地址替换
保留源程序中的数据地址到输出文件。同时将其输出到文件。
宏定义的展开
使用标记一段对程序的宏定义。在程序中通过引用,汇编器将这一段宏定义展开,展开时用添加到宏定义代码段中的立即地址之前。
&&&&&&mul&&&&&&&&r32_0&&&r32_1
ld&&&&&&&&r64_0&&&&alu_result
&&&&&&ld&&&&&&&&&&r3&&&&&&&&&&#my_label_page
&&&&&&st&&&&&&&&&r64_0&&&&&&data_save
ld&&&&&&&&&&r1&&&&&&&&&&#5a
输出文件1范例
h0000: begin instr = {`arth, `mul, `r32_0, `r32_1}&&&&&&&&&&&&&&&&&&&&&; end
h0001: begin instr = {`ldst, `ld_drt_addr, `r64_0, `alu_result }&&&&; end
h0002: begin instr = {`ldst, `ld_drt_data, `r3, 8’h00 }&&&&&&&&&&&&&&&&;end
h0003: begin instr = {`brch, `drt, `cnd_z, `jmp_next, 8’h01}&&&&&&&&&&&&; end
h0004: begin instr = {`ldst, `st_drt_addr, `r64_0, `data_save}&&&&&&&&&&&&&; end
h0005: begin instr = {`ldst, `ld_drt_data, `r2, 8’h5a}&&&&&&&&&&&&&&&&; end
输出文件2范例
用VS2013控制台实现
1、需要转换的文件格式如下:
macrostart
macro_def : test1 ( base_para )
st r64_0 & data_save
ld r1 # 5a
arth_mus r32_0
macro_def : test2 ( base_para )
arth_mus r32_0
% my_label
& alu_result
jnz & my_label
; an input file example
arth_mus r32_0
r64_0 & szy_data_save
ld r1 # 5a
arth_mus r32_0
ld r1 # 5a
arth_mus r32_0
arth_mus r32_0
r64_0 & szy_data_save
ld r1 # 5a
arth_mus r32_0
macro_gen : test2 ( lpf )
% my_label
& alu_result
ld r3 # my_label_page
jz & my_label
arth_mus r32_0
macro_gen : test1 ( cic )
% szy_my_label
& szy_alu_result
st r64_0 & data_save
ld r1 # 5a
由于需要区别宏和数据,我用了macrostart和datastart分开这两部分。
2、需要的参数如下:
(至少两个参数)程序 输入文件
如果多余两个参数,则对参数进行分类:一类是以&-&开头的,一类则是文件(输入文件和输出文件)
对于以&-&开头的,目前只识别 -d、-r、-md、-m
这四个参数分别表示处理完翻译之后会打印 最终数据、寄存器信息、宏展开后的数据、宏信息
最多有5个文件,若有5个文件,则分别表示 (若不足5个,那就只处理相应的前几个文件)
输入文件、最终数据文件、寄存器信息文件、宏展开后的数据文件、宏信息文件
//命令行参数处理
set&int&//带‘-’参数集合,存储的是到全局数组的偏移量
vector&string&//文件列表
for (int i = 1; i & i++)
string currpara(argv[i]);
if (currpara.empty())
if (currpara[0] == '-')//带‘-’参数
//判断能否识别这个参数
auto it = find(g_para, g_para + g_paran, currpara);
if (it == g_para + g_paran)//没有找到
cout && &\nerror: not indentifies the \&& && currpara && &\&.\n&;
cout && &----------------------------------\n&;
paraset.insert(it - g_para);
else filelist.push_back(currpara);//文件
if (filelist.empty())
cout && &\nerror: not find infile.\n&;
cout && &----------------------------------\n&;
else if (filelist.size() & 5)
cout && &\nerror: file num too more(greater than 5).\n&;
cout && &----------------------------------\n&;
默认第二个参数是输入的文件。
g_para和g_paran是两个全局变量:
//四个带-的参数: -d,-rd,-md,-m
g_paran = 4;
const string
g_para[g_paran] = { &-d&, &-r&, &-md&, &-m& };//依次会打印asmalgorithm中的私有成员
g_parai{ D = 0, R, MD, M };
3、读取需要转换的文件
//获取输入文件数据
//文件数据
if (!ReadFile(filelist[0], filedata, errmsg))//获取数据
cout && &\n& && errmsg && &\nexit!\n&;
cout && &----------------------------------\n&;
ReadFile实现为:
bool ReadFile(const string &file, string & filedata, std::string &errmsg)
filedata.clear();
errmsg.clear();
fin.open(file.c_str());
if (!fin.is_open())
errmsg = &not open file: \&& + file + &\&&;
ss && fin.rdbuf();
filedata = ss.str();
fin.close();
4、转换文件
//处理输入的文件数据
if (!myasm.Handle(filedata,errmsg))//处理数据
cout && &\n& && errmsg && &\nexit!\n&;
cout && &----------------------------------\n&;
定义了一个类AsmAlgorithm,用它的Handle成员来统一处理。
5、AsmAlgorithm类
AsmAlgorithm类如下:
class AsmAlgorithm
AsmAlgorithm();
~AsmAlgorithm();
public://行为
//核心算法处理
总处理函数
对于原始文件的一行,判断是哪种处理,并调用相应处理, 然后包裹格式来获取新行
bool Handle(const std::string &idata, std::string & errmsg);
//获取数据成员信息
const std::vector&std::string&& GetData();
const std::vector&std::string&& GetReg();
const std::vector&std::vector&std::string&&& GetMacroData();
const std::set&MacroInfo&& GetMacro();
//注释处理 无
//标签处理
static bool LabelHandle(const int cmdindex, const std::vector&std::string& &isource,
std::vector&std::string& &odst, std::string &errmsg);
//跳转处理
拿到输入的数据,按照某种格式输出
static bool JumpHandle(const int cmdindex, const std::vector&std::string& &isource,
std::vector&std::string& &odst, std::string &errmsg);
//操作处理
static bool OperatorHandle(const int cmdindex, const std::vector&std::string& &isource,
std::vector&std::string&&odst, std::string &errmsg);
//shell处理
static bool ShellHandle(const int cmdindex, const std::vector&std::string& &isource,
std::vector&std::string&&odst, std::string &errmsg);
//传送处理
static bool TransmitHandle(const int cmdindex, const std::vector&std::string& &isource,
std::vector&std::string&&odst, std::string &errmsg);
//////////////////////////////////////////////////////////////////////////
//辅助方法
//大写转小写
static std::string MyToLower(const std::string & str);
//包裹函数 把一个容器包装成一个字符串 对应于文件1中的字符串格式
static std::string Wrapper(const std::vector&std::string& isource);
//包裹文件2的字符串格式
static std::string Wrapper(const std::pair&std::string, int& & regitem);
//添加一个立即地址到寄存器列表中
static void AddRegAddr(const std::string &reg);
//拼接错误函数
static std::string SplitError(const std::string &cause, const std::string &line);
//获取宏域内的信息
static bool GetMacroInfo(const std::string &data, std::set&MacroInfo& &odata, std::string & errmsg);
//获取数据域内的信息
static bool GetDataAreaInfo(const std::string &idata, const std::set&MacroInfo& &vmi,
std::vector&std::vector&std::string&& &odata, std::string &errmsg);
std::vector&std::string &
m_//最终的数据信息,若有文件1,将会写入到文件1
std::vector&std::string &
m_//寄存器信息,若有文件2,将会写入到文件2
std::vector&std::vector&std::string&& m_//宏展开后的数据信息,若有文件3,将会写入到文件3
std::set&MacroInfo&
m_//宏信息,若有文件4,将会写入到文件4
其中MacroInfo这个宏定义成了:
struct MacroInfo
std:://这个宏的名字
std:://这个宏的参数
std::vector&std::vector&std::string&&//这个宏里面的命令列表
friend bool operator&(const MacroInfo &item1, const MacroInfo &item2)
return item1.name & item2.
6、一些全局变量以及宏等
//宏定义和展开的入口
#define MACRODEF &macro_def&
#define MACROGEN &macro_gen&
//当前行地址
static int g_currlineaddr = -1;//&=0xffffffff
//寄存器地址
static int g_regaddr = -1;//&=0xff
vector&pair&string, int&& g_//寄存器列表
//标签地址
static map&string, int& g_//&标签,地址&
//注释处理的助记符
static const string g_NC = &;&;//note cmd
//标签处理的助记符
static const string g_LS = &%&;//label start
static const string g_LE = &:&;//label end
//跳转处理的的助记符
static const int g_JCN = 6;//Jump cmd num
static const string g_JC[g_JCN] = { &jmp&, &jz&, &jnz&, &jc&, &jnc&, &jw& };//Jump cmd
g_JCI{ JMP = 0, JZ, JNZ, JC, JNC, JW };//Jump cmd index
static const int g_JFN = 2;//Jump
static const string g_JF[g_JFN] = { &&&, &@& };//Jump flag
g_JFI{ JAND = 0, JAT };//Jump cmd flag
//操作处理的的助记符
static const string g_OP = &arth_&;//operator prefix
static const string g_OC = &arth&;//operator cmd
//shell处理的助记符
static const int g_SCN = 5;//shell cmd num
static string
g_SC[g_SCN] = { &nop&, &shl&, &rttl&, &shr&, &rttr& };//shell cmd
g_SCI{ NOP = 0, SHL, RTTL, SHR, RTTR };//shell cmd index
static const int g_SFN = 3;//shell flag num
static string
g_SF[g_SFN] = { &0&, &1&, &s& };//shell flag
g_SFI{ SFI0 = 0, SFI1, SFIS };//shell flag index
//传送处理的助记符
static const int g_TCN = 2;//transmit cmd num
static string
g_TC[g_TCN] = { &ld&, &st& };//transmit cmd
g_TCI{ LD = 0, ST };//transmit cmd index
static const int g_TFN = 3;//transmit flag num
static string
g_TF[g_TFN] = { &#&, &&&, &@& };//transmit flag num
g_TFI{TWELL=0,TAND,TAT};//transmit flag index
7、AsmAlgorithm处理
Handle成员:
数据准备工作:
bool AsmAlgorithm::Handle(const string &idata,string & errmsg)
errmsg.clear();
//私有数据的初始化
m_macro.clear();
m_macrodata.clear();
m_data.clear();
m_reg.clear();
g_labeladdrmap.clear();//清空标签地址
g_reglist.clear();//清空寄存器地址信息
接着查找宏域和数据域
获取的文件数据
它有两部分,宏和数据(宏不是必须存在的(若存在,则必须在数据域前面),数据是必须存在的)
用macrostart开始的是宏,直到遇到datastart
用datastart开始的是数据,直到文件结束
宏的格式:文件数据中遇到这个宏名时会把里面的标签(格式为 % label :)
和 &地址(跳转中的&地址和传送中的地址)添加相应的label和地址的前缀(实参_)
macro_def : 宏名 ( 参数 )
文件数据中的数据格式
macro_def : test1 ( base_para )
r64_0 & data_save
//////////////////////////////////////////////////////////////////////////
//查找宏区域
auto macrostart = idata.find(MACROSTART);//查找macrostart
string tmpstr(idata.substr(0,macrostart));
int LF = tmpstr.rfind(&\n&);//从后往前找换行符,行首
if (LF + 1 != macrostart)//行首的下一个不是macrostart
errmsg = SplitError(&\&macrostart\& is not at top of line&,
idata.substr(LF+1, macrostart - LF) + MACROSTART + &...&);
//查找数据区域
auto datastart = idata.find(DATASTART);//查找datastart
tmpstr = idata.substr(0, datastart);
LF = tmpstr.rfind(&\n&);//从后往前找换行符,行首
if (LF + 1 != datastart)//行首的下一个不是datastart
errmsg = SplitError(&\&datastart\& is not at top of line&,
idata.substr(LF+1, datastart - LF) + DATASTART + &...&);
//判断宏域和数据域的位置关系
if (datastart == string::npos)//没有找到数据域开始的部分
errmsg = &not find data area from the infile.\n&;
if (macrostart != string::npos && macrostart & datastart)//宏域在数据域之后,错误
errmsg = &the macrostart is not at behand of datastart.\n&;
处理宏域并宏展开:
//////////////////////////////////////////////////////////////////////////
if (macrostart != string::npos)//有宏域
//处理宏域
if (!GetMacroInfo(idata.substr(macrostart, datastart - macrostart), m_macro, errmsg))
//宏展开和填写标签地址信息
if (!GetDataAreaInfo(idata.substr(datastart), m_macro, m_macrodata, errmsg))
处理完宏域之后,接着处理数据域(把它们放入一个vector的m_macrodata里面),处理数据域时,遇到宏定义需要宏展开(宏的信息在m_macro中),并且还需要填写标签地址信息(标签地址信息是一个全局变量g_labeladdrmap)。
数据处理:
//////////////////////////////////////////////////////////////////////////
//数据处理。。。
using fun_manager =
bool(*)(const int, const vector&string& &, vector&string& &, string &);//函数对象
vector&string&//命令列表,含所有命令
map&int, fun_manager,greater&int&&//函数对象的映射关系
cmdfunmap.insert({ cmdlist.end() - cmdlist.begin(), LabelHandle });
cmdlist.push_back(g_LS);//标签 0
cmdfunmap.insert({ cmdlist.end() - cmdlist.begin(), JumpHandle });
cmdlist.insert(cmdlist.end(), g_JC, g_JC + g_JCN);//跳转
cmdfunmap.insert({ cmdlist.end() - cmdlist.begin(), OperatorHandle });
cmdlist.insert(cmdlist.end(), g_OC);//操作
cmdfunmap.insert({ cmdlist.end() - cmdlist.begin(), ShellHandle });
cmdlist.insert(cmdlist.end(), g_SC, g_SC + g_SCN);//shell
cmdfunmap.insert({ cmdlist.end() - cmdlist.begin(), TransmitHandle });
cmdlist.insert(cmdlist.end(), g_TC, g_TC + g_TCN);//传送
for (vector&vector&string&&::size_type i = 0; i & m_macrodata.size(); i++)
{//执行原始文件的每一行
vector&string& oldformat = m_macrodata[i];//获取输入的数据格式
string cmd(MyToLower(oldformat[0]));//获取命令
auto cmdit = find(cmdlist.begin(), cmdlist.end(), cmd);//查找这个命令是否存在
if (cmdit == cmdlist.end())//没有找到
errmsg = SplitError(&command is not find&, Vector2String(oldformat));
const int cmdoffset = cmdit - cmdlist.begin();//cmd的偏移
const auto realit = find_if(cmdfunmap.cbegin(), cmdfunmap.cend(), //获取需要执行的cmd属于哪一类
[cmdoffset](const pair&int, fun_manager&&item){return cmdoffset &=item. });
vector&string&//输出的数据格式
//需要执行function的命令
if (!realit-&second(cmdoffset - realit-&first, oldformat, newformat, errmsg))
if (realit-&first == 0)//标签的处理,不用添加到输出容器中
string newline = Wrapper(newformat);//包裹起来
//追加到新容器中,之后会把这个容器的内容写到目标文件中
m_data.push_back(newline);
我把需要转换的命令分成了五类:标签(%开头的)、跳转(J开头的)、操作(add、sub、mul等)、shell(nop、shl、rttl等)、传送(ld,st),它们不区分大小写,我统一用MyToLower转换成小写了。
fun_manager在必要的时候分别指向这五类函数。
主要算法是遍历每一行,通过命令来判断这一行应该属于哪一类处理,然后调用相应的函数来处理这一行数据。
再介绍辅助函数
MyToLower:
string AsmAlgorithm::MyToLower(const string & str)
for (string::size_type i = 0; i & str.size();i++)
ret += tolower(str[i]);
string AsmAlgorithm::Wrapper(const vector&string& isource)
{//格式:16’h0000: begin instr = {`arth, `mul, `r32_0, `r32_1}; end
g_currlineaddr++;
if (g_currlineaddr & 0xffffffff)
g_currlineaddr = 0;
char sztmp[50] = { 0 };//前缀部分
MySprintf(sztmp, sizeof(sztmp), &16'h%04x : begin instr = &, (short)(g_currlineaddr));
string vsstr = &{& + Vector2String(isource, &,&) + &}&;//数据部分
sout && sztmp && setw(45) && left && vsstr && &;end&;
return sout.str();
std::string AsmAlgorithm::Wrapper(const std::pair&std::string, int& & regitem)
{//格式: `define alu_result 8’h00
char regstr[10] = { 0 };
MySprintf(regstr, sizeof(regstr), & 8'h%02x&, (char)(regitem.second));
sout && &`define & && setw(15) && left && regitem.first.c_str() &&
return sout.str();
SplitError:
string AsmAlgorithm::SplitError(const string &cause, const string &line)
char szerr[300] = { 0 };
MySprintf(szerr, sizeof(szerr), &error[%s]: \&%s\&\n&, cause.c_str(), line.c_str());
return string(szerr);
因为我的程序也会在gcc下编译,所以MySprintf是:
#if defined(_WIN32)|| defined(WIN32) || defined(_WIN64) || defined(WIN64) || defined(_WIN32_WINNT)
MySprintf sprintf_s//Win下
MySprintf snprintf//linux下
AddRegAddr:
void AsmAlgorithm::AddRegAddr(const std::string &reg)
g_regaddr++;
if (g_regaddr & 0xff)
g_regaddr = 0;
g_reglist.push_back(pair&string, int&(reg, g_regaddr));
处理宏域的GetMacroInfo:
bool AsmAlgorithm::GetMacroInfo(const string &data, set&MacroInfo& &odata, string &errmsg)
macro_def : test1 ( base_para )
r64_0 & data_save
stringstream sin(data);
getline(sin, line);//第一行的格式应该是 macrostart
vector&string& FML = String2Vector(line);//first macro list
if (FML.size() != 1 || FML[0] != MACROSTART)//不是“macrostart”格式
errmsg = SplitError(&format is not \&macrostart\&&, line);
//先获取所有数据到容器里面,
//空行舍弃、只含有空格的行也舍弃,以;开头的行(注释行)也舍弃
vector&vector&string&&
while (getline(sin, line))
if (line.empty())//空行
vector&string& s2v = String2Vector(line);
if (s2v.empty())//只含有空格的行
if (s2v[0] == g_NC)//注释行
linelist.push_back(s2v);
//对每一行,开始找macro_def
const int linesize = linelist.size();
int titleline = 0;
for (int i = 0; i & i++)
vector&string& itemlist = linelist[i];
if (itemlist.size() != 6
|| itemlist[0] != MACRODEF
|| itemlist[1] != &:&
|| itemlist[3] != &(&
|| itemlist[5] != &)&)//这个macro_def不符合格式,错误
errmsg = SplitError(&format is not \&macro_def : name ( base_para )\&&, Vector2String(linelist[i]));
//找到这个宏的题头了
info.name = itemlist[2];
info.parameter = itemlist[4];
titleline =//记录下题头行
//开始找这个宏包含的命令信息
//先找{符号
if (i == linesize)
errmsg = SplitError(&not find the \&{\& after the macrotitile&, Vector2String(linelist[titleline]));
itemlist = linelist[i];
if (!(itemlist.size() == 1 && itemlist[0] == &{&))//这行不是只含有{,则认为是错的
errmsg = SplitError(&the line is not \&{\& after macrotitle&, Vector2String(linelist[titleline]));
errmsg += &it is \&& + Vector2String(linelist[i]) + &\&\n&;
//开始找命令行信息了
bool bfindend =//用}来判断这个宏的结束
for (i++; i &i++)
itemlist = linelist[i];
if (itemlist.size() == 1 && itemlist[0] == &}&)//找到一个只含有}的行
bfindend =
info.cmdlist.push_back(itemlist);
if (!bfindend)//遍历完宏域,都没有找到},则认为是错的
errmsg = SplitError(&not find the \&}\& of the macro_def&, Vector2String(linelist[titleline]));
//判断以前是否有这个宏定义
auto it = find_if(odata.begin(), odata.end(),
[info](const MacroInfo &item){return info.name == item. });
if (it != odata.end())//这个宏定义已经存在了
errmsg = &the macro define of \&& + info.name + &\&have 2 times or more.\n&;
odata.insert(info);
获取数据域内的信息GetDataAreaInfo:
bool AsmAlgorithm::GetDataAreaInfo(const string &idata, const set&MacroInfo& &vmi,
vector&vector&string&& &odata,string &errmsg)
{//遇到宏定义需要展开,并填写标签地址
odata.clear();
errmsg.clear();
stringstream sin(idata);
getline(sin, line);//第一行的格式应该是 datastart
vector&string& FDL = String2Vector(line);//first data list
if (FDL.size() != 1 || FDL[0] != DATASTART)//不是“datastart”格式
errmsg = SplitError(&format is not \&datastart\&&, line);
while (getline(sin, line))
if (line.empty())//空行
vector&string& linelist = String2Vector(line);//拆分当前行
if (linelist.empty())//只有空格的行
if (linelist[0] == g_NC)//注释行舍弃
string firstitem = MyToLower(linelist[0]);
const auto findpos = firstitem.find(g_OP);//查找operator处理
if (findpos == 0)//找到 arth_
linelist.insert(linelist.begin(), g_OC);
linelist[1] = firstitem.substr(g_OP.size());
const string cmd(linelist[0]);//获取命令
//只有宏展开入口macro_gen
if (cmd == MACROGEN)//宏展开
if (linelist.size() != 6
|| linelist[0] != MACROGEN
|| linelist[1] != &:&
|| linelist[3] != &(&
|| linelist[5] != &)&)//这个macro_gen不符合格式
errmsg = SplitError(&format is not \&macro_gen : name ( para )\&&, line);
//将这一行替换为宏定义
//查找这个宏
auto macroit = find_if(vmi.begin(), vmi.end(),
[linelist](const MacroInfo &item){return linelist[2] == item. });
if (macroit == vmi.end())//没有找到这个宏定义
errmsg = &not find macro define of the \&& + linelist[2] + &\&.\n&;
for (vector&vector&string&&::size_type i = 0; i & macroit-&cmdlist.size(); i++)
{//把标签和&的都添加前缀
vector&string& itemlist = macroit-&cmdlist[i];//获取一个命令行的容器
const string mcmd(MyToLower(itemlist[0]));//获取命令
string firstitem = MyToLower(itemlist[0]);
const auto findpos = firstitem.find(g_OP);//查找operator处理
if (findpos == 0)//找到 arth_
itemlist.insert(itemlist.begin(), g_OC);
itemlist[1] = firstitem.substr(g_OP.size());
auto jumpit = find_if(g_JC, g_JC + g_JCN,
[mcmd](const string & item){return item == });
auto tramsit = find_if(g_TC, g_TC + g_TCN,
[mcmd](const string & item){return item == });
if (jumpit != g_JC + g_JCN)//跳转处理
if (itemlist.size() == 3 && itemlist[1] == g_JF[g_JFI::JAND])//是jxx & xxx
itemlist[2] = linelist[4] + &_& + itemlist[2];
odata.push_back(itemlist);
else if (tramsit != g_TC + g_TCN)//传送处理
if (itemlist.size() == 4 && itemlist[2] == g_TF[g_TFI::TAND])//是 ld/st xxx & xxx
itemlist[3] = linelist[4] + &_& + itemlist[3];
odata.push_back(itemlist);
else if (mcmd==g_LS)//标签
if (itemlist.size() == 3 && itemlist[2] == g_LE)//完全匹配标签
itemlist[1] = linelist[4] + &_& + itemlist[1];
odata.push_back(itemlist);
//写到标签地址中
g_labeladdrmap[itemlist[1]] = odata.size() - g_labeladdrmap.size() - 1;
errmsg = SplitError(&format is not \&% label :\& from macro \&& + macroit-&name + &\&&,
Vector2String(itemlist));
else//宏中的其他命令
odata.push_back(itemlist);
else//除了宏之外的行信息
if (cmd == g_LS)//标签行
if (linelist.size() == 3 && linelist[2] == g_LE)//完全匹配标签
odata.push_back(linelist);
//写到标签地址中
g_labeladdrmap[linelist[1]] = odata.size() - g_labeladdrmap.size() - 1;
errmsg = SplitError(&format is not \&% label :\&&, line);
else//其他的行
odata.push_back(linelist);
最后介绍五类转换函数:
标签的LabelHandle:
bool AsmAlgorithm::LabelHandle(const int cmdindex, const vector&string& &isource,
vector&string& &odst, string &errmsg)
{//格式 % label : //为了和另外几个xxxHandle函数统一,也用了输出容器,其实不需要输出容器
odst.clear();
errmsg.clear();
if (isource.size() != 3 || isource[2] != g_LE)
errmsg = AsmAlgorithm::SplitError(&format is not \&% label :\&&, Vector2String(isource));
//添加到地址 其实在宏展开的时候就已经写好了
g_labeladdrmap[isource[1]] = g_currlineaddr + 1;
这里为了和另外几个转换函数风格一致,我用了isource容器,但用不上,需要注意这个isource不能添加到输出容器中。
跳转的JumpHandle:
bool AsmAlgorithm::JumpHandle(const int cmdindex, const vector&string& &isource,
vector&string& &odst, string &errmsg)
{//格式 jxx &/@ label/r1r0
Jmp & my_label {`brch, `drt, `cnd_non, `jmp_next, 8’hxx}
Jz & my_label
{`brch, `drt, `cnd_z, `jmp_next, 8’hxx}
Jnz & my_label {`brch, `drt, `cnd_nz, `jmp_next, 8’hxx}
Jc & my_label
{`brch, `drt, `cnd_c, `jmp_next, 8’hxx}
Jnc & my_label {`brch, `drt, `cnd_nc, `jmp_next, 8’hxx}
Jw & my_label
{`brch, `drt, `cnd_non, `jmp_wait, 8’hxx}
Jmp @ r1r0
{`brch, `ptr, `cnd_non, `jmp_next, 8’h00}
{`brch, `ptr, `cnd_z, `jmp_next, 8’h00}
Jnz @ r1r0
{`brch, `ptr, `cnd_nz, `jmp_next, 8’h00}
{`brch, `ptr, `cnd_c, `jmp_next, 8’h00}
Jnc @ r1r0
{`brch, `ptr, `cnd_nc, `jmp_next, 8’h00}
{`brch, `ptr, `cnd_non, `jmp_wait, 8’h00}
odst.clear();
errmsg.clear();
if (isource.size() != 3)
errmsg = SplitError(&format is not \&jxx &/@ label/r1r0\&&, Vector2String(isource));
string flag(MyToLower(isource[1]));//获取符号
auto flagit = find(g_JF, g_JF + g_JFN, flag);//查找符号
if (flagit == g_JF + g_JFN)//没找到符号
errmsg = SplitError(&not find flag \&@/&\&&, Vector2String(isource));
if (*flagit == g_JF[g_JFI::JAND])//&
if (g_labeladdrmap.find(isource[2]) == g_labeladdrmap.end())//查找标签
errmsg = SplitError(&not find the label address&, Vector2String(isource));
string tmparray[5] = { &`brch&, &`drt&, &`cnd_non&, &`jmp_next&, &8'h& };
odst.assign(tmparray, tmparray + 5);
char sztmp[20] = { 0 };
MySprintf(sztmp, sizeof(sztmp), &%02x&, (char)(g_labeladdrmap[isource[2]]));
odst[4] +=
switch (cmdindex)
case g_JCI::JMP:
case g_JCI::JZ:
odst[2] = &`cnd_z&;
case g_JCI::JNZ:
odst[2] = &`cnd_nz&;
case g_JCI::JC:
odst[2] = &`cnd_c&;
case g_JCI::JNC:
odst[2] = &`cnd_nc&;
case g_JCI::JW:
odst[3] = &`jmp_wait&;
errmsg = SplitError(&format is not \&jxx &/@ label/r1r0\&&, Vector2String(isource));
if (MyToLower(isource[2]) != MyToLower(&r1r0&))
errmsg = SplitError(&not defined&, Vector2String(isource));
string tmparray[5] = { &`brch&, &`ptr&, &`cnd_non&, &`jmp_next&, &8'h00& };
odst.assign(tmparray, tmparray + 5);
switch (cmdindex)
case g_JCI::JMP:
case g_JCI::JZ:
odst[2] = &`cnd_z&;
case g_JCI::JNZ:
odst[2] = &`cnd_nz&;
case g_JCI::JC:
odst[2] = &`cnd_c&;
case g_JCI::JNC:
odst[2] = &`cnd_nc&;
case g_JCI::JW:
odst[3] = &`jmp_wait&;
errmsg = SplitError(&format is not \&jxx &/@ label/r1r0\&&, Vector2String(isource));
操作的OperatorHandle:
bool AsmAlgorithm::OperatorHandle(const int cmdindex, const vector&string& &isource,
vector&string&&odst, string &errmsg)
{//格式 operator rega regb
Add rega regb {`arth, `add, `rega, `regb}
Sub rega regb {`arth, `sub, `rega, `regb}
Mul rega regb {`arth, `mul, `rega, `regb}
Mac rega regb {`arth, `mac, `rega, `regb}
Div rega regb {`arth, `div, `rega, `regb}
Sqt rega regb {`arth, `sqt, `rega, `regb}
odst.clear();
errmsg.clear();
if (isource.size() != 4)
errmsg = SplitError(&format is not \&operator rega regb\&&, Vector2String(isource));
//{`arth, `add, `rega, `regb}
odst.push_back(&`& + isource[0]);
odst.push_back(&`& + isource[1]);
odst.push_back(&`& + isource[2]);
odst.push_back(&`& + isource[3]);
shell的ShellHandle:
bool AsmAlgorithm::ShellHandle(const int cmdindex, const vector&string& &isource,
vector&string&&odst, string &errmsg)
{//格式 Shl 0 nmb regs
Shl 0 nmb regs {`shft, `left, `with_0, `act, `nmb, `regs}
Shl 1 nmb regs {`shft, `left, `with_1, `act, `nmb, `regs}
Shl s nmb regs {`shft, `left, `with_s, `act, `nmb, `regs}
{`shft, `left, `with_r, `act, 1’b1, `regs}
Shr 0 nmb regs {`shft, `right, `with_0, `act, `nmb, `regs}
Shr 1 nmb regs {`shft, `right, `with_1, `act, `nmb, `regs}
Shr s nmb regs {`shft, `right, `with_s, `act, `nmb, `regs}
{`shft, `right, `with_r, `act, 1’b1, `regs}
odst.clear();
errmsg.clear();
string tmparray[6] = { &`shft&, &`left&, &`with_&, &`act&, &`&, &`& };
odst.assign(tmparray, tmparray + 6);
switch (cmdindex)
case g_SCI::NOP:
if (isource.size() != 1)
errmsg = SplitError(&format is not \&nop\&&, Vector2String(isource));
odst.clear();
odst.push_back(&16'b0&);
case g_SCI::RTTL:
case g_SCI::RTTR:
if (isource.size() != 2)
errmsg = SplitError(&format is not \&rttl/rttr regs\&&, Vector2String(isource));
odst[2] = &`with_r&;
odst[4] = &1'b1&;
odst[5] += isource[1];
if (cmdindex == g_SCI::RTTR)
odst[1] = &`right&;
case g_SCI::SHL:
case g_SCI::SHR:
if (isource.size() != 4)
errmsg = SplitError(&format is not \&shl/shr 0/1/s nmb regs\&&, Vector2String(isource));
string flag(MyToLower(isource[1]));//获取符号
auto flagit = find(g_SF, g_SF + g_SFN, flag);
if (flagit == g_SF + g_SFN)//没找到
errmsg = SplitError(&not find flag \&0/1/s\&&, Vector2String(isource));
odst[2] += g_SF[flagit - g_SF];
odst[4] += isource[2];
odst[5] += isource[3];
if (cmdindex == g_SCI::SHR)
odst[1] = &`right&;
errmsg = SplitError(&format is not \&nop/shl/shr/rttl/rttr ...\&&, Vector2String(isource));
传送的TransmitHandle:
bool AsmAlgorithm::TransmitHandle(const int cmdindex, const vector&string& &isource,
vector&string&&odst, string &errmsg)
{//格式 ld/st regx #/&/@/_ xxx
Ld regs # 立即数
{`ldst, `ld_drt_data, `regs, 8’h立即数}
Ld regs & 立即地址 {`ldst, `ld_drt_addr, `regs, `立即数据地址}
St regs & 立即地址 {`ldst, `st_drt_addr, `regs, `立即数据地址}
Ld rega regb
{`ldst, `reg_or_ptr, `rega, `ld_reg, `regb}
St rega regb
{`ldst, `reg_or_ptr, `rega, `st_reg, `regb}
Ld regs @ r1r0
{`ldst, `reg_or_ptr, `regs, `ld_ptr, 4’b0}
St regs @ r1r0
{`ldst, `reg_or_ptr, `regs, `st_ptr, 4’b0}
odst.clear();
errmsg.clear();
const int isourcesize = isource.size();
if (isourcesize != 3 && isourcesize != 4)
errmsg = SplitError(&format is not \&ld/st regx #/&/@/_ xxx\&&, Vector2String(isource));
if (isourcesize == 3)
string temparray[5] = { &`ldst&, &`reg_or_ptr&, &`&, &`ld_reg&, &`& };
odst.assign(temparray, temparray + 5);
odst[2] += isource[1];
odst[4] += isource[2];
if (cmdindex==g_TCI::ST)
odst[3] = &`st_reg&;
else//4个元素
auto flagit = find(g_TF, g_TF + g_TFN, isource[2]);//查找标志
if (flagit == g_TF + g_TFN)//没找到
errmsg = SplitError(&not find flag \&#/&/@\&&, Vector2String(isource));
const int flagoffset = flagit - g_TF;//获取标志所在的偏移量
switch (flagoffset)
case g_TFI::TWELL://#
string temparray[4] = { &`ldst&, &`ld_drt_data&, &`&, &8'h&};
odst.assign(temparray, temparray + 4);
odst[2] += isource[1];
//判断是label_page还是立即数
const auto findpos = isource[3].rfind(&_page&);
if (findpos == string::npos)//没找到 _page
odst[3] += isource[3];
string label = isource[3].substr(0, findpos);
if (g_labeladdrmap.find(label) == g_labeladdrmap.end())//查找标签
errmsg = SplitError(&not find the label address&, Vector2String(isource));
char hight8addr[20] = { 0 };
MySprintf(hight8addr, sizeof(hight8addr), &%02x&, (char)(g_labeladdrmap[label] && 8));
odst[3] += hight8
case g_TFI::TAND://&
string temparray[4] = { &`ldst&, &`ld_drt_addr&, &`&, &`& };
odst.assign(temparray, temparray + 4);
odst[2] += isource[1];
odst[3] += isource[3];
if (cmdindex==g_TCI::ST)
odst[1] = &`st_drt_addr&;
//判断是否已存在,如果存在就不用写到寄存器地址列表中
string reg = isource[3];
auto regit = find_if(g_reglist.begin(), g_reglist.end(),
[reg](const pair&string, int& & item){return item.first == });
if (regit == g_reglist.end())
AddRegAddr(isource[3]);//添加到寄存器地址列表中去
case g_TFI::TAT://@
if (MyToLower(isource[3]) != MyToLower(&r1r0&))
errmsg = SplitError(&not defined&, Vector2String(isource));
string temparray[5] = { &`ldst&, &`reg_or_ptr&, &`&, &`ld_ptr&, &4'b0& };
odst.assign(temparray, temparray + 5);
odst[2] += isource[1];
if (cmdindex == g_TCI::ST)
odst[3] = &`st_ptr&;
errmsg = SplitError(&format is not \&ld/st regx #/&/@/_ xxx\&&, Vector2String(isource));
获取私有成员变量的get函数不再列出。
8、打印结果
在主程序中,调用Handle处理完之后就可以打印信息:
//写入文件中
switch (filelist.size())
cout && &macro info into & && filelist[4] &&
WriteFile(filelist[4], myasm.GetMacro());
cout && &macro and data info into & && filelist[3] &&
WriteFile(filelist[3], myasm.GetMacroData());
cout && &register info into & && filelist[2] &&
WriteFile(filelist[2], myasm.GetReg());
cout && &data info into & && filelist[1] &&
WriteFile(filelist[1], myasm.GetData());
//打印到界面上
for (auto it = paraset.begin(); it != paraset.end(); ++it)
switch (*it)
case g_parai::D:
cout && &print data info :& &&
cout && myasm.GetData()&&
case g_parai::R:
cout && &print register info :& &&
cout && myasm.GetReg() &&
case g_parai::MD:
cout && &print macro and data info :& &&
cout && myasm.GetMacroData() &&
case g_parai::M:
cout && &print macro info :& &&
cout && myasm.GetMacro() &&
9、在Win控制台和gcc下的makefile
#Win下编译
#需要vcvars32.bat环境支持
#nmake 本文件
asmtranslator.exe : main.obj asmalgorithm.obj file.obj
link.exe main.obj asmalgorithm.obj file.obj /out:asmtranslator.exe
@del *.obj
main.obj:main.cpp
cl.exe /c /EHsc main.cpp
asmalgorithm.obj:asmalgorithm.cpp
cl.exe /c /EHsc asmalgorithm.cpp
file.obj:file.cpp
cl.exe /c /EHsc file.cpp
这个需要vcvars32.bat的环境支持。我开始编的时候能编译过去,后来不知调整了什么就编译不过了,只能分开编译。
#g++ build
#make -f thisfile
AsmTranslator.out: main.o asmalgorithm.o file.o
g++ -o AsmTranslator.out main.o asmalgorithm.o file.o
#clear .o file
@rm -rf *.o
main.o: main.cpp
g++ -std=c++11 -c main.cpp
asmalgorithm.o: asmalgorithm.cpp asmalgorithm.h os.h
g++ -std=c++11 -c asmalgorithm.cpp
file.o: file.cpp file.h
g++ -std=c++11 -c file.cpp
10、测试:
我用1中的那个文件在gcc中使用 ./AsmTranslator.out infile.txt -d -r 测试结果如下:
----------welcome-----------------
welcom to ./AsmTranslator.out!
print data info :
16'h0000 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h0001 : begin instr = {`ldst,`st_drt_addr,`r64_0,`szy_data_save}end
16'h0002 : begin instr = {`ldst,`ld_drt_data,`r1,8'h5a}end
16'h0003 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h0004 : begin instr = {`ldst,`ld_drt_data,`r1,8'h5a}end
16'h0005 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h0006 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h0007 : begin instr = {`ldst,`st_drt_addr,`r64_0,`szy_data_save}end
16'h0008 : begin instr = {`ldst,`ld_drt_data,`r1,8'h5a}end
16'h0009 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h000a : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h000b : begin instr = {`ldst,`ld_drt_addr,`r64_0,`lpf_alu_result}end
16'h000c : begin instr = {`brch,`drt,`cnd_nz,`jmp_next,8'h0b}end
16'h000d : begin instr = {`ldst,`ld_drt_addr,`r64_0,`alu_result}end
16'h000e : begin instr = {`ldst,`ld_drt_data,`r3,8'h00}end
16'h000f : begin instr = {`brch,`drt,`cnd_z,`jmp_next,8'h0d}end
16'h0010 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h0011 : begin instr = {`ldst,`st_drt_addr,`r64_0,`cic_data_save}end
16'h0012 : begin instr = {`ldst,`ld_drt_data,`r1,8'h5a}end
16'h0013 : begin instr = {`arth,`mus,`r32_0,`r32_1}end
16'h0014 : begin instr = {`ldst,`ld_drt_addr,`r64_0,`szy_alu_result}end
16'h0015 : begin instr = {`ldst,`st_drt_addr,`r64_0,`data_save}end
16'h0016 : begin instr = {`ldst,`ld_drt_data,`r1,8'h5a}end
print register info :
`define szy_data_save
`define lpf_alu_result
`define alu_result
`define cic_data_save
`define szy_alu_result
`define data_save
----------------------------------11、我已压缩这个工程传到这儿了,有需要的朋友可以下载。




&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:10367次
排名:千里之外
原创:11篇
(8)(1)(1)(10)

我要回帖

更多关于 中英文翻译软件 的文章

 

随机推荐