Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
Hardware-IRQ
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
Dream Logic Group
实验项目模板
计算机组成原理
Hardware-IRQ
提交
ce75876e
提交
ce75876e
11月 12, 2019
创建
作者:
赵鹏翀
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'c-code' into 'master'
change c code See merge request
!9
上级
40869280
08724b1b
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
2957 行增加
和
2957 行删除
+2957
-2957
dmasm.c
dmasm.c
+2075
-2075
microasm.c
microasm.c
+882
-882
没有找到文件。
dmasm.c
浏览文件 @
ce75876e
这个 源代码变更 因为 太大 而不能显示。 你可以
浏览blob
。
microasm.c
浏览文件 @
ce75876e
/*******************************************************************************
/*******************************************************************************
Copyright (c) 2008 - 2018 北京英真时代科技有限公司。保留所有权利。
Copyright (c) 2008 - 2018 北京英真时代科技有限公司。保留所有权利。
*******************************************************************************/
*******************************************************************************/
#
include <stdio.h>
#
define _CRT_SECURE_NO_WARNINGS
#
include <stdlib.h>
#
define _CRT_NONSTDC_NO_DEPRECATE
#include <string.h>
#include <
ctype.h>
#include <
stdio.h>
#include <stdlib.h>
typedef
unsigned
char
BYTE
;
#include <string.h>
typedef
long
BOOL
;
#include <ctype.h>
#define FALSE 0
typedef
unsigned
char
BYTE
;
#define TRUE 1
typedef
long
BOOL
;
#define FALSE 0
#define
MAX_LINE_LENGTH 256 // 一行代码最多可以有多少个字符
#define
TRUE 1
#define MAX_LINE_COUNT 1024 // 源代码文件最多可以有多少行
#define MAX_LINE_LENGTH 256 // 一行代码最多可以有多少个字符
#define MAX_
SYMBOL_LENGTH 64 // 一个符号最多可以包含多少个字符
#define MAX_
LINE_COUNT 1024 // 源代码文件最多可以有多少行
#define MAX_SYMBOL_COUNT 256 // 源代码文件中最多可以包含多少个符号
#define MAX_SYMBOL_LENGTH 64 // 一个符号最多可以包含多少个字符
#
ifndef MAX_PATH
#
define MAX_SYMBOL_COUNT 256 // 源代码文件中最多可以包含多少个符号
#define MAX_PATH 256 // 文件路径最多可以包含多少了字符
#
endif
#
ifndef MAX_PATH
#define MAX_PATH 256 // 文件路径最多可以包含多少了字符
#endif
// 代码行数据库。记录源代码文件中所有代码行的信息(包括注释行、空行)
struct
LINE_RECORD
// 代码行数据库。记录源代码文件中所有代码行的信息(包括注释行、空行)
{
struct
LINE_RECORD
char
line_string
[
MAX_LINE_LENGTH
];
// 代码行的内容
{
unsigned
long
line_num
;
// 行号
char
line_string
[
MAX_LINE_LENGTH
];
// 代码行的内容
unsigned
long
address
;
// 此行代码转换的机器码在映像文件中的地址(偏移)。注意,对于 DM1000 来说,微指令的一个地址对应 4 个字节。
unsigned
long
line_num
;
// 行号
int
machine_code_count
;
// 此行代码转换的机器码的字节数量
unsigned
long
address
;
// 此行代码转换的机器码在映像文件中的地址(偏移)。注意,对于 DM1000 来说,微指令的一个地址对应 4 个字节。
unsigned
long
flag
;
// 代码行标志位,32位
int
machine_code_count
;
// 此行代码转换的机器码的字节数量
};
unsigned
long
flag
;
// 代码行标志位,32位
struct
LINE_RECORD
line_database
[
MAX_LINE_COUNT
]
=
{
0
};
};
int
line_count
=
0
;
struct
LINE_RECORD
line_database
[
MAX_LINE_COUNT
]
=
{
0
};
int
machine_code_line_count
=
0
;
// 记录产生了机器码的代码行的数量
int
line_count
=
0
;
int
machine_code_line_count
=
0
;
// 记录产生了机器码的代码行的数量
// 在此定义所有的代码行标志位。注意,代码行标志位是按位或的关系。
#define LF_INSTRUCTION 0x00000001 // 代码行标志位的最低位是1,表示此行是一条指令,否则表示此行是数据
// 在此定义所有的代码行标志位。注意,代码行标志位是按位或的关系。
#define LF_INSTRUCTION 0x00000001 // 代码行标志位的最低位是1,表示此行是一条指令,否则表示此行是数据
//
//
在下面定义所有的关键字
//
//
//
在下面定义所有的关键字
//
// 寄存器名称
// 寄存器名称
const
char
*
rx_register_keyword
=
"rx"
;
const
char
*
rx_register_keyword
=
"rx"
;
const
char
*
mar_register_keyword
=
"mar"
;
const
char
*
mar_register_keyword
=
"mar"
;
const
char
*
rin_register_keyword
=
"rin"
;
const
char
*
rin_register_keyword
=
"rin"
;
const
char
*
rout_register_keyword
=
"rout"
;
const
char
*
rout_register_keyword
=
"rout"
;
const
char
*
sp_register_keyword
=
"sp"
;
const
char
*
sp_register_keyword
=
"sp"
;
const
char
*
ia_register_keyword
=
"ia"
;
const
char
*
ia_register_keyword
=
"ia"
;
const
char
*
ir_register_keyword
=
"ir"
;
const
char
*
ir_register_keyword
=
"ir"
;
const
char
*
flag_register_keyword
=
"flag"
;
const
char
*
flag_register_keyword
=
"flag"
;
const
char
*
pc_register_keyword
=
"pc"
;
const
char
*
pc_register_keyword
=
"pc"
;
const
char
*
a_register_keyword
=
"a"
;
const
char
*
a_register_keyword
=
"a"
;
const
char
*
w_register_keyword
=
"w"
;
const
char
*
w_register_keyword
=
"w"
;
const
char
*
asr_register_keyword
=
"asr"
;
const
char
*
asr_register_keyword
=
"asr"
;
const
char
*
upc_register_keyword
=
"upc"
;
const
char
*
upc_register_keyword
=
"upc"
;
// 堆栈计数器
// 堆栈计数器
const
char
*
csp_counter_keyword
=
"csp"
;
const
char
*
csp_counter_keyword
=
"csp"
;
//
//
// alu 操作码
// alu 操作码
const
char
*
alu_add_keyword
=
"alu_add"
;
const
char
*
alu_add_keyword
=
"alu_add"
;
const
char
*
alu_adc_keyword
=
"alu_adc"
;
const
char
*
alu_adc_keyword
=
"alu_adc"
;
const
char
*
alu_sub_keyword
=
"alu_sub"
;
const
char
*
alu_sub_keyword
=
"alu_sub"
;
const
char
*
alu_sbb_keyword
=
"alu_sbb"
;
const
char
*
alu_sbb_keyword
=
"alu_sbb"
;
const
char
*
alu_and_keyword
=
"alu_and"
;
const
char
*
alu_and_keyword
=
"alu_and"
;
const
char
*
alu_or_keyword
=
"alu_or"
;
const
char
*
alu_or_keyword
=
"alu_or"
;
const
char
*
alu_aout_keyword
=
"alu_aout"
;
const
char
*
alu_aout_keyword
=
"alu_aout"
;
const
char
*
alu_shr_keyword
=
"alu_shr"
;
const
char
*
alu_shr_keyword
=
"alu_shr"
;
const
char
*
alu_shl_keyword
=
"alu_shl"
;
const
char
*
alu_shl_keyword
=
"alu_shl"
;
const
char
*
alu_rcr_keyword
=
"alu_rcr"
;
const
char
*
alu_rcr_keyword
=
"alu_rcr"
;
const
char
*
alu_rcl_keyword
=
"alu_rcl"
;
const
char
*
alu_rcl_keyword
=
"alu_rcl"
;
const
char
*
alu_not_keyword
=
"alu_not"
;
const
char
*
alu_not_keyword
=
"alu_not"
;
const
char
*
sp_inc_keyword
=
"sp_inc"
;
const
char
*
sp_inc_keyword
=
"sp_inc"
;
const
char
*
sp_dec_keyword
=
"sp_dec"
;
const
char
*
sp_dec_keyword
=
"sp_dec"
;
const
char
*
int_ia_keyword
=
"int_ia"
;
const
char
*
int_ia_keyword
=
"int_ia"
;
// 访问主存或外设的操作数
// 访问主存或外设的操作数
const
char
*
pc_main_memory_keyword
=
"[pc]"
;
const
char
*
pc_main_memory_keyword
=
"[pc]"
;
const
char
*
mar_main_memory_keyword
=
"[mar]"
;
const
char
*
mar_main_memory_keyword
=
"[mar]"
;
const
char
*
delimit_char
=
"
\n\t\r
"
;
// 需要忽略的空白字符
const
char
*
delimit_char
=
"
\n\t\r
"
;
// 需要忽略的空白字符
const
char
*
delimit_char_comma
=
"
\n\t\r
, "
;
// 需要忽略的空白字符,包括英文逗号
const
char
*
delimit_char_comma
=
"
\n\t\r
, "
;
// 需要忽略的空白字符,包括英文逗号
// 单操作数微指令
// 单操作数微指令
struct
ONE_OPERAND_INSTRUCTION_ENTRY
struct
ONE_OPERAND_INSTRUCTION_ENTRY
{
{
const
char
**
op
;
const
char
**
op
;
unsigned
long
micro_machine_code
;
unsigned
long
micro_machine_code
;
};
};
struct
ONE_OPERAND_INSTRUCTION_ENTRY
one_operand_table
[]
=
struct
ONE_OPERAND_INSTRUCTION_ENTRY
one_operand_table
[]
=
{
{
{
NULL
,
0x0
}
// 未用
{
NULL
,
0x0
}
// 未用
,{
&
pc_register_keyword
,
0xffffffff
}
// inc pc
,{
&
pc_register_keyword
,
0xffffffff
}
// inc pc
,{
&
upc_register_keyword
,
0xffffffcf
}
// reset upc
,{
&
upc_register_keyword
,
0xffffffcf
}
// reset upc
};
};
// 查表,操作数是否匹配。返回0,操作数不匹配;返回非0,操作数匹配,并且返回值就是操作数在表中的下标。
// 查表,操作数是否匹配。返回0,操作数不匹配;返回非0,操作数匹配,并且返回值就是操作数在表中的下标。
int
match_one_operand
(
const
char
*
op
)
int
match_one_operand
(
const
char
*
op
)
{
{
int
i
;
int
i
;
for
(
i
=
1
;
i
<
sizeof
(
one_operand_table
)
/
sizeof
(
one_operand_table
[
0
]);
i
++
)
for
(
i
=
1
;
i
<
sizeof
(
one_operand_table
)
/
sizeof
(
one_operand_table
[
0
]);
i
++
)
{
{
if
((
stricmp
(
op
,
*
one_operand_table
[
i
].
op
)
==
0
))
if
((
stricmp
(
op
,
*
one_operand_table
[
i
].
op
)
==
0
))
{
{
return
i
;
return
i
;
}
}
}
}
return
0
;
return
0
;
}
}
// 双操作数微指令
// 双操作数微指令
struct
PATH_INSTRUCTION_OPERAND_ENTRY
struct
PATH_INSTRUCTION_OPERAND_ENTRY
{
{
const
char
**
op1
;
const
char
**
op1
;
const
char
**
op2
;
const
char
**
op2
;
unsigned
long
micro_machine_code
;
unsigned
long
micro_machine_code
;
};
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
//
struct
PATH_INSTRUCTION_OPERAND_ENTRY
path_operand_table
[]
=
struct
PATH_INSTRUCTION_OPERAND_ENTRY
path_operand_table
[]
=
{
{
{
NULL
,
NULL
,
0x0
}
// 未用
{
NULL
,
NULL
,
0x0
}
// 未用
,{
&
pc_main_memory_keyword
,
&
ir_register_keyword
,
0xfff93fef
}
// path [pc], ir ff e3 ff ff
,{
&
pc_main_memory_keyword
,
&
ir_register_keyword
,
0xfff93fef
}
// path [pc], ir ff e3 ff ff
,{
&
alu_add_keyword
,
&
a_register_keyword
,
0x99e4ffef
}
// path alu_add, a ff ff fe 90
,{
&
alu_add_keyword
,
&
a_register_keyword
,
0x99e4ffef
}
// path alu_add, a ff ff fe 90
,{
&
alu_sub_keyword
,
&
a_register_keyword
,
0x86e4ffef
}
// path alu_sub, a ff ff fe 91
,{
&
alu_sub_keyword
,
&
a_register_keyword
,
0x86e4ffef
}
// path alu_sub, a ff ff fe 91
,{
&
alu_or_keyword
,
&
a_register_keyword
,
0xbee4ffef
}
// path alu_or, a
,{
&
alu_or_keyword
,
&
a_register_keyword
,
0xbee4ffef
}
// path alu_or, a
,{
&
alu_and_keyword
,
&
a_register_keyword
,
0xbbe4ffef
}
// path alu_and, a
,{
&
alu_and_keyword
,
&
a_register_keyword
,
0xbbe4ffef
}
// path alu_and, a
,{
&
alu_adc_keyword
,
&
a_register_keyword
,
0x89e4ffef
}
// path alu_adc, a
,{
&
alu_adc_keyword
,
&
a_register_keyword
,
0x89e4ffef
}
// path alu_adc, a
,{
&
alu_sbb_keyword
,
&
a_register_keyword
,
0x96e4ffef
}
// path alu_sbb, a
,{
&
alu_sbb_keyword
,
&
a_register_keyword
,
0x96e4ffef
}
// path alu_sbb, a
,{
&
alu_shr_keyword
,
&
a_register_keyword
,
0x90d5ffef
}
// path alu_shr, a ff ff fc b7
,{
&
alu_shr_keyword
,
&
a_register_keyword
,
0x90d5ffef
}
// path alu_shr, a ff ff fc b7
,{
&
alu_shl_keyword
,
&
a_register_keyword
,
0x90d6ffef
}
// path alu_shl, a
,{
&
alu_shl_keyword
,
&
a_register_keyword
,
0x90d6ffef
}
// path alu_shl, a
,{
&
alu_rcr_keyword
,
&
a_register_keyword
,
0x90e5ffef
}
// path alu_rcr, a
,{
&
alu_rcr_keyword
,
&
a_register_keyword
,
0x90e5ffef
}
// path alu_rcr, a
,{
&
alu_rcl_keyword
,
&
a_register_keyword
,
0x90e6ffef
}
// path alu_rcl, a
,{
&
alu_rcl_keyword
,
&
a_register_keyword
,
0x90e6ffef
}
// path alu_rcl, a
,{
&
alu_not_keyword
,
&
a_register_keyword
,
0xb0f4ffef
}
// path alu_not, a
,{
&
alu_not_keyword
,
&
a_register_keyword
,
0xb0f4ffef
}
// path alu_not, a
,{
&
rx_register_keyword
,
&
w_register_keyword
,
0x7ffaffef
}
// path rx, w
,{
&
rx_register_keyword
,
&
w_register_keyword
,
0x7ffaffef
}
// path rx, w
,{
&
rx_register_keyword
,
&
mar_register_keyword
,
0xfffaf7ef
}
// path rx, mar
,{
&
rx_register_keyword
,
&
mar_register_keyword
,
0xfffaf7ef
}
// path rx, mar
,{
&
mar_main_memory_keyword
,
&
w_register_keyword
,
0x7ff9fbef
}
// path [mar], w
,{
&
mar_main_memory_keyword
,
&
w_register_keyword
,
0x7ff9fbef
}
// path [mar], w
,{
&
pc_main_memory_keyword
,
&
mar_register_keyword
,
0xfff977ef
}
// path [pc], mar
,{
&
pc_main_memory_keyword
,
&
mar_register_keyword
,
0xfff977ef
}
// path [pc], mar
,{
&
pc_main_memory_keyword
,
&
w_register_keyword
,
0x7ff97fef
}
// path [pc], w
,{
&
pc_main_memory_keyword
,
&
w_register_keyword
,
0x7ff97fef
}
// path [pc], w
,{
&
rx_register_keyword
,
&
a_register_keyword
,
0xbffaffef
}
// path rx, a
,{
&
rx_register_keyword
,
&
a_register_keyword
,
0xbffaffef
}
// path rx, a
,{
&
mar_main_memory_keyword
,
&
a_register_keyword
,
0xbff9fbef
}
// path [mar], a 从地址寄存器指定的内存单元读数据到a寄存器
,{
&
mar_main_memory_keyword
,
&
a_register_keyword
,
0xbff9fbef
}
// path [mar], a 从地址寄存器指定的内存单元读数据到a寄存器
,{
&
pc_main_memory_keyword
,
&
a_register_keyword
,
0xbff97fef
}
// path [pc], a
,{
&
pc_main_memory_keyword
,
&
a_register_keyword
,
0xbff97fef
}
// path [pc], a
,{
&
a_register_keyword
,
&
rx_register_keyword
,
0xd0b4ffef
}
// path a, rx
,{
&
a_register_keyword
,
&
rx_register_keyword
,
0xd0b4ffef
}
// path a, rx
,{
&
a_register_keyword
,
&
mar_main_memory_keyword
,
0xd0f4fbed
}
// path a, [mar] 将a寄存器数据写入地址寄存器指向的内存
,{
&
a_register_keyword
,
&
mar_main_memory_keyword
,
0xd0f4fbed
}
// path a, [mar] 将a寄存器数据写入地址寄存器指向的内存
,{
&
pc_main_memory_keyword
,
&
rx_register_keyword
,
0xffb97fef
}
// path [pc], rx
,{
&
pc_main_memory_keyword
,
&
rx_register_keyword
,
0xffb97fef
}
// path [pc], rx
,{
&
alu_aout_keyword
,
&
mar_main_memory_keyword
,
0xd0f4fbec
}
// path alu_aout, [mar]
,{
&
alu_aout_keyword
,
&
mar_main_memory_keyword
,
0xd0f4fbec
}
// path alu_aout, [mar]
,{
&
pc_main_memory_keyword
,
&
pc_register_keyword
,
0xfff96fff
}
// path [pc], pc
,{
&
pc_main_memory_keyword
,
&
pc_register_keyword
,
0xfff96fff
}
// path [pc], pc
,{
&
pc_register_keyword
,
&
sp_register_keyword
,
0xfff3feef
}
// path pc, sp
,{
&
pc_register_keyword
,
&
sp_register_keyword
,
0xfff3feef
}
// path pc, sp
,{
&
ia_register_keyword
,
&
mar_register_keyword
,
0xfff1f7ef
}
// path ia, mar
,{
&
ia_register_keyword
,
&
mar_register_keyword
,
0xfff1f7ef
}
// path ia, mar
,{
&
pc_register_keyword
,
&
mar_register_keyword
,
0xfff3f7ef
}
// path pc, mar
,{
&
pc_register_keyword
,
&
mar_register_keyword
,
0xfff3f7ef
}
// path pc, mar
,{
&
rin_register_keyword
,
&
a_register_keyword
,
0xbff0ffef
}
// path rin, a
,{
&
rin_register_keyword
,
&
a_register_keyword
,
0xbff0ffef
}
// path rin, a
,{
&
a_register_keyword
,
&
rout_register_keyword
,
0xd0f4ffee
}
// path a, rout
,{
&
a_register_keyword
,
&
rout_register_keyword
,
0xd0f4ffee
}
// path a, rout
,{
&
mar_main_memory_keyword
,
&
pc_register_keyword
,
0xfff9ebef
}
// path [mar], pc 从地址寄存器指定的内存单元读数据到程序计数器pc
,{
&
mar_main_memory_keyword
,
&
pc_register_keyword
,
0xfff9ebef
}
// path [mar], pc 从地址寄存器指定的内存单元读数据到程序计数器pc
,{
&
pc_main_memory_keyword
,
&
sp_register_keyword
,
0xfff97eef
}
// path [pc], sp
,{
&
pc_main_memory_keyword
,
&
sp_register_keyword
,
0xfff97eef
}
// path [pc], sp
,{
&
sp_register_keyword
,
&
mar_register_keyword
,
0xfff2f7ef
}
// path sp, mar
,{
&
sp_register_keyword
,
&
mar_register_keyword
,
0xfff2f7ef
}
// path sp, mar
,{
&
sp_register_keyword
,
&
csp_counter_keyword
,
0xff72ffef
}
// path sp, csp
,{
&
sp_register_keyword
,
&
csp_counter_keyword
,
0xff72ffef
}
// path sp, csp
,{
&
pc_main_memory_keyword
,
&
ia_register_keyword
,
0xfff97feb
}
// path [pc], ia
,{
&
pc_main_memory_keyword
,
&
ia_register_keyword
,
0xfff97feb
}
// path [pc], ia
,{
&
pc_main_memory_keyword
,
&
asr_register_keyword
,
0xfff97def
}
// path [pc], asr
,{
&
pc_main_memory_keyword
,
&
asr_register_keyword
,
0xfff97def
}
// path [pc], asr
,{
&
csp_counter_keyword
,
&
mar_register_keyword
,
0xfff8f7ef
}
// path csp, mar
,{
&
csp_counter_keyword
,
&
mar_register_keyword
,
0xfff8f7ef
}
// path csp, mar
,{
&
csp_counter_keyword
,
&
sp_register_keyword
,
0xfff8feef
}
// path csp, sp
,{
&
csp_counter_keyword
,
&
sp_register_keyword
,
0xfff8feef
}
// path csp, sp
,{
&
sp_inc_keyword
,
&
csp_counter_keyword
,
0xffffffe7
}
// path sp_inc, csp
,{
&
sp_inc_keyword
,
&
csp_counter_keyword
,
0xffffffe7
}
// path sp_inc, csp
,{
&
sp_dec_keyword
,
&
csp_counter_keyword
,
0xffffffef
}
// path sp_dec, csp
,{
&
sp_dec_keyword
,
&
csp_counter_keyword
,
0xffffffef
}
// path sp_dec, csp
,{
&
pc_register_keyword
,
&
mar_main_memory_keyword
,
0xfff3fbed
}
// path pc, [mar] 将pc值写入mar指向的存储单元
,{
&
pc_register_keyword
,
&
mar_main_memory_keyword
,
0xfff3fbed
}
// path pc, [mar] 将pc值写入mar指向的存储单元
,{
&
asr_register_keyword
,
&
pc_register_keyword
,
0xfff7efef
}
// path asr, pc
,{
&
asr_register_keyword
,
&
pc_register_keyword
,
0xfff7efef
}
// path asr, pc
,{
&
sp_register_keyword
,
&
asr_register_keyword
,
0xfff2fdef
}
// path sp, asr
,{
&
sp_register_keyword
,
&
asr_register_keyword
,
0xfff2fdef
}
// path sp, asr
,{
&
int_ia_keyword
,
&
mar_register_keyword
,
0xfff1f7ef
}
// path int_ia, mar
,{
&
int_ia_keyword
,
&
mar_register_keyword
,
0xfff1f7ef
}
// path int_ia, mar
};
};
// 查表,判断两个操作数是否匹配。返回0,操作数不完全匹配;返回非0,操作数完全匹配,并且返回值就是操作数在表中的下标。
// 查表,判断两个操作数是否匹配。返回0,操作数不完全匹配;返回非0,操作数完全匹配,并且返回值就是操作数在表中的下标。
int
match_ops
(
const
char
*
op1
,
const
char
*
op2
)
int
match_ops
(
const
char
*
op1
,
const
char
*
op2
)
{
{
int
i
;
int
i
;
for
(
i
=
1
;
i
<
sizeof
(
path_operand_table
)
/
sizeof
(
path_operand_table
[
0
]);
i
++
)
for
(
i
=
1
;
i
<
sizeof
(
path_operand_table
)
/
sizeof
(
path_operand_table
[
0
]);
i
++
)
{
{
if
((
stricmp
(
op1
,
*
path_operand_table
[
i
].
op1
)
==
0
)
if
((
stricmp
(
op1
,
*
path_operand_table
[
i
].
op1
)
==
0
)
&&
(
stricmp
(
op2
,
*
path_operand_table
[
i
].
op2
)
==
0
))
&&
(
stricmp
(
op2
,
*
path_operand_table
[
i
].
op2
)
==
0
))
{
{
return
i
;
return
i
;
}
}
}
}
return
0
;
return
0
;
}
}
// 汇编产生的机器码
// 汇编产生的机器码
#define MAX_MACHINE_CODE 1024
#define MAX_MACHINE_CODE 1024
BYTE
machine_code
[
MAX_MACHINE_CODE
];
BYTE
machine_code
[
MAX_MACHINE_CODE
];
unsigned
long
machine_code_address
=
0
;
// 一个地址对应一个字节
unsigned
long
machine_code_address
=
0
;
// 一个地址对应一个字节
unsigned
long
machine_code_old_address
=
0
;
unsigned
long
machine_code_old_address
=
0
;
const
char
*
micro_file_name
=
NULL
;
// 微指令文件路径
const
char
*
micro_file_name
=
NULL
;
// 微指令文件路径
const
char
*
target_file_name
=
NULL
;
// 目标文件路径
const
char
*
target_file_name
=
NULL
;
// 目标文件路径
const
char
*
list_file_name
=
NULL
;
// 列表文件路径
const
char
*
list_file_name
=
NULL
;
// 列表文件路径
const
char
*
dbg_file_name
=
NULL
;
// 调试信息文件路径
const
char
*
dbg_file_name
=
NULL
;
// 调试信息文件路径
const
unsigned
long
dbg_file_magic
=
58
;
const
unsigned
long
dbg_file_magic
=
58
;
const
unsigned
long
dbg_file_version
=
1
;
const
unsigned
long
dbg_file_version
=
1
;
// 输出汇编过程中发现的语法错误信息
// 输出汇编过程中发现的语法错误信息
void
error_msg
(
const
char
*
error_msg
,
int
line_num
)
void
error_msg
(
const
char
*
error_msg
,
int
line_num
)
{
{
if
(
line_num
>=
1
)
if
(
line_num
>=
1
)
{
{
printf
(
"%s:%d: error: %s
\n
"
,
micro_file_name
,
line_num
,
error_msg
);
printf
(
"%s:%d: error: %s
\n
"
,
micro_file_name
,
line_num
,
error_msg
);
}
}
else
else
{
{
printf
(
"%s: error: %s
\n
"
,
micro_file_name
,
error_msg
);
printf
(
"%s: error: %s
\n
"
,
micro_file_name
,
error_msg
);
}
}
exit
(
1
);
exit
(
1
);
}
}
char
formated_msg
[
1024
];
// 将格式化后的错误信息放在此字符串中。
char
formated_msg
[
1024
];
// 将格式化后的错误信息放在此字符串中。
void
error_msg_miss_op
(
const
char
*
instruction_name
,
int
line_num
)
void
error_msg_miss_op
(
const
char
*
instruction_name
,
int
line_num
)
{
{
sprintf
(
formated_msg
,
"%s 指令缺少操作数。"
,
instruction_name
);
sprintf
(
formated_msg
,
"%s 指令缺少操作数。"
,
instruction_name
);
error_msg
(
formated_msg
,
line_num
);
error_msg
(
formated_msg
,
line_num
);
}
}
void
error_msg_wrong_op
(
const
char
*
instruction_name
,
int
line_num
)
void
error_msg_wrong_op
(
const
char
*
instruction_name
,
int
line_num
)
{
{
sprintf
(
formated_msg
,
"%s 指令不支持这样的操作数。"
,
instruction_name
);
sprintf
(
formated_msg
,
"%s 指令不支持这样的操作数。"
,
instruction_name
);
error_msg
(
formated_msg
,
line_num
);
error_msg
(
formated_msg
,
line_num
);
}
}
// 定义关键字和解析函数的对应关系
// 定义关键字和解析函数的对应关系
typedef
void
(
*
PARSE_FUNCTION
)(
int
line_num
);
typedef
void
(
*
PARSE_FUNCTION
)(
int
line_num
);
struct
KEYWORD_FUNCTION_ENTRY
struct
KEYWORD_FUNCTION_ENTRY
{
{
const
char
**
keyword
;
const
char
**
keyword
;
PARSE_FUNCTION
parse_function
;
PARSE_FUNCTION
parse_function
;
};
};
// 指令名称
// 指令名称
const
char
*
dup_instruction_keyword
=
"dup"
;
const
char
*
dup_instruction_keyword
=
"dup"
;
const
char
*
null_instruction_keyword
=
"null"
;
const
char
*
null_instruction_keyword
=
"null"
;
const
char
*
path_instruction_keyword
=
"path"
;
const
char
*
path_instruction_keyword
=
"path"
;
const
char
*
inc_instruction_keyword
=
"inc"
;
// pc+1
const
char
*
inc_instruction_keyword
=
"inc"
;
// pc+1
const
char
*
reset_instruction_keyword
=
"reset"
;
// 复位
const
char
*
reset_instruction_keyword
=
"reset"
;
// 复位
const
char
*
ask_for_int_instruction_keyword
=
"ask_for_int"
;
//查询硬中断
const
char
*
ask_for_int_instruction_keyword
=
"ask_for_int"
;
//查询硬中断
const
char
*
inta1_instruction_keyword
=
"inta1"
;
//第一个中断应答信号
const
char
*
inta1_instruction_keyword
=
"inta1"
;
//第一个中断应答信号
const
char
*
inta2_instruction_keyword
=
"inta2"
;
//第二个中断应答信号
const
char
*
inta2_instruction_keyword
=
"inta2"
;
//第二个中断应答信号
const
char
*
eoi_instruction_keyword
=
"eoi"
;
//中断返回
const
char
*
eoi_instruction_keyword
=
"eoi"
;
//中断返回
// 判断是否是立即数。不支持负数。
// 判断是否是立即数。不支持负数。
int
is_immediate
(
const
char
*
token
)
int
is_immediate
(
const
char
*
token
)
{
{
return
isdigit
(
token
[
0
]);
return
isdigit
(
token
[
0
]);
}
}
// 根据立即数得到值。不支持负数。
// 根据立即数得到值。不支持负数。
unsigned
long
get_value_from_immediate
(
const
char
*
immediate
)
unsigned
long
get_value_from_immediate
(
const
char
*
immediate
)
{
{
char
*
end
;
char
*
end
;
int
base
=
(
immediate
[
0
]
==
'0'
&&
(
immediate
[
1
]
==
'x'
||
immediate
[
1
]
==
'X'
))
?
16
:
10
;
int
base
=
(
immediate
[
0
]
==
'0'
&&
(
immediate
[
1
]
==
'x'
||
immediate
[
1
]
==
'X'
))
?
16
:
10
;
return
strtoul
(
immediate
,
&
end
,
base
);
return
strtoul
(
immediate
,
&
end
,
base
);
}
}
// dup n, null
// dup n, null
void
parse_dup
(
int
line_num
)
void
parse_dup
(
int
line_num
)
{
{
char
*
op1
,
*
op2
;
char
*
op1
,
*
op2
;
int
i
;
int
i
;
unsigned
long
micro_instruction_count
;
// 微指令个数
unsigned
long
micro_instruction_count
;
// 微指令个数
unsigned
long
micro_code
;
// 微指令编码
unsigned
long
micro_code
;
// 微指令编码
op1
=
strtok
(
NULL
,
delimit_char_comma
);
op1
=
strtok
(
NULL
,
delimit_char_comma
);
op2
=
strtok
(
NULL
,
delimit_char
);
op2
=
strtok
(
NULL
,
delimit_char
);
if
(
NULL
==
op1
||
NULL
==
op2
)
if
(
NULL
==
op1
||
NULL
==
op2
)
{
{
error_msg_miss_op
(
dup_instruction_keyword
,
line_num
);
error_msg_miss_op
(
dup_instruction_keyword
,
line_num
);
}
}
// dup微指令的第一个操作数必须是立即数(十进制或十六进制)
// dup微指令的第一个操作数必须是立即数(十进制或十六进制)
if
(
!
is_immediate
(
op1
))
if
(
!
is_immediate
(
op1
))
{
{
error_msg_wrong_op
(
dup_instruction_keyword
,
line_num
);
error_msg_wrong_op
(
dup_instruction_keyword
,
line_num
);
}
}
// 得到微指令个数
// 得到微指令个数
micro_instruction_count
=
get_value_from_immediate
(
op1
);
micro_instruction_count
=
get_value_from_immediate
(
op1
);
// 解析第二个操作数
// 解析第二个操作数
if
(
is_immediate
(
op2
))
if
(
is_immediate
(
op2
))
{
{
micro_code
=
get_value_from_immediate
(
op2
);
micro_code
=
get_value_from_immediate
(
op2
);
}
}
else
if
(
0
==
stricmp
(
op2
,
null_instruction_keyword
))
else
if
(
0
==
stricmp
(
op2
,
null_instruction_keyword
))
{
{
micro_code
=
0xffffffff
;
micro_code
=
0xffffffff
;
}
}
else
else
{
{
error_msg_wrong_op
(
dup_instruction_keyword
,
line_num
);
error_msg_wrong_op
(
dup_instruction_keyword
,
line_num
);
}
}
for
(
i
=
0
;
i
<
(
int
)
micro_instruction_count
;
i
++
)
for
(
i
=
0
;
i
<
(
int
)
micro_instruction_count
;
i
++
)
{
{
memcpy
(
&
machine_code
[
machine_code_address
],
&
micro_code
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
micro_code
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
}
}
// null
// null
void
parse_null
(
int
line_num
)
void
parse_null
(
int
line_num
)
{
{
unsigned
long
ul
=
0xffffffff
;
unsigned
long
ul
=
0xffffffff
;
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
// ask_for_int
// ask_for_int
void
parse_ask_for_int
(
int
line_num
)
void
parse_ask_for_int
(
int
line_num
)
{
{
unsigned
long
ul
=
0xffffffaf
;
unsigned
long
ul
=
0xffffffaf
;
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
// inta1
// inta1
void
parse_inta1
(
int
line_num
)
void
parse_inta1
(
int
line_num
)
{
{
unsigned
long
ul
=
0xfffbffef
;
unsigned
long
ul
=
0xfffbffef
;
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
// inta2
// inta2
void
parse_inta2
(
int
line_num
)
void
parse_inta2
(
int
line_num
)
{
{
unsigned
long
ul
=
0xfffcffeb
;
unsigned
long
ul
=
0xfffcffeb
;
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
// eoi
// eoi
void
parse_eoi
(
int
line_num
)
void
parse_eoi
(
int
line_num
)
{
{
unsigned
long
ul
=
0xfffdffef
;
unsigned
long
ul
=
0xfffdffef
;
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
ul
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
// path op1, op2
// path op1, op2
void
parse_path
(
int
line_num
)
void
parse_path
(
int
line_num
)
{
{
char
*
op1
,
*
op2
;
char
*
op1
,
*
op2
;
int
index
;
int
index
;
op1
=
strtok
(
NULL
,
delimit_char_comma
);
op1
=
strtok
(
NULL
,
delimit_char_comma
);
op2
=
strtok
(
NULL
,
delimit_char
);
op2
=
strtok
(
NULL
,
delimit_char
);
if
(
NULL
==
op1
||
NULL
==
op2
)
if
(
NULL
==
op1
||
NULL
==
op2
)
{
{
error_msg_miss_op
(
path_instruction_keyword
,
line_num
);
error_msg_miss_op
(
path_instruction_keyword
,
line_num
);
}
}
index
=
match_ops
(
op1
,
op2
);
index
=
match_ops
(
op1
,
op2
);
if
(
0
==
index
)
if
(
0
==
index
)
{
{
error_msg_wrong_op
(
path_instruction_keyword
,
line_num
);
error_msg_wrong_op
(
path_instruction_keyword
,
line_num
);
}
}
memcpy
(
&
machine_code
[
machine_code_address
],
&
path_operand_table
[
index
].
micro_machine_code
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
path_operand_table
[
index
].
micro_machine_code
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
//
//
// 在代码行数据库中,标记此行是一个指令行
// 在代码行数据库中,标记此行是一个指令行
//
//
line_database
[
line_count
].
flag
|=
LF_INSTRUCTION
;
line_database
[
line_count
].
flag
|=
LF_INSTRUCTION
;
}
}
// inc
// inc
void
parse_inc
(
int
line_num
)
void
parse_inc
(
int
line_num
)
{
{
char
*
op
;
char
*
op
;
int
index
;
int
index
;
op
=
strtok
(
NULL
,
delimit_char_comma
);
op
=
strtok
(
NULL
,
delimit_char_comma
);
if
(
NULL
==
op
)
if
(
NULL
==
op
)
{
{
error_msg_miss_op
(
inc_instruction_keyword
,
line_num
);
error_msg_miss_op
(
inc_instruction_keyword
,
line_num
);
}
}
index
=
match_one_operand
(
op
);
index
=
match_one_operand
(
op
);
if
(
0
==
index
)
if
(
0
==
index
)
{
{
error_msg_wrong_op
(
inc_instruction_keyword
,
line_num
);
error_msg_wrong_op
(
inc_instruction_keyword
,
line_num
);
}
}
memcpy
(
&
machine_code
[
machine_code_address
],
&
one_operand_table
[
index
].
micro_machine_code
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
one_operand_table
[
index
].
micro_machine_code
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
//
//
// 在代码行数据库中,标记此行是一个指令行
// 在代码行数据库中,标记此行是一个指令行
//
//
line_database
[
line_count
].
flag
|=
LF_INSTRUCTION
;
line_database
[
line_count
].
flag
|=
LF_INSTRUCTION
;
}
}
// reset
// reset
void
parse_reset
(
int
line_num
)
void
parse_reset
(
int
line_num
)
{
{
char
*
op
;
char
*
op
;
int
index
;
int
index
;
op
=
strtok
(
NULL
,
delimit_char_comma
);
op
=
strtok
(
NULL
,
delimit_char_comma
);
if
(
NULL
==
op
)
if
(
NULL
==
op
)
{
{
error_msg_miss_op
(
reset_instruction_keyword
,
line_num
);
error_msg_miss_op
(
reset_instruction_keyword
,
line_num
);
}
}
index
=
match_one_operand
(
op
);
index
=
match_one_operand
(
op
);
if
(
0
==
index
)
if
(
0
==
index
)
{
{
error_msg_wrong_op
(
reset_instruction_keyword
,
line_num
);
error_msg_wrong_op
(
reset_instruction_keyword
,
line_num
);
}
}
memcpy
(
&
machine_code
[
machine_code_address
],
&
one_operand_table
[
index
].
micro_machine_code
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
one_operand_table
[
index
].
micro_machine_code
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
//
//
// 在代码行数据库中,标记此行是一个指令行
// 在代码行数据库中,标记此行是一个指令行
//
//
line_database
[
line_count
].
flag
|=
LF_INSTRUCTION
;
line_database
[
line_count
].
flag
|=
LF_INSTRUCTION
;
}
}
//
//
// 必须将关键字及其解析函数放在下面的表中。从而可以使用“表驱动”的编程模式。
// 必须将关键字及其解析函数放在下面的表中。从而可以使用“表驱动”的编程模式。
//
//
struct
KEYWORD_FUNCTION_ENTRY
keyword_function_table
[]
=
struct
KEYWORD_FUNCTION_ENTRY
keyword_function_table
[]
=
{
{
{
NULL
,
NULL
}
// 未用
{
NULL
,
NULL
}
// 未用
,{
&
dup_instruction_keyword
,
parse_dup
}
,{
&
dup_instruction_keyword
,
parse_dup
}
,{
&
null_instruction_keyword
,
parse_null
}
,{
&
null_instruction_keyword
,
parse_null
}
,{
&
path_instruction_keyword
,
parse_path
}
,{
&
path_instruction_keyword
,
parse_path
}
,{
&
inc_instruction_keyword
,
parse_inc
}
,{
&
inc_instruction_keyword
,
parse_inc
}
,{
&
reset_instruction_keyword
,
parse_reset
}
,{
&
reset_instruction_keyword
,
parse_reset
}
,{
&
ask_for_int_instruction_keyword
,
parse_ask_for_int
}
,{
&
ask_for_int_instruction_keyword
,
parse_ask_for_int
}
,{
&
inta1_instruction_keyword
,
parse_inta1
}
,{
&
inta1_instruction_keyword
,
parse_inta1
}
,{
&
inta2_instruction_keyword
,
parse_inta2
}
,{
&
inta2_instruction_keyword
,
parse_inta2
}
,{
&
eoi_instruction_keyword
,
parse_eoi
}
,{
&
eoi_instruction_keyword
,
parse_eoi
}
};
};
// 判断是否是一个关键字。返回0,不是关键字;返回非0,是关键字,并且返回值就是关键字在表中的下标。
// 判断是否是一个关键字。返回0,不是关键字;返回非0,是关键字,并且返回值就是关键字在表中的下标。
int
match_keyword
(
const
char
*
token
)
int
match_keyword
(
const
char
*
token
)
{
{
int
i
;
int
i
;
for
(
i
=
1
;
i
<
sizeof
(
keyword_function_table
)
/
sizeof
(
keyword_function_table
[
0
]);
i
++
)
for
(
i
=
1
;
i
<
sizeof
(
keyword_function_table
)
/
sizeof
(
keyword_function_table
[
0
]);
i
++
)
{
{
if
(
stricmp
(
token
,
*
keyword_function_table
[
i
].
keyword
)
==
0
)
if
(
stricmp
(
token
,
*
keyword_function_table
[
i
].
keyword
)
==
0
)
{
{
return
i
;
return
i
;
}
}
}
}
return
0
;
return
0
;
}
}
// 输出版本信息
// 输出版本信息
void
version_msg
()
void
version_msg
()
{
{
printf
(
printf
(
"Engintime DM1000 8位模型机微指令汇编器 [版本 2.0]
\n
"
"Engintime DM1000 8位模型机微指令汇编器 [版本 2.0]
\n
"
"版权所有 (c) 2008-2018 北京英真时代科技有限公司。保留所有权利。
\n
"
"版权所有 (c) 2008-2018 北京英真时代科技有限公司。保留所有权利。
\n
"
);
);
}
}
// 输出帮助信息
// 输出帮助信息
void
help_msg
()
void
help_msg
()
{
{
printf
(
printf
(
"Engintime DM1000 8位模型机微指令汇编器。
\n\n
"
"Engintime DM1000 8位模型机微指令汇编器。
\n\n
"
"用法:
\n\n
"
"用法:
\n\n
"
" microasm.exe micro_file_name [options]
\n\n
"
" microasm.exe micro_file_name [options]
\n\n
"
"选项:
\n\n
"
"选项:
\n\n
"
" -g debug_file_name
\t
指定生成的调试信息文件路径。
\n
"
" -g debug_file_name
\t
指定生成的调试信息文件路径。
\n
"
" -h
\t\t\t
打印此帮助信息。
\n
"
" -h
\t\t\t
打印此帮助信息。
\n
"
" -l list_file_name
\t
指定生成的列表文件路径。
\n
"
" -l list_file_name
\t
指定生成的列表文件路径。
\n
"
" -o target_file_name
\t
指定生成的目标文件路径。若未指定,默认生成 micro.obj 文件。
\n
"
" -o target_file_name
\t
指定生成的目标文件路径。若未指定,默认生成 micro.obj 文件。
\n
"
" -v
\t\t\t
打印版本信息。
\n
"
" -v
\t\t\t
打印版本信息。
\n
"
);
);
printf
(
"
\n
"
);
printf
(
"
\n
"
);
version_msg
();
version_msg
();
exit
(
1
);
exit
(
1
);
}
}
void
argument_error_msg
()
void
argument_error_msg
()
{
{
printf
(
"命令行参数错误。
\n\n
"
);
printf
(
"命令行参数错误。
\n\n
"
);
help_msg
();
help_msg
();
}
}
// 处理器用户输入的命令行参数
// 处理器用户输入的命令行参数
void
process_argument
(
int
argc
,
char
*
argv
[])
void
process_argument
(
int
argc
,
char
*
argv
[])
{
{
int
i
;
int
i
;
// argv[0] 是 "easm.exe",所以可以忽略。
// argv[0] 是 "easm.exe",所以可以忽略。
for
(
i
=
1
;
i
<
argc
;
i
++
)
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
{
if
(
strcmp
(
argv
[
i
],
"-v"
)
==
0
)
if
(
strcmp
(
argv
[
i
],
"-v"
)
==
0
)
{
{
version_msg
();
version_msg
();
exit
(
1
);
exit
(
1
);
}
}
else
if
(
strcmp
(
argv
[
i
],
"-h"
)
==
0
)
else
if
(
strcmp
(
argv
[
i
],
"-h"
)
==
0
)
{
{
help_msg
();
help_msg
();
}
}
else
if
(
strcmp
(
argv
[
i
],
"-o"
)
==
0
)
else
if
(
strcmp
(
argv
[
i
],
"-o"
)
==
0
)
{
{
if
(
i
+
1
<
argc
)
if
(
i
+
1
<
argc
)
{
{
i
++
;
i
++
;
target_file_name
=
argv
[
i
];
target_file_name
=
argv
[
i
];
}
}
else
else
{
{
argument_error_msg
();
argument_error_msg
();
}
}
}
}
else
if
(
strcmp
(
argv
[
i
],
"-l"
)
==
0
)
else
if
(
strcmp
(
argv
[
i
],
"-l"
)
==
0
)
{
{
if
(
i
+
1
<
argc
)
if
(
i
+
1
<
argc
)
{
{
i
++
;
i
++
;
list_file_name
=
argv
[
i
];
list_file_name
=
argv
[
i
];
}
}
else
else
{
{
argument_error_msg
();
argument_error_msg
();
}
}
}
}
else
if
(
strcmp
(
argv
[
i
],
"-g"
)
==
0
)
else
if
(
strcmp
(
argv
[
i
],
"-g"
)
==
0
)
{
{
if
(
i
+
1
<
argc
)
if
(
i
+
1
<
argc
)
{
{
i
++
;
i
++
;
dbg_file_name
=
argv
[
i
];
dbg_file_name
=
argv
[
i
];
}
}
else
else
{
{
argument_error_msg
();
argument_error_msg
();
}
}
}
}
else
if
(
NULL
==
micro_file_name
&&
argv
[
i
][
0
]
!=
'-'
)
else
if
(
NULL
==
micro_file_name
&&
argv
[
i
][
0
]
!=
'-'
)
{
{
// 输入的汇编源代码文件路径。
// 输入的汇编源代码文件路径。
micro_file_name
=
argv
[
i
];
micro_file_name
=
argv
[
i
];
}
}
else
else
{
{
argument_error_msg
();
argument_error_msg
();
}
}
}
}
//
//
// 如果命令行参数中没有指定输入的汇编文件,就打印错误信息后退出
// 如果命令行参数中没有指定输入的汇编文件,就打印错误信息后退出
//
//
if
(
NULL
==
micro_file_name
)
if
(
NULL
==
micro_file_name
)
{
{
printf
(
"命令行参数错误。没有指定微指令源代码文件的路径。
\n
"
);
printf
(
"命令行参数错误。没有指定微指令源代码文件的路径。
\n
"
);
help_msg
();
help_msg
();
}
}
}
}
// 将一个字符串写入二进制文件中。先将字符串长度写入文件,然后将字符串中的
// 将一个字符串写入二进制文件中。先将字符串长度写入文件,然后将字符串中的
// 每个字符依次写入文件,不包括字符串末尾的 0.
// 每个字符依次写入文件,不包括字符串末尾的 0.
void
write_string_to_binary_file
(
const
char
*
str
,
FILE
*
fp
)
void
write_string_to_binary_file
(
const
char
*
str
,
FILE
*
fp
)
{
{
int
str_length
;
int
str_length
;
if
(
str
!=
NULL
)
if
(
str
!=
NULL
)
{
{
str_length
=
strlen
(
str
);
str_length
=
strlen
(
str
);
fwrite
(
&
str_length
,
1
,
sizeof
(
str_length
),
fp
);
fwrite
(
&
str_length
,
1
,
sizeof
(
str_length
),
fp
);
fwrite
(
str
,
1
,
str_length
,
fp
);
fwrite
(
str
,
1
,
str_length
,
fp
);
}
}
else
else
{
{
str_length
=
0
;
str_length
=
0
;
fwrite
(
&
str_length
,
1
,
sizeof
(
str_length
),
fp
);
fwrite
(
&
str_length
,
1
,
sizeof
(
str_length
),
fp
);
}
}
}
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
FILE
*
fp
;
FILE
*
fp
;
char
*
token
;
char
*
token
;
char
line
[
MAX_LINE_LENGTH
];
char
line
[
MAX_LINE_LENGTH
];
int
i
,
j
;
int
i
,
j
;
int
line_num
=
1
;
// 行号从第一行开始计数
int
line_num
=
1
;
// 行号从第一行开始计数
int
keyword_index
;
int
keyword_index
;
unsigned
long
micro_code
;
unsigned
long
micro_code
;
//
//
// 处理命令行参数
// 处理命令行参数
//
//
process_argument
(
argc
,
argv
);
process_argument
(
argc
,
argv
);
//
//
// 打开汇编源代码文件
// 打开汇编源代码文件
//
//
fp
=
fopen
(
micro_file_name
,
"r"
);
fp
=
fopen
(
micro_file_name
,
"r"
);
if
(
NULL
==
fp
)
if
(
NULL
==
fp
)
{
{
printf
(
"无法打开微指令源代码文件 %s
\n
"
,
micro_file_name
);
printf
(
"无法打开微指令源代码文件 %s
\n
"
,
micro_file_name
);
return
1
;
return
1
;
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//// 扫描
//// 扫描
version_msg
();
version_msg
();
printf
(
"
\n
正在汇编 %s...
\n
"
,
micro_file_name
);
printf
(
"
\n
正在汇编 %s...
\n
"
,
micro_file_name
);
//
//
// 一次读取一行文本,同时记录所有的代码行信息
// 一次读取一行文本,同时记录所有的代码行信息
//
//
while
(
fgets
(
line
,
sizeof
(
line
),
fp
)
!=
NULL
)
while
(
fgets
(
line
,
sizeof
(
line
),
fp
)
!=
NULL
)
{
{
//
//
// 将一行代码的信息记录到代码行数据库中
// 将一行代码的信息记录到代码行数据库中
//
//
strcpy
(
line_database
[
line_count
].
line_string
,
line
);
strcpy
(
line_database
[
line_count
].
line_string
,
line
);
line_database
[
line_count
].
line_num
=
line_num
;
line_database
[
line_count
].
line_num
=
line_num
;
line_database
[
line_count
].
address
=
machine_code_address
;
line_database
[
line_count
].
address
=
machine_code_address
;
//
//
// 将代码行中的注释剥离
// 将代码行中的注释剥离
//
//
line
[
strcspn
(
line
,
";"
)]
=
0
;
line
[
strcspn
(
line
,
";"
)]
=
0
;
//
//
// 开始解析代码行
// 开始解析代码行
//
//
token
=
strtok
(
line
,
delimit_char
);
token
=
strtok
(
line
,
delimit_char
);
if
(
NULL
==
token
)
if
(
NULL
==
token
)
{
{
// 如果是空行,不做任何处理
// 如果是空行,不做任何处理
}
}
else
if
((
keyword_index
=
match_keyword
(
token
))
!=
0
)
else
if
((
keyword_index
=
match_keyword
(
token
))
!=
0
)
{
{
// 根据关键字进行相应的处理
// 根据关键字进行相应的处理
keyword_function_table
[
keyword_index
].
parse_function
(
line_num
);
keyword_function_table
[
keyword_index
].
parse_function
(
line_num
);
}
}
else
if
(
is_immediate
(
token
))
else
if
(
is_immediate
(
token
))
{
{
// 将立即数直接作为微指令
// 将立即数直接作为微指令
micro_code
=
get_value_from_immediate
(
token
);
micro_code
=
get_value_from_immediate
(
token
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
micro_code
,
4
);
memcpy
(
&
machine_code
[
machine_code_address
],
&
micro_code
,
4
);
machine_code_address
+=
4
;
machine_code_address
+=
4
;
}
}
else
else
{
{
error_msg
(
"无法识别的代码行。"
,
line_num
);
error_msg
(
"无法识别的代码行。"
,
line_num
);
}
}
//
//
// 补充代码行数据库信息
// 补充代码行数据库信息
//
//
line_database
[
line_count
].
machine_code_count
=
machine_code_address
-
machine_code_old_address
;
line_database
[
line_count
].
machine_code_count
=
machine_code_address
-
machine_code_old_address
;
machine_code_old_address
=
machine_code_address
;
machine_code_old_address
=
machine_code_address
;
//
//
// 记录产生了机器码的代码行数量
// 记录产生了机器码的代码行数量
//
//
if
(
line_database
[
line_count
].
machine_code_count
!=
0
)
if
(
line_database
[
line_count
].
machine_code_count
!=
0
)
{
{
machine_code_line_count
++
;
machine_code_line_count
++
;
}
}
//
//
// 增加行号
// 增加行号
//
//
line_count
++
;
line_count
++
;
line_num
++
;
line_num
++
;
if
(
line_count
==
MAX_LINE_COUNT
)
if
(
line_count
==
MAX_LINE_COUNT
)
{
{
sprintf
(
formated_msg
,
"微指令文件中的代码行过多,最多只能有 %d 行代码。"
,
MAX_LINE_COUNT
);
sprintf
(
formated_msg
,
"微指令文件中的代码行过多,最多只能有 %d 行代码。"
,
MAX_LINE_COUNT
);
error_msg
(
formated_msg
,
-
1
);
error_msg
(
formated_msg
,
-
1
);
}
}
}
}
fclose
(
fp
);
fclose
(
fp
);
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//// 产生各种输出文件
//// 产生各种输出文件
//
//
// 将机器码写入二进制文件
// 将机器码写入二进制文件
//
//
if
(
NULL
==
target_file_name
)
if
(
NULL
==
target_file_name
)
{
{
target_file_name
=
"micro.obj"
;
target_file_name
=
"micro.obj"
;
}
}
fp
=
fopen
(
target_file_name
,
"wb"
);
fp
=
fopen
(
target_file_name
,
"wb"
);
if
(
NULL
==
fp
)
if
(
NULL
==
fp
)
{
{
printf
(
"无法打开目标文件 %s
\n
"
,
target_file_name
);
printf
(
"无法打开目标文件 %s
\n
"
,
target_file_name
);
return
1
;
return
1
;
}
}
fwrite
(
machine_code
,
1
,
machine_code_address
,
fp
);
fwrite
(
machine_code
,
1
,
machine_code_address
,
fp
);
fclose
(
fp
);
fclose
(
fp
);
printf
(
"
\n
生成目标文件 %s
\n
"
,
target_file_name
);
printf
(
"
\n
生成目标文件 %s
\n
"
,
target_file_name
);
//
//
// 将代码行数据库中的信息写入列表文件
// 将代码行数据库中的信息写入列表文件
//
//
if
(
list_file_name
!=
NULL
)
if
(
list_file_name
!=
NULL
)
{
{
fp
=
fopen
(
list_file_name
,
"w"
);
fp
=
fopen
(
list_file_name
,
"w"
);
if
(
NULL
==
fp
)
if
(
NULL
==
fp
)
{
{
printf
(
"无法打开列表文件 %s
\n
"
,
list_file_name
);
printf
(
"无法打开列表文件 %s
\n
"
,
list_file_name
);
return
1
;
return
1
;
}
}
for
(
i
=
0
;
i
<
line_count
;
i
++
)
for
(
i
=
0
;
i
<
line_count
;
i
++
)
{
{
// 行号
// 行号
fprintf
(
fp
,
"%04d "
,
line_database
[
i
].
line_num
);
fprintf
(
fp
,
"%04d "
,
line_database
[
i
].
line_num
);
// 地址和机器码
// 地址和机器码
if
(
line_database
[
i
].
machine_code_count
>
0
)
if
(
line_database
[
i
].
machine_code_count
>
0
)
{
{
fprintf
(
fp
,
"%02X "
,
line_database
[
i
].
address
);
fprintf
(
fp
,
"%02X "
,
line_database
[
i
].
address
);
for
(
j
=
0
;
j
<
4
;
j
++
)
for
(
j
=
0
;
j
<
4
;
j
++
)
{
{
fprintf
(
fp
,
"%02X "
,
machine_code
[
line_database
[
i
].
address
+
j
]);
fprintf
(
fp
,
"%02X "
,
machine_code
[
line_database
[
i
].
address
+
j
]);
}
}
fprintf
(
fp
,
" "
);
fprintf
(
fp
,
" "
);
}
}
else
else
{
{
fprintf
(
fp
,
" "
);
fprintf
(
fp
,
" "
);
}
}
// 源代码
// 源代码
fprintf
(
fp
,
line_database
[
i
].
line_string
);
fprintf
(
fp
,
line_database
[
i
].
line_string
);
}
}
fclose
(
fp
);
fclose
(
fp
);
printf
(
"生成列表文件 %s
\n
"
,
list_file_name
);
printf
(
"生成列表文件 %s
\n
"
,
list_file_name
);
}
}
//
//
// 将代码行数据库中的信息写入二进制的调试信息文件。
// 将代码行数据库中的信息写入二进制的调试信息文件。
//
//
// 调试信息的基本格式为:
// 调试信息的基本格式为:
// 魔数(4字节),固定不可改变
// 魔数(4字节),固定不可改变
// 版本号(4字节),固定不可改变
// 版本号(4字节),固定不可改变
// 源代码文件绝对路径字符串长度(4字节)
// 源代码文件绝对路径字符串长度(4字节)
// 源代码文件绝对路径字符串(不包括字符串结尾的0)
// 源代码文件绝对路径字符串(不包括字符串结尾的0)
// 列表文件绝对路径字符串长度(4字节)
// 列表文件绝对路径字符串长度(4字节)
// 列表文件绝对路径字符串(不包括字符串结尾的0)
// 列表文件绝对路径字符串(不包括字符串结尾的0)
//
//
// 代码行数据库中元素的数量(4字节)
// 代码行数据库中元素的数量(4字节)
// 代码行数据库中的所有元素
// 代码行数据库中的所有元素
//
//
// 符号表元素的数量(4字节)
// 符号表元素的数量(4字节)
// 符号表中的所有元素
// 符号表中的所有元素
//
//
if
(
dbg_file_name
!=
NULL
)
if
(
dbg_file_name
!=
NULL
)
{
{
fp
=
fopen
(
dbg_file_name
,
"wb"
);
fp
=
fopen
(
dbg_file_name
,
"wb"
);
if
(
NULL
==
fp
)
if
(
NULL
==
fp
)
{
{
printf
(
"无法打开调试信息文件 %s
\n
"
,
dbg_file_name
);
printf
(
"无法打开调试信息文件 %s
\n
"
,
dbg_file_name
);
return
1
;
return
1
;
}
}
// 魔数
// 魔数
fwrite
(
&
dbg_file_magic
,
1
,
sizeof
(
dbg_file_magic
),
fp
);
fwrite
(
&
dbg_file_magic
,
1
,
sizeof
(
dbg_file_magic
),
fp
);
// 版本号
// 版本号
fwrite
(
&
dbg_file_version
,
1
,
sizeof
(
dbg_file_version
),
fp
);
fwrite
(
&
dbg_file_version
,
1
,
sizeof
(
dbg_file_version
),
fp
);
// 源代码文件路径
// 源代码文件路径
write_string_to_binary_file
(
micro_file_name
,
fp
);
write_string_to_binary_file
(
micro_file_name
,
fp
);
// 列表文件路径
// 列表文件路径
write_string_to_binary_file
(
list_file_name
,
fp
);
write_string_to_binary_file
(
list_file_name
,
fp
);
// 代码行数据库中的所有元素
// 代码行数据库中的所有元素
fwrite
(
&
machine_code_line_count
,
1
,
sizeof
(
machine_code_line_count
),
fp
);
fwrite
(
&
machine_code_line_count
,
1
,
sizeof
(
machine_code_line_count
),
fp
);
for
(
i
=
0
;
i
<
line_count
;
i
++
)
for
(
i
=
0
;
i
<
line_count
;
i
++
)
{
{
// 跳过没有产生机器码的代码行
// 跳过没有产生机器码的代码行
if
(
0
==
line_database
[
i
].
machine_code_count
)
if
(
0
==
line_database
[
i
].
machine_code_count
)
{
{
continue
;
continue
;
}
}
fwrite
(
&
line_database
[
i
].
line_num
,
1
,
sizeof
(
unsigned
long
),
fp
);
fwrite
(
&
line_database
[
i
].
line_num
,
1
,
sizeof
(
unsigned
long
),
fp
);
fwrite
(
&
line_database
[
i
].
address
,
1
,
sizeof
(
unsigned
long
),
fp
);
fwrite
(
&
line_database
[
i
].
address
,
1
,
sizeof
(
unsigned
long
),
fp
);
fwrite
(
&
line_database
[
i
].
machine_code_count
,
1
,
sizeof
(
int
),
fp
);
fwrite
(
&
line_database
[
i
].
machine_code_count
,
1
,
sizeof
(
int
),
fp
);
fwrite
(
&
line_database
[
i
].
flag
,
1
,
sizeof
(
unsigned
long
),
fp
);
fwrite
(
&
line_database
[
i
].
flag
,
1
,
sizeof
(
unsigned
long
),
fp
);
}
}
// 没有符号表。但是为了确保调试信息的格式能够被正确读取,必须写入符号表数量为 0
// 没有符号表。但是为了确保调试信息的格式能够被正确读取,必须写入符号表数量为 0
i
=
0
;
i
=
0
;
fwrite
(
&
i
,
1
,
sizeof
(
i
),
fp
);
fwrite
(
&
i
,
1
,
sizeof
(
i
),
fp
);
fclose
(
fp
);
fclose
(
fp
);
printf
(
"生成调试信息文件 %s
\n
"
,
dbg_file_name
);
printf
(
"生成调试信息文件 %s
\n
"
,
dbg_file_name
);
}
}
return
0
;
return
0
;
}
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论