汇编作业--电话簿

Catalogue
  1. 1. 汇编作业–电话簿
    1. 1.1. 实现基本功能
      1. 1.1.1. 数据结构
        1. 1.1.1.1. 字符串
        2. 1.1.1.2. 数组
        3. 1.1.1.3. 数据结构
    2. 1.2. 实现增加功能
      1. 1.2.1. 输入功能
      2. 1.2.2. 添加数据函数
    3. 1.3. 实现查询功能
    4. 1.4. 增加一个菜单功能
    5. 1.5. 实现修改/删除功能
    6. 1.6. 效果图
    7. 1.7. 完整代码
    8. 1.8. 遇到的问题及其解决方案
      1. 1.8.0.1. 0X01 找不到msvcrt.inv文件
  2. 1.9. 参考资料

汇编作业–电话簿

花了不少时间,不过总算完成这项作业了,虽然不是很完美,但也基本符合要求了,完成过程跟大家分享分享,

个人博客:https://kn0sky.com

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
**项目名称:**汇编语言电话本

**项目背景:**基于同学们学习汇编语言后没有练习的问题,特以该项目作为阶段性练习。

**项目目的:**熟悉汇编语言编程,练习编程逻辑,熟悉Win32 API调用模式

**项目要求:**编写一个具有增删改查功能的电话本,基于控制台。具体要求如下:

1. 基本功能:电话本具有姓名与电话号码两项属性,并且使用数据结构作为存储
2. 增加功能:插入姓名与电话号码到数据结构的最后。
3. 查询功能:输入姓名,以此作为依据,到数据结构中查找,将找到的信息打印到控制台。
4. 删除功能:输入姓名或电话号码,以此作为依据,到数据结构中查找,且删除该条信息。
5. 修改功能:输入姓名或电话号码,以此作为依据,到数据结构中查找,找到后打印信息,要求输入新的姓名或电话,接受后修改原有条目。


**编写指南:**

**1.****数组的编写方式**

TelephoneNumber dd 30 DUP(?)


**2.****结构体的编写方式**

Name STRUCT

具体成员信息

Name ENDS


**3.****控制台相关的API**

GetStdHandle 获得标准输入输出的窗口句柄

SetConsoleTextAttribute是设置控制台字体颜色和背景色

CONSOLE_CURSOR_INFO用于存放控制光标信息

SetConsoleCursorInfo设置光标的信息

GetConsoleScreenBufferInfo取得控制台屏幕信息

SetConsoleCursorPosition设置光标位置

WriteConsoleOutput直接写输入缓冲区

SetConsoleTitle设置控制台的标题

ReadConsole 读控制台

WriteConsole 写控制台

实现基本功能

首先,根据前面所学的知识不能够完成本项目,目前以本项目为最终目标,将目标分解成小目标逐个击破

第一步———-基本功能:电话本具有姓名与电话号码两项属性,并且使用数据结构作为存储

数据结构

首先要了解数据结构要怎么弄,我们的数据包括姓名和电话两部分,姓名是字符串,电话是数组,应该先弄清楚这两样东西怎么用

字符串

定义一个字符串并通过调用消息框输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.586
.model flat,stdcall
includelib user32.lib
includelib kernel32.lib
ExitProcess PROTO, dwExitCode:DWORD
MessageBoxA PROTO, hWnd:DWORD ,lpText:BYTE ,lpCaption:BYTE ,uType:DWORD

.data
name1 db "警告" ,0
name2 db "你菜爆了" ,0

.code
main proc
push 0
lea eax ,name1
push eax
lea eax ,name2
push eax
push 0
call MessageBoxA
add esp,16
call ExitProcess
main ENDP
END main

通过控制台输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.586
.model flat, stdcall

include msvcrt.inc
includelib msvcrt.lib

.data
szText db 'Hello World!', 0

.code
main proc
invoke crt_printf, addr szText;类似于call,但比call方便,可直接在后面跟参数
mov eax ,eax
main endp
end main

数组

定义一个数组赋值并输出到控制台:

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
.386
.model flat, stdcall

include msvcrt.inc
includelib msvcrt.lib

.data
;定义数组
user db 20 dup(0)
testext db "hello world!",0

.code
main proc
;给数组赋值
lea edi ,offset user
lea esi ,offset testext
mov ecx,20
rep movsb
;打印
push offset user
call crt_printf

mov eax ,eax

main endp
end main

数据结构

到这里我们已经会使用字符串和数组了,接下来了解一下如何使用数据结构作为存储。

示例:创建一个结构体,包含两项内容,插入值并输出

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
.386
.model flat, stdcall

include msvcrt.inc
includelib msvcrt.lib

.data
;定义结构体
Contact struct
user db 20 dup(0)
tel db 20 dup(0)
Contact ends

person1 Contact <>
person2 Contact <'john','12312312312'>

tsname db "Li Hua",0
tstel db "12312345678",0


.code
main proc
;给结构体数组赋值
lea edi ,offset person1.tel
lea esi ,offset tstel
mov ecx ,20
rep movsb

lea edi ,offset person1.user
lea esi ,offset tsname
mov ecx ,20
rep movsb

push offset person1.user
call crt_printf
add esp ,4

push offset person1.tel
call crt_printf
add esp ,4

mov eax ,eax

main endp
end main

到此,基本功能已经实现,下一步,实现增加功能

实现增加功能

增加功能:插入姓名与电话号码到数据结构的最后。

这里要解决两个问题

  1. 如何输入数据
  2. 如何将数据加到数据结构的最后

输入功能

输入一个字符数并输出:

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
.586
.model flat ,stdcall

include msvcrt.inc
includelib msvcrt.lib

.data
;输入格式
input_format_str db "%s",0

;存放输入的变量
inputstr db 0,0

.code
main proc
push offset inputstr
push offset input_format_str
call crt_scanf ;输入函数需要两个参数,一个是输入格式,一个用来保存输入的值
add esp,8

invoke crt_printf ,offset inputstr

mov eax ,eax
main endp
end main

添加数据函数

据此,我们可以用一个变量来计数,来计算数组最后一个位置的偏移量,通过上面的方法来实现添加数据。

初步完成添加数据功能函数:

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
.data
;结构体存储名字电话
Contact struct
user db 20 dup(0)
tel db 20 dup(0)
Contact ends

;定义一个结构体数组存储所有联系人
ContactList Contact 100 dup(<'0'>)

;定义一个临时结构用来传送数据
tmpContact Contact <'john','123123123123'>

;输入格式
input_format_str db "%s",0

;存放输入的变量
inputstr db 20 dup(0)

;现有数据数
count dd 1 dup(0)

;问候语
input_user_text db "请输入联系人姓名:",0
input_tel_text db "请输入联系人电话:",0


.code
addContact proc
;消息提示1:请输入联系人姓名
push offset input_user_text
call crt_printf
add esp,4

;输入
push offset inputstr
push offset input_format_str
call crt_scanf
add esp,8

;保存到临时用结构里
lea esi ,offset inputstr
lea edi ,offset tmpContact.user
mov ecx ,20
rep movsb

;----------------------------------------

;消息提示2:请输入联系人电话
push offset input_tel_text
call crt_printf
add esp,4

;输入
push offset inputstr
push offset input_format_str
call crt_scanf
add esp,8

;保存到临时用结构里
lea esi ,offset inputstr
lea edi ,offset tmpContact.tel
mov ecx ,20
rep movsb

;-----------------------------------------

;保存到数据结构的最后
lea esi ,offset tmpContact
lea edi ,offset ContactList

;计算偏移,并移动
mov eax ,sizeof(Contact)
mov ecx ,count
imul eax,ecx
add edi ,eax
mov ecx ,40
rep movsb

;总数+1
inc count

;返回
retn
addContact endp

实现查询功能

查询功能:输入姓名,以此作为依据,到数据结构中查找,将找到的信息打印到控制台。

这里思路就很简单了,我们把我们的联系人数组遍历一遍即可,ebx来接收要循环的次数,edx显示当前已循环的次数,如果到循环次数了,也就是遍历到联系人总数了,就结束循环跳出

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
searchContact proc
mov edx ,0
mov ebx ,count
l:
;判断循环条件
cmp edx ,ebx
jz exit;edx==ebx的时候退出

;获取数组地址
lea esi ,offset ContactList
lea edi ,offset s_test_user ;临时用待查询人姓名

