西电计科微机原理实验二(详细注释版)
环境:VSCode+MASM/TASM插件(建议使用相同环境,学校机房环境有点老,可能会出一些奇怪的问题)
实验室:EⅡ-522
实验要求
- 输入一个不超过5位的十进制数,回车结束输入,并将其转换为二进制数,输出到屏幕上
- 输入非数字字符,报错,重新输入
- 输入q或Q,结束程序
- 输入字符串,空格结束输入,统计字符串中数字的个数 (选做)
基础版本(不做4)
_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
运行结果:
完整版
_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
运行结果: