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

2023-12-14 05:01:43

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

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

avatar

实验室:EⅡ-522

实验要求
  1. 输入一个不超过5位的十进制数,回车结束输入,并将其转换为二进制数,输出到屏幕上
  2. 输入非数字字符,报错,重新输入
  3. 输入q或Q,结束程序
  4. 输入字符串,空格结束输入,统计字符串中数字的个数 (选做)
基础版本(不做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

运行结果:

avatar

完整版
_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

文章来源:https://blog.csdn.net/m0_62201229/article/details/134981138
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。