;计算偏移量来选择数组的下一位
mov eax ,sizeof(Contact)
imul eax,edx
add esi ,eax

;串比较
mov ecx ,20
repe cmpsb

;比较成功了,跳转到s程序,将查询到的信息打印出来
jz s

;比较失败了,edx+1,然后继续查询
inc edx
jnz l
s:
;edx+1,然后ebx,edx入栈出栈
inc edx
push edx
push ebx
;invoke会改变ebx,edx的内容
invoke crt_printf ,offset s_test_user
pop ebx
pop edx
;然后无条件跳转回循环中继续下一次查询
jmp l

exit:
retn

searchContact endp

增加一个菜单功能

已经实现几个功能了,接下来我们可以新增一下菜单功能,让我们的操作看起来更直接一些

思路很简单,就是接收一个输入的值,如果值等于1就走1选项,以此类推即可,这里给出一个例子

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
.data
;菜单
bookmenu db "电话簿(Console版)v0.1",endl,
"1. 添加数据",endl,
"2. 查询数据",endl,
"3. 修改数据",endl,
"4. 删除数据",endl,
"5. 添加测试用数据",endl,
"6. 退出程序",endl,
"请输入选项:",0

choose db 1 dup(0)

chooselist db " 123456",0
.code
menu:
;显示菜单
push offset bookmenu
call crt_printf
add esp ,4

;输入选项
push offset choose
push offset input_format_str
call crt_scanf

;jcc跳转
mov ebx ,1

mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c1
inc ebx
;此处省略c2--c5
mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c6
jmp menu
c1:
inc ebx
call addContact
jmp menu
c6:
call ExitProcess

实现修改/删除功能

这里就讲个思路,方法与前面大同小异

修改/删除功能是在查询功能的基础之上新增的功能,设置一个修改flag=0,如果从菜单选中修改/删除,则flag=1,思路是通过查询函数查到数据之后,检查flag的值,如果flag=1,则进行修改/删除

删除操作其实就是把要删除的那一个部分用后面的内容覆盖掉就行了

效果图

image-20200514230142334

image-20200514230655653

image-20200514230749576

完整代码

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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
.586
.model flat ,stdcall

include msvcrt.inc
includelib msvcrt.lib
includelib user32.lib
includelib kernel32.lib

ExitProcess PROTO, dwExitCode:DWORD

.data
;清零用
zero db 20 dup(0)
;换行符
endl EQU <0dh,0ah>
;冒号
maohao db ":",0

;结构体存储名字电话
Contact struct
user db 20 dup(0)
tel db 20 dup(0)
Contact ends


;定义一个结构体数组存储所有联系人
ContactList Contact 100 dup(<'0'>)


;保存结构体数组查询出来的信息
s_user db 20 dup(0)
s_tel db 20 dup(0)


;定义一个临时结构用来传送数据
tmpContact Contact <'john','123123123123'>
;默认数据
tmpContact2 Contact <'chill','123123123123'>
tmpContact3 Contact <'bob','123123123123'>
;测试用查找字符
s_test_user db 20 dup(0)


;输入格式
input_format_str db "%s",0

;存放输入的变量
inputstr db 20 dup(0)
;查询用户名变量
searchstr db 20 dup(0)

;现有数据数
count dd 1 dup(0)

;修改数据flag
xg_flag dd 1 dup(0)

;删除数据flag
sc_flag dd 1 dup(0)

;分割线
line db "----------------------------------",endl,0

;问候语
input_user_text db "请输入联系人姓名:",endl,0
input_tel_text db "请输入联系人电话:",endl,0

search_info db "查询到信息如下:",endl,0

edit_user db endl,"请输入新的用户名:",endl,0
edit_tel db "请输入新的电话号码:",endl,0
search_success db "查询成功",endl,0
edit_success db "修改成功",endl,0
add_success db "添加成功",endl,0
rm_success db "删除成功",endl,0
addtmp_success db "添加临时数据成功,临时数据为:john、chill、bob",endl,0

;菜单
bookmenu db "电话簿(Console版)v0.1",endl,
"1. 添加数据",endl,
"2. 查询数据",endl,
"3. 修改数据",endl,
"4. 删除数据",endl,
"5. 添加测试用数据",endl,
"6. 退出程序",endl,
"请输入选项:>",0

choose db 1 dup(0)

chooselist db " 123456",0

.code
addContact proc
;消息提示1:请输入联系人姓名
push offset input_user_text
call crt_printf
add esp,4

;输入
push offset inputstr
push offset input_format_str
call crt_scanf
add esp,8

;保存到临时用结构里
lea esi ,offset inputstr
lea edi ,offset tmpContact.user
mov ecx ,20
rep movsb

;inputstr清零
lea esi ,offset zero
lea edi ,offset inputstr
mov ecx ,20
rep movsb

;----------------------------------------

;消息提示2:请输入联系人电话
push offset input_tel_text
call crt_printf
add esp,4

;输入
push offset inputstr
push offset input_format_str
call crt_scanf
add esp,8

;保存到临时用结构里
lea esi ,offset inputstr
lea edi ,offset tmpContact.tel
mov ecx ,20
rep movsb

;inputstr清零
lea esi ,offset zero
lea edi ,offset inputstr
mov ecx ,20
rep movsb

;-----------------------------------------

;保存到数据结构的最后
lea esi ,offset tmpContact
lea edi ,offset ContactList

;计算偏移,并移动
mov eax ,sizeof(Contact)
mov ecx ,count
imul eax,ecx
add edi ,eax
mov ecx ,40
rep movsb

push offset add_success
call crt_printf
add esp,4


;总数+1
inc count

;tmpContact 清零
lea esi ,offset zero
lea edi ,offset tmpConTact.user
mov ecx ,20
rep movsb
lea esi ,offset zero
lea edi ,offset tmpConTact.tel
mov ecx ,20
rep movsb

;返回
retn
addContact endp


add_default_data proc
;默认添加的数据
lea esi ,offset tmpContact
lea edi ,offset ContactList
mov eax ,sizeof(Contact)
mov ecx ,count
imul eax,ecx
add edi ,eax
mov ecx ,40
rep movsb
inc count

lea esi ,offset tmpContact2
lea edi ,offset ContactList
mov eax ,sizeof(Contact)
mov ecx ,count
imul eax,ecx
add edi ,eax
mov ecx ,40
rep movsb
inc count

lea esi ,offset tmpContact3
lea edi ,offset ContactList
mov eax ,sizeof(Contact)
mov ecx ,count
imul eax,ecx
add edi ,eax
mov ecx ,40
rep movsb
inc count


retn
add_default_data endp



searchContact proc
;消息提示1:请输入待查询联系人姓名
push offset input_user_text
call crt_printf
add esp,4

;输入
push offset searchstr
push offset input_format_str
call crt_scanf
add esp,8


mov edx ,0
mov ebx ,count
l:
cmp edx ,ebx
jz exit


lea esi ,offset ContactList
lea edi ,offset searchstr

mov eax ,sizeof(Contact)
imul eax,edx
add esi ,eax

mov ecx ,20
repe cmpsb
jz s

inc edx

jnz l
s:
inc edx
push edx
push ebx
push eax

;将查到的数据存起来
sub esi ,20
lea edi ,offset tmpContact.user
mov ecx ,20
rep movsb
lea edi ,offset tmpContact.tel
mov ecx ,20
rep movsb

invoke crt_printf ,offset search_info
invoke crt_printf ,offset tmpContact.user
invoke crt_printf ,offset maohao
invoke crt_printf ,offset tmpContact.tel

;检测是否需要修改
lea edi ,offset xg_flag
lea esi ,offset chooselist
add esi ,1
mov ecx ,1
repe cmpsb
jz xg

;检测是否需要删除
lea edi ,offset sc_flag
lea esi ,offset chooselist
add esi ,1
mov ecx ,1
repe cmpsb
jz sc

pop eax
pop ebx
pop edx


jmp l

exit:
;inputstr清零
lea esi ,offset zero
lea edi ,offset searchstr
mov ecx ,20
rep movsb
retn


xg:
pop eax
call editContact
pop ebx
pop edx
jmp l

sc:
pop eax
call rmContact
pop ebx
pop edx
jmp l

searchContact endp


editContact proc
push eax ;偏移量入栈
;消息提示1:请输入新的联系人姓名
push offset edit_user
call crt_printf
add esp,4

;输入
push offset inputstr
push offset input_format_str
call crt_scanf
add esp,8

