脚本解释器
脚本解释器设计
1.概要说明
该解释器分为两个过程:脚本的编译和执行。
编译过程:运行于PC机环境下,负责对txt格式测试脚本进行解析,生成指令代码和数据文件。
执行过程:运行于嵌入式环境下,执行下载到嵌入式环境下的指令代码。指令代码在ROM下,数据文件在外部存储区。
2.设计说明
2.1 指令代码
1.) 格式
一条指令由10个字节组成。
行号 指令 属性 操作数一 操作数二 中间结果 2Byte-uint 1Byte-uchar 1Byte-uchar 2Byte-int 2Byte-int 2Byte-int
, 行号: 原txt脚本语句所在行号;
示范围0-65535 , 指令: 执行的指令标号;
高4位表示指令类型,低4位表示指令符。 , 操作数: 指令操作参数标号,该标号指向数据文件中变量的索引 , 属性: 高4位指令终止标识(0x00-未终止,0x01已终止),低4位表
示指令属性
, 中间结果: 用于存储(RAM)计算指令所得中间结果变量标号。
2.) 指令名
分类 标号 名称 说明
0x01 I_LT <
0x02 I_LE <=
0x03 I_GT >
0x04 I_GE >=
0x05 I_EQ ==
0x06 I_NE != 表达式计算 0x07 I_ADD +
0x08 I_DEC -
0x09 I_MUL *
0x0a I_DIV /
0x0b I_ASIGN =
0x0c I_NOT !
0x0d I_AND &&
0x0e I_OR || 指令跳转 0x10 I_GOTO
函数调用 0x20 I_API 命令 0x30 I_CMD
3()指令说明
指令类别 属性说明(低4位) 操作数一 操作数二 中间结果 表达式计算 0-整型计算 采用整型数表示该数 中间结果标号为:
1-字符串连接 据在数据文件中的标-1,-2,-3。表示
号 三个内存变量 指令跳转 3-4bit 00–无条件跳0 指令索引号 0
转
3-4bit 01–有条件跳条件值量的标号(一般指令索引号 0
转 为中间结果)
1-2bit 00-假值跳转
1-2bit 01-真值跳转
函数调用 - 函数标号 0 有 命令 - 该行卡命令标号 0 0(执行结果默认
存于系统变量)
4()中间结果
中间结果存放在内存中,供表达式计算存放中间计算结果,分配三个,循环使用。
5()指令数据结构
结构表示如下:
typedef struct Program
{
unsigned int line_no; // 原txt脚本行号
unsigned char token; // 指令值
unsigned char attri; //指令属性
int param_one; //操作数一
int param_two; //操作数二
int param_tmp; //中间结果
}Program;
2.2 数据文件
数据文件表。
由274个字节组成,格式表示如下:
标号 名称 属性 值 2Byte-uint 23Byte-uchar 1Byte-uchar 256Byte-uchar
, 标号:
索引,表示范围1-65535
, 名称:变量名称,其他类型为空
, 属性:高4位表示数据类型(0000-常量,0001-变量,0002-函数参数,0003
卡片命令串);
当数据类型为变量时,低4位表示值类型(0000-整型,0001-字符串) , 值: 数据内容
结构表示如下:
typedef struct DataElem {
unsigned int data_id; // 数据单元标识
unsigned char data_name[15]; // 数据单元名字
unsigned char data_attri; //属性
unsigned char data_value[256]; //值
}DATAELEM;
2.3 脚本解析规则及示例
1.) 脚本解析规则
a.脚本的解析按行顺序进行。
b.根据该行脚本语句类型执行相应的解析过程。
c.函数API调用作为单行指令,结果存于中间结果。
d.指令程序不含注释、空行及空指令行。
e.在函数表和卡命令表中,参数列表和报文串里所含的变量名解析为%n(1,2,3…),标号表示。
f.跳转指令中,[操作数二]为跳转目标,是指令程序语句行的索引。
g.指令里的中间结果,采用三个内存全局变量,标号分别为:-1,-2,-3;并循环使用。
h.卡片命令运行的结果和返回码(两个变量%resp 和%status),作为内存全局变量,标号分别设为-100,-99。
2.) 示例
原脚本如下:
1 ;生成RSA密钥对
2 80 46 00 00 04 00 04 00 03 3 reccmptxt 90 00
4
5 <--! do
6 <--! %data=@rand(128)
7 <--! %data1=@left(%data,1) 8 <--! until %data1<80
9 <--! %ydata=@strmidh(%resp,0,20) 10 <--! %jsdata=@hash(sha1,%data1) 11 <--! if %jsdata!=%ydata
12 stop
13 <--! Endif
14 <--! for %c=118;%c<128;%c=%c+1 15 <--! %strdata=@rand(%c)
16 <--! %clen=@strlen(%strdata) 17 80 86 00 04 %c %strdata
18 reccmptxt 67 00
19 <--! next
20 <--! %pin=12 34 56 78 12 34 56 78 21 writekey 00 10 01 01 00 11 0F 01 0F 33 %pin
经过编译后指令程序如下:
2 0x30 0x00 1 0 0 1
2 3 0x30 0x00 2 0 0 3 5 0x10 0x00 0 4 0 4 6 0x20 0x00 1 0 -1 5 6 0x0b 0x01 -1 0 1 6 7 0x20 0x00 2 0 -1 7 7 0x0b 0x01 -1 0 2 8 8 0x01 0x00 2 3 -1 9 8 0x10 0101 -1 5 0 10 9 0x20 0x00 3 0 -1 11 9 0x0b 0x01 -1 0 5 12 10 0x20 0x00 4 0 -1 13 10 0x0b 0x01 -1 0 6 14 11 0x06 0x01 5 6 -1 15 11 0x10 0100 -1 17 0 16 12 0x30 0x00 3 0 0 17 13 0x10 0x00 0 18 0 18 14 0x0b 0x01 7 0 8 19 14 0x10 0x00 0 22 0 20 14 0x07 0x00 8 9 -1 21 14 0x0b 0x00 -1 0 8 22 14 0x01 0x00 8 10 -2 23 14 0x10 0101 -2 31 0 24 15 0x20 0x00 5 0 -1 25 15 0x0b 0x01 -1 0 11 26 16 0x20 0x00 6 0 -1 27 16 0x0b 0x01 -1 0 12 28 17 0x30 0x00 4 0 0 29 18 0x30 0x00 5 0 0 30 19 0x10 0000 0 20 0 31 20 0x0b 0x01 13 0 14 32 21 0x30 0x00 6 0 0
常变量表:
标号 名称 属性 值
1 0x11 data
2 0x11 data1
3 0x01 80
4 0x11 resp
5 0x11 ydata
6 0x11 jsdata
7 0x01 118 8 0x10 i 9 0x01 1 10 0x01 128 11 0x11 strdata 12 0x11 ilen 13 0x01 12 34 56 78 12 34 56 78
14 0x11 pin
函数API表:
标号 名称 属性 参数列表 1 1 rand 128 2 1 left %1,1 3 1 strmidh %4,0,20 4 1 hash sha1,%2 5 1 rand %8 6 1 strlen %11
卡命令表:
标号 属性 卡命令名 报文串
1 0 - 80 46 00 00 04 00 04 00 03 2 1 reccmptxt 90 00
3 0 stop
80 86 00 04 %8 %11 4 0 -
67 00 5 1 reccmptxt
00 10 01 01 00 11 0F 01 0F 33 %14 6 1 writekey