-
Notifications
You must be signed in to change notification settings - Fork 0
/
栈机.c
295 lines (269 loc) · 7.47 KB
/
栈机.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/*
一个极小栈机只为编译实践
*/
#include <stdio.h>
#include <stdlib.h>
#include "hong.h"
枚举 操作类型{
操作停机,操作入,操作出,操作加,操作减,操作乘,操作除,
操作转储,
操作载入,操作存储,操作载入码,
操作跳小于,操作跳小等,
操作跳大于,操作跳大等,
操作跳等于,操作跳不等,
操作跳,
操作无效
};
类型定义 结构 指令{
整型 操作;
整型 实参;
}指令;
#define 代码大小 (1024)
#define 数据大小 (1024)
#define 栈大小 (256)
#define 弹错误 (0x7fffffff)
/*操作栈*/
整型 操作栈[栈大小];
整型 操作位置 = 0;
指令 指令内存[代码大小];
整型 程序计数;
整型 数据内存[数据大小];
枚举 错误码{
停机,可行,错误除由零,错误数据内存,错误指令内存,错误栈过流,错误栈空,
错误未知操作,
};
空 错误(常量 印刻 *错误){
fprintf(stderr, 错误);
}
/*取操作码实参(操作数)计数*/
整型 取操作数计数(整型 操作){
整型 返;
切换(操作){
情况 操作载入码:
情况 操作跳小于:
情况 操作跳小等:
情况 操作跳大于:
情况 操作跳大等:
情况 操作跳等于:
情况 操作跳不等:
情况 操作跳:
返 = 1;
断;
默认:
返 = 0;
}
返回 返;
}
//控制栈相关
整型 推操作栈(整型 指令){
若(操作位置 >= 栈大小){
错误("栈过流");
返回 -1;
}
操作栈[操作位置++] = 指令;
返回 0;
}
整型 弹操作栈(){
若(操作位置 == 0){
错误("栈空");
返回 弹错误;
}
返回 操作栈[--操作位置];
}
整型 顶部操作栈(){
若(操作位置 == 0){
错误("栈空");
返回 弹错误;
}
返回 操作栈[操作位置 - 1];
}
#define 增指针(文本) 代码 = 代码 + 求大小(文本); 大小 -= 求大小(文本)
/*读代码进到指令内存*/
整型 读指令(常量 印刻 *代码,整型 大小){
整型 操作计数,定位 = 0;
指令 操作码;
一会儿(大小 > 0 && 定位 < 代码大小){
/*操作是1字节在代码文件*/
操作码.操作 = *代码;
增指针(印刻);
操作计数 = 取操作数计数(操作码.操作);
若(操作计数 > 0){//有实参
操作码.实参 = *(整型*) 代码;
增指针(整型);
}否则{
操作码.实参 = 0;
}
指令内存[定位++] = 操作码;
}
返回 1;
}
整型 步骤跑(){
指令 *操作码 = &指令内存[程序计数++];
整型 返 = 可行;
切换(操作码 -> 操作){
情况 操作停机:{
返 = 停机;
}
断;
情况 操作入:{
整型 甲;
printf("输入:");
scanf("%d", &甲);
推操作栈(甲);
}
断;
情况 操作出:{
整型 甲 = 弹操作栈();
printf("输出:%d\n", 甲);
}
断;
情况 操作加:{
整型 子 = 弹操作栈();
整型 丑 = 弹操作栈();
推操作栈(丑 + 子);
}
断;
情况 操作减:{
整型 子 = 弹操作栈();
整型 丑 = 弹操作栈();
推操作栈(丑 - 子);
}
断;
情况 操作乘:{
整型 子 = 弹操作栈();
整型 丑 = 弹操作栈();
推操作栈(丑 * 子);
}
断;
情况 操作除:{
整型 子 = 弹操作栈();
整型 丑 = 弹操作栈();
若(子 == 0){
返回 错误除由零;
}
推操作栈(丑 / 子);
}
断;
情况 操作转储:{
推操作栈(顶部操作栈());
}
断;
情况 操作载入:{
整型 地址 = 弹操作栈();
若(地址 < 0 || 地址 >= 数据大小){
错误("数据内存访问错误");
返回 错误数据内存;
}否则{
推操作栈(数据内存[地址]);
}
}
断;
情况 操作存储:{
整型 值 = 弹操作栈();
整型 地址 = 弹操作栈();
若(地址 < 0 || 地址 >= 数据大小){
错误("数据内存访问错误");
返回 错误数据内存;
}否则{
数据内存[地址] = 值;
}
}
断;
情况 操作载入码:{
推操作栈(操作码 -> 实参);
}
断;
情况 操作跳小于:{
整型 甲 = 弹操作栈();
若(甲 < 0){
程序计数 = 操作码 -> 实参;
}
}
断;
情况 操作跳小等:{
整型 甲 = 弹操作栈();
若(甲 <= 0){
程序计数 = 操作码 -> 实参;
}
}
断;
情况 操作跳大于:{
整型 甲 = 弹操作栈();
若(甲 > 0){
程序计数 = 操作码 -> 实参;
}
}
断;
情况 操作跳大等:{
整型 甲 = 弹操作栈();
若(甲 >= 0){
程序计数 = 操作码 -> 实参;
}
}
断;
情况 操作跳等于:{
整型 甲 = 弹操作栈();
若(甲 == 0){
程序计数 = 操作码 -> 实参;
}
}
断;
情况 操作跳不等:{
整型 甲 = 弹操作栈();
若(甲 != 0){
程序计数 = 操作码 -> 实参;
}
}
断;
情况 操作跳:{
程序计数 = 操作码 -> 实参;
}
断;
默认 :
返 = 错误未知操作;
}
返回 返;
}
空 跑(){
整型 返 = 可行;
一会儿(返 == 可行){
返 = 步骤跑();
}
}
整型 文件大小(FILE *文件指针){
整型 大小;
fseek(文件指针, 0, SEEK_SET);
fseek(文件指针, 0, SEEK_END);
大小 = ftell(文件指针);
fseek(文件指针, 0, SEEK_SET);
返回 大小;
}
外部 空 反汇编出投掷(常量 印刻 *文件, 常量 指令 *操作码, 整型 大小);
整型 main(整型 实参计数, 印刻 **实参值){
FILE *文件指针;
印刻 *缓冲;
整型 大小;
若(实参计数 < 2){
错误("用法: 栈机 <文件名> ");
exit(-1);
}
文件指针 = fopen(实参值[1], "rb");
若(文件指针 == 0 ){
错误("打开文件失败");
exit(-1);
}
大小 = 文件大小(文件指针);
缓冲 = (印刻*) malloc(大小);
fread(缓冲, 大小, 1, 文件指针);
读指令(缓冲, 大小);
若(实参计数 > 2){
整型 数据旗 = atoi(实参值[2]);
若(数据旗){
反汇编出投掷(实参值[1], 指令内存, 代码大小);
}
}
跑();
free(缓冲);
fclose(文件指针);
返回 0;
}