;保存到临时用结构里
lea esi ,offset inputstr
lea edi ,offset tmpContact.user
mov ecx ,20
rep movsb

;inputstr清零
lea esi ,offset zero
lea edi ,offset inputstr
mov ecx ,20
rep movsb

;----------------------------------------

;消息提示2:请输入新的联系人电话
push offset edit_tel
call crt_printf
add esp,4

;输入
push offset inputstr
push offset input_format_str
call crt_scanf
add esp,8

;保存到临时用结构里
lea esi ,offset inputstr
lea edi ,offset tmpContact.tel
mov ecx ,20
rep movsb

;inputstr清零
lea esi ,offset zero
lea edi ,offset inputstr
mov ecx ,20
rep movsb

;-----------------------------------------

;使用新的联系人覆盖老的联系人
lea esi ,offset tmpContact
lea edi ,offset ContactList
;取出偏移量
pop eax
add edi ,eax
mov ecx ,40
rep movsb

;tmpContact 清零
lea esi ,offset zero
lea edi ,offset tmpConTact.user
mov ecx ,20
rep movsb
lea esi ,offset zero
lea edi ,offset tmpConTact.tel
mov ecx ,20
rep movsb

;-----------------------------------------



retn

editContact endp


rmContact proc


;获取要删除的地址
lea edi ,offset ContactList
add edi ,eax

;获取要删除的地址之后的地址
lea esi ,offset ContactList
add esi ,eax
add esi ,sizeof(Contact)

;获得要删除的地址之后的地址位数
mov ecx ,count
imul ecx,sizeof(Contact)
sub ecx,eax

;覆盖
rep movsb

dec count

push offset rm_success
call crt_printf
add esp,4

retn
rmContact endp

main proc
menu:
;显示菜单
push offset bookmenu
call crt_printf
add esp ,4

;输入选项
push offset choose
push offset input_format_str
call crt_scanf

;jcc跳转
mov ebx ,1

mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c1
inc ebx


mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c2
inc ebx

mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c3
inc ebx

mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c4
inc ebx

mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c5
inc ebx

mov esi ,offset chooselist
mov edi ,offset choose
add esi ,ebx
mov ecx ,1
repe cmpsb
jz c6

jmp menu

;增加数据
c1:
inc ebx
call addContact


push offset line
call crt_printf
add esp,4


jmp menu

;查找数据
c2:
inc ebx
call searchContact

push offset search_success
call crt_printf
add esp,4

push offset line
call crt_printf
add esp,4
jmp menu

;修改数据
c3:
inc ebx
lea edi ,offset xg_flag
lea esi ,chooselist
add esi ,1
mov ecx ,1
rep movsb
call searchContact

;把flag变回去
lea edi ,offset xg_flag
lea esi ,chooselist
add esi ,0
mov ecx ,1
rep movsb

push offset edit_success
call crt_printf
add esp,4

push offset line
call crt_printf
add esp,4
jmp menu

;删除数据
c4:
inc ebx
lea edi ,offset sc_flag
lea esi ,chooselist
add esi ,1
mov ecx ,1
rep movsb
call searchContact

;把flag变回去
lea edi ,offset sc_flag
lea esi ,chooselist
add esi ,0
mov ecx ,1
rep movsb

push offset line
call crt_printf
add esp,4
jmp menu

;添加临时数据
c5:
inc ebx
call add_default_data

push offset addtmp_success
call crt_printf
add esp,4

push offset line
call crt_printf
add esp,4

jmp menu

;退出程序
c6:
call ExitProcess

main endp
end main

遇到的问题及其解决方案

0X01 找不到msvcrt.inv文件

  1. 下载MASM SDK文件(http://www.masm32.com/)
  2. 安装,C盘装不上装其他盘也可以
  3. masm32文件夹下找到lib目录中找到msvcrt.lib文件,在include目录中找到msvcrt.inc文件,将它们复制到项目目录下

参考资料

VS常见错误之一:error LNK2019: 无法解析的外部符号

安装masm32 问题:Delete Operation of EXE file has Failed!的解决办法

汇编实现电话本 Tips

asm基础–汇编中的结构体

汇编语言LEA和OFFSET的区别

汇编语言:movsb/w/d