西电计科微机原理实验二(详细注释版)

环境:VSCode+MASM/TASM插件(建议使用相同环境,学校机房环境有点老,可能会出一些奇怪的问题)

avatar

实验要求

  1. 输入一个不超过5位的十进制数,回车结束输入,并将其转换为二进制数,输出到屏幕上
  2. 输入非数字字符,报错,重新输入
  3. 输入q或Q,结束程序
  4. 输入字符串,空格结束输入,统计字符串中数字的个数 (选做)

基础版本(不做4)

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
_STACK SEGMENT PARA STACK'_STACK'
DB 128 DUP(0)
_STACK ENDS


DATA SEGMENT
hello DB 'Input a number or an instruction!!Q OR q: EXIT',0AH,0DH,'$'
wrong DB 0AH,0DH,'Wrong Input(only numbers!)',0AH,0DH,'$'
endofhex DB 0AH,0DH,'Binary:',0AH,0DH,'$'
finish DB 0AH,0DH,'Finished',0AH,0DH,'$'
got DB 5 DUP(0)
DATA ENDS


CODE SEGMENT
assume cs:CODE,ds:DATA,ss:_STACK

START:

beginofread:
mov ax,DATA
mov ds,ax
;取偏移地址
mov dx,offset hello
;显示字符串
mov ah,09H
int 21H
; 清零BX
mov bx,0H
; 初始化DI和CX
mov di,offset got
mov cx,0H
readchar:
; 读取字符
mov ah,01H
int 21H
; 比较BX是否为0,如果不是,跳到notfirst
cmp bx,0H
jne notfirst
; 比较AL是否为Q或q,如果是,则退出程序
cmp al,'Q'
je exit
cmp al,'q'
je exit


notfirst:
;判断是否合法
mov bx,01H
call legalcheck
;不合法重新开始
cmp bx,02H
je beginofread
;换行输入结束
cmp bx,04H
je endofinput

jmp loadinmemory

loadinmemory:
;输入存入内存
mov [di],al
inc cx
inc di
jmp readchar

endofinput:
;取前5位
mov dx,0H
mov di,offset got

;将数字转换为ascii码
beginofhandle:
mov bx,0H
mov bl,[di]
; 将寄存器BX中的值减去30H
sub bx,30H
add dx,bx
;处理完毕
cmp cx,1H
je endofhandle
;ax清零,乘10
call mulAHdxtodx
;待处理字符减一
dec cx
;下一位
inc di
jmp beginofhandle

;输出ASCII码
endofhandle:
;输出2进制
call binaryoutput
;跳转重新开始
jmp beginofread

binaryoutput:
mov bx,dx
mov dx,0H
mov cx,10H ;循环16次
;开始循环
beginofoutputloop:
;左移1位
shl bx,1
;不进位则跳转
jnc out0
mov dl,'1'
jmp outputdl
out0:
mov dl,'0'
outputdl:
mov ah,02H
int 21H
dec cx ;循环次数减1
cmp cx,0H ;判断循环是否结束
jne beginofoutputloop
;结束循环,输出结束语句
mov dx,offset finish
mov ah,09H
int 21H
ret

legalcheck:
;判断换行
cmp al,0DH
je endlegalnextline
;判断数字0-9
cmp al,30H
jb endlegalfalse
cmp al,39H
ja endlegalfalse

endlegaltrue:
mov bx,03H
ret

endlegalnextline:
mov bx,04H
ret

endlegalfalse:
;输出wrong语句
mov dx,offset wrong
mov ah,09H
int 21H
;重新开始程序
mov bx,02H
ret


mulAHdxtodx:
mov bx,0H
mov ax,0H

loopofmul:
add ax,dx
inc bx
cmp bx,0AH
jb loopofmul
mov dx,ax
ret

exit:
mov ah,4CH
int 21H
CODE ENDS
END START

运行结果:

avatar

完整版(实验结束后完成)

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
_STACK SEGMENT PARA STACK'_STACK'
DB 128 DUP(0)
_STACK ENDS


DATA SEGMENT
hello DB 'Input a number or an instruction!!Q OR q: EXIT,s:SEARCH',0AH,0DH,'$'
wrong DB 0AH,0DH,'Wrong Input(only numbers!)',0AH,0DH,'$'
endofhex DB 0AH,0DH,'Binary:',0AH,0DH,'$'
finish DB 0AH,0DH,'Finished',0AH,0DH,'$'
hello2 DB 0AH,0DH,'Search number inyour string. Space to end input',0AH,0DH,'Input string:',0AH,0DH,'$'
finish2 DB 0AH,0DH,'FINISHED!!!',0AH,0DH,'THERE ARE ','$'
finish3 DB ' numbers',0AH,0DH,'$'
got DB 5 DUP(0)
DATA ENDS


CODE SEGMENT
assume cs:CODE,ds:DATA,ss:_STACK

START:

beginofread:
mov ax,DATA
mov ds,ax
;取偏移地址
mov dx,offset hello
;显示字符串
mov ah,09H
int 21H
; 清零BX
mov bx,0H
; 初始化DI和CX
mov di,offset got
mov cx,0H
readchar:
; 读取字符
mov ah,01H
int 21H
; 比较BX是否为0,如果不是,跳到notfirst
cmp bx,0H
jne notfirst
; 比较AL是否为Q或q,如果是,则退出程序
cmp al,'Q'
je exit
cmp al,'q'
je exit
; 比较AL是否为s,如果是,则进行搜索操作
cmp al,'s'
je counterofnumber


notfirst:
;判断是否合法
mov bx,01H
call legalcheck
;不合法重新开始
cmp bx,02H
je beginofread
;换行输入结束
cmp bx,04H
je endofinput

jmp loadinmemory

loadinmemory:
;输入存入内存
mov [di],al
inc cx
inc di
jmp readchar

endofinput:
;取前5位
mov dx,0H
mov di,offset got

;将数字转换为ascii码
beginofhandle:
mov bx,0H
mov bl,[di]
; 将寄存器BX中的值减去30H
sub bx,30H
add dx,bx
;处理完毕
cmp cx,1H
je endofhandle
;ax清零,乘10
call mulAHdxtodx
;待处理字符减一
dec cx
;下一位
inc di
jmp beginofhandle

;输出ASCII码
endofhandle:
;输出2进制
call binaryoutput
;跳转重新开始
jmp beginofread

binaryoutput:
mov bx,dx
mov dx,0H
mov cx,10H ;循环16次
;开始循环
beginofoutputloop:
;左移1位
shl bx,1
;不进位则跳转
jnc out0
mov dl,'1'
jmp outputdl
out0:
mov dl,'0'
outputdl:
mov ah,02H
int 21H
dec cx ;循环次数减1
cmp cx,0H ;判断循环是否结束
jne beginofoutputloop
;结束循环,输出结束语句
mov dx,offset finish
mov ah,09H
int 21H
ret

legalcheck:
;判断换行
cmp al,0DH
je endlegalnextline
;判断数字0-9
cmp al,30H
jb endlegalfalse
cmp al,39H
ja endlegalfalse

endlegaltrue:
mov bx,03H
ret

endlegalnextline:
mov bx,04H
ret

endlegalfalse:
;输出wrong语句
mov dx,offset wrong
mov ah,09H
int 21H
;重新开始程序
mov bx,02H
ret

mulAHdxtodx:
mov bx,0H
mov ax,0H

loopofmul:
add ax,dx
inc bx
cmp bx,0AH
jb loopofmul
mov dx,ax
ret

counterofnumber:
mov dx,offset hello2
mov ah,09H
int 21H
mov cx,0H
beginofcount:
mov ah,01H
int 21H
;空格完成输入
cmp al,20H
je endofcount
cmp al,30H
jb notnum
cmp al,39H
ja notnum
isnum:
inc cx
jmp beginofcount
notnum:
jmp beginofcount
endofcount:
add cx,30H
mov dx,offset finish2
mov ah,09H
int 21H
mov dx,0H
mov dl,cl
mov ah,02H
int 21H
mov dx,offset finish3
mov ah,09H
int 21H
;跳回开始位置
jmp beginofread




exit:
mov ah,4CH
int 21H
CODE ENDS
END START


运行结果:
avatar