华工微机实验报告

微机系统与接口实验

电子与信息学院

电类联合班

何俊

实验二:将ASCII码表示的十进制数转换为二进制数

1. 将ASCII码表示的十进制数转换为二进制数。

DATA SEGMENT

ORG 3500H

     NUM1 DB 5 DUP(0)

ORG 3510H

     NUM2 DD 5 DUP(0)

DATA ENDS

STACK SEGMENT STACK 'STACK'

      DB 100 DUP(0)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:STACK

START:

     MOV AX,DATA

     MOV DS,AX

     MOV AX,OFFSET NUM1

     MOV SI,AX

     MOV AX,OFFSET NUM2

     MOV DI,AX

     MOV CX,5

     MOV AX,0

     MOV BH,0

CHANGE:

     MOV BL,[SI]

     SUB BL,30H

     MOV DX,10

     MUL DX

     ADD AX,BX

     ADD SI,1

     LOOP CHANGE

EXIT:

     MOV WORD PTR[DI],AX

     MOV AH,4CH

     INT 21H

CODE ENDS

END START

 

2. 将从键盘输入的五位十进制数的ASCII码已存在3500起始的内存单元中。把它转换成BCD码后,再按位分别存入350A起始的内存单元内。若输入的不是十进制的ASCII码,则显示FF.

DATA SEGMENT

ORG 3500H

     NUM1 DB 5 DUP(0)

     ;NUM1 DB ‘12345’

ORG 350AH

     NUM2 DB 5 DUP(0)

DATA ENDS

STACK SEGMENT

      DB 100 DUP(0)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:STACK

START:

     MOV AX,DATA

     MOV DS,AX

     MOV AX,OFFSET NUM1

     MOV SI,AX

     MOV AX,OFFSET NUM2

     MOV DI,AX

    

     MOV CX,5

CHANGE:

     MOV AL,[SI]

     CMP AL,39H

     JA ERROR

     CMP AL,30H

     JB ERROR

     SUB AL,30H

     MOV [DI],AL

     ADD SI,1

     ADD DI,1

     LOOP CHANGE

    

     JMP EXIT

ERROR:

     MOV BX,0FFH

     MOV [DI],BX

EXIT:

     MOV AH,4CH

     INT 21H

CODE ENDS

END START

3.  将十六位二进制数转换为ASCII码表示的十进制数。

十六进制数的值域为0~65535,最大可转换为五位十进制数。

DATA SEGMENT

ORG 3500H

     NUM1 DD 0

ORG 3510H

     NUM2 DB 5 DUP(0)

DATA ENDS

STACK SEGMENT

      DB 100 DUP(0)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:STACK

START:

     MOV AX,DATA

     MOV DS,AX

     MOV AX,OFFSET NUM1

     MOV SI,AX

     MOV AX,OFFSET NUM2

     MOV DI,AX

     ADD DI,5

     MOV CX,5

     MOV AX,WORD PTR[SI]

     MOV BX,10

    

CHANGE:

     MOV DX,0

     DIV BX

     ADD DL ,30H

     MOV [DI],DL

     DEC DI    

LOOP CHANGE

EXIT:

     MOV AH,4CH

     INT 21H

CODE ENDS

END START

4.      十六进制数转换为ASCII码

DATA SEGMENT

ORG 3500H

     NUM1 DD 0

ORG 3510H

     NUM2 DB 4 DUP(0)

DATA ENDS

STACK SEGMENT

      DD 100 DUP(0)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:STACK

START:

     MOV AX,DATA

     MOV DS,AX

     MOV AX,OFFSET NUM1

     MOV SI,AX

     MOV AX,OFFSET NUM2

     MOV DI,AX

     MOV BL,2

     MOV CX,4

CHOICE:

     MOV AL,[SI]

     AND AL,0FH

     CMP AL,9

JBE CHANGE_11

JMP CHANGE_12

CHANGE_11:

     ADD AL,30H

     JMP NEXT_1

    

CHANGE_12:

     ADD AL,37H

    

NEXT_1:

     MOV [DI],AL

     ADD DI,1

     MOV AL,[SI]

     AND AL,0F0H

     SHR AL,CL

     CMP AL,9

JBE CHANGE_21

JMP CHANGE_22

CHANGE_21:

     ADD AL,30H

JMP NEXT_2

CHANGE_22:

     ADD AL,37H

    

NEXT_2:

     MOV [DI],AL

     ADD DI,1

     ADD SI,1

     DEC BX

JNE CHOICE

EXIT:

     MOV AH,4CH

     INT 21H

CODE ENDS

END START

5.      BCD码转换为二进制码

DATA SEGMENT

ORG 3500H

     NUM1 DB 8 DUP(0)

ORG 3510H

NUM2 DB 4 DUP(0)

DATA ENDS

STACK SEGMENT

      DB 100 DUP(0)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:STACK

START:

     MOV AX,DATA

     MOV DS,AX

     MOV AX,OFFSET NUM1

     MOV SI,AX

     MOV AX,OFFSET NUM2

     MOV DI,AX

     MOV CX,4

     MOV BL,10

CHANGE:

     MOV AL,[SI]

     MUL BL

     ADD SI,1

     ADD AL,[SI]

     ADD SI,1

     MOV [DI],AL

     ADD DI,2

LOOP CHANGE

EXIT:

     MOV AH,4CH

     INT 21H

CODE ENDS

END START

实验三  分支和循环程序设计实验

1.      设计一数据块间的搬移程序

DATA SEGMENT

ORG 3500H

     MESSAGE1 DB 'HELLO KITTY'

     COUNT EQU 11

DATA ENDS

EXTRA SEGMENT

ORG 3510H

     MESSAGE2 DB 11 DUP(0)

EXTRA ENDS

STACK SEGMENT

    DD 100 DUP(0)

STACK ENDS

CODE SEGMENT

    ASSUME CS:CODE,DS:DATA,ES:EXTRA,SS:STACK

START:

    MOV AX,DATA

    MOV DS,AX

    MOV AX,OFFSET MESSAGE1

    MOV SI,AX

    MOV AX,OFFSET MESSAGE2

    MOV DI,AX

    MOV AX,DS

    MOV ES,AX

   

    MOV CX,COUNT

   

    CLD

   

COMPARE:

    CMP SI,DI

    JB NEXT1

    JMP NEXT2

NEXT1:

    STD

    ADD SI,COUNT-1

    ADD DI,COUNT-1

    REP MOVSB

    JMP EXIT

   

NEXT2:

    REP MOVSB

    JMP EXIT

EXIT:   

    MOV AH,4CH

    INT 21H

CODE ENDS

END START

2.      编制程序使S=1+2*3+3*4+4*5+……N(N+1),直到N(N+1)项大于200为止。

DATA SEGMENT

ORG 3500H

RESULT DD 0

DATA ENDS

CODE SEGMENT

    ASSUME CS:CODE

START:

    MOV DX,1

    MOV BL,2

SUM:

    MOV AL,BL

    INC BL

    MUL BL

    ADD DX,AX

    CMP AX,200

    JB SUM

   

PRINT:

    MOV AX,OFFSET RESULT

    MOV DI,AX

    MOV [DI],DX

   

EXIT:

    MOV AH,4CH

    INT 21H

CODE ENDS

END START

3.      求某个数据区内负数的个数。

DATA SEGMENT

ORG 3500H

     NUM DB 6H,12H,88H,82H,90H,22H,33H

DATA ENDS

CODE SEGMENT

    ASSUME CS:CODE,DS:DATA

START:

    MOV AX,DATA

    MOV DS,AX

    MOV AX,OFFSET NUM

    MOV SI,AX

   

    MOV BL,0

    MOV CL,[SI]

    MOV CH,0

    INC SI

   

CHECK:

    MOV AL,[SI]

    CMP AL,10000000B

    JBE NEXT

    INC BL

NEXT:

    INC SI

    LOOP CHECK

   

PRINT:

    MOV [SI],BL   

   

EXIT:

    MOV AH,4CH

    INT 21H

CODE ENDS

END START

实验四 子程序设计

程序采用菜单式选择,可接收用户输入的命令(1~5),各命令如下:

按1键完成字符串小写字母变大写字母

用户输入一由英文大小写字母或数字0~9组成的字符串(以回车结束),程序逐个检查字符串中各字符,将原串中小写字母变成大写字母,其它字符不变,并在屏幕上显示。用户按任一键,重做,按ESC键,返回主菜单。

按2键完成找最大值(二选一)

1、接收用户输入的可显示字符串(以回车结束),程序将其中ASCII码值最大的字符显示出来。

2、接收用户输入若干无符号8位数(以空格或逗号为分隔符,以回车结束),程序将其中最大的数显示出来。用户按任一键,重做,按ESC键,返回主菜单。

按3键完成排序(二选一)

1、接收用户输入的可显示字符串,以回车结束。程序按ASCII码值大小由大到小排序并输出显示。

2、接收用户输入若干个有符号8位数(以空格逗号为分隔符,以回车结束)。程序将其中最大的数显示出来。用户按任一键,重做,按ESC键,返回主菜单。

按4键显示时间

首先提示用户对时,即用户输入时,分,秒(以空格或冒号分隔,以回车结束),然后,在屏幕上不断显示时间,格式为:××(时):××(分):××(秒),最好定点显示。用户按任一键,重新对时,按ESC键,返回主菜单。

按5键,结束程序运行,返回系统提示符。

DATA SEGMENT

ORG 0000H

;BUFFER POOL.

    BUFF DB 100

         DB 0

         DB 100 DUP(0)

DATA ENDS

STACK SEGMENT

    STT DB 100 DUP(0)

    TOP EQU LENGTH STT

STACK ENDS

CODE SEGMENT

    ASSUME CS:CODE,DS:DATA,SS:STACK

;MAIN PROCESS

START:

MAIN PROC FAR

FIRST:

    MOV AX,DATA

    MOV DS,AX

    MOV SI,OFFSET BUFF

    MOV AX,STACK

    MOV SS,AX

    MOV SP,OFFSET TOP

   

CHOICE:

    MOV AH,1

    INT 21H

    CMP AL,'5'

    JE EXIT

    CMP AL,'1'

    JE FUNCTION1

    CMP AL,'2'

    JE FUNCTION2

    CMP AL,'3'

    JE FUNCTION3

    CMP AL,'4'

    JE FUNCTION4

CHANGE_LINE:

    MOV DL,0AH

    MOV AH,2

    INT 21H

;ERROR INPUT, CHOOSE AGAIN.

    JMP FIRST

       

FUNCTION1:

    MOV DL,0AH

    MOV AH,2

    INT 21H

    CALL F1

    JMP CHANGE_LINE

   

FUNCTION2:

    MOV DL,0AH

    MOV AH,2

    INT 21H

    CALL F2

    JMP CHANGE_LINE

   

FUNCTION3:

    MOV DL,0AH

    MOV AH,2

    INT 21H

    CALL F3

    JMP CHANGE_LINE

FUNCTION4:

    MOV DL,0AH

    MOV AH,2

    INT 21H

    CALL F4

    JMP CHANGE_LINE

   

EXIT:

    MOV AH,4CH

    INT 21H

    RET

   

MAIN ENDP

;SUBPROCESS 1

F1 PROC NEAR

;GET STRING

    MOV SI,OFFSET BUFF

    MOV DX,SI

    MOV AH,0AH

    INT 21H

   

    CALL CHANGE_LINE

   

;GET THE SIZE OF STRING

    INC SI   

    MOV CL,[SI]

    MOV CH,0

    INC SI

;CHANGE THE LETTERS AND PRINT

CHANGE:

    MOV DL,[SI]

    CMP DL,'Z'

    JBE NEXT

    SUB DL,20H

NEXT:

    MOV AH,2

    INT 21H

    INC SI

    LOOP CHANGE

   

    CALL CHANGE_LINE

  

;RETURN

RET

F1 ENDP

;SUBPROCESS 2

F2 PROC NEAR

;GET STRING

    MOV DX,SI

    MOV AH,0AH

    INT 21H

    CALL CHANGE_LINE

;GET THE SIZE OF STRING

    INC SI   

    MOV CL,[SI]

    MOV CH,0

    INC SI

;GET THE MAX CHAR

    MOV AL,[SI]

    INC SI

COMPARE:

    CMP AL,[SI]

    JA NEXT

    MOV AL,[SI]

NEXT:

    INC SI

    LOOP COMPARE

PRINT:

    MOV DL,AL

    MOV AH,2

    INT 21H

   

    CALL CHANGE_LINE

;RETURN

RET

F2 ENDP

;SUBPROCESS 3

F3 PROC NEAR

;GET STRING

    MOV SI,OFFSET BUFF

    ADD SI,2

    MOV DX,SI

    MOV AH,0AH

    INT 21H

    CALL CHANGE_LINE

;GET THE SIZE OF STRING

    INC SI   

    MOV CL,[SI]

    MOV CH,0

    INC SI

    MOV DX,SI

    DEC CX

   

;BUBBLE SORT

LOOP1:

    MOV BX,CX

LOOP2:

    MOV AL,[SI]

    CMP AL,[SI+1]

    JA NEXT

    XCHG AL,[SI+1]

    MOV [SI],AL

NEXT:

    INC SI

    DEC BX

    JNE LOOP2

    MOV SI,DX

    LOOP LOOP1

   

;PRINT

    MOV CL,[SI-1]

    MOV CH,0

PRINT:

    MOV DL,[SI]

    MOV AH,2

    INT 21H

    INC SI

    LOOP PRINT

   

    CALL CHANGE_LINE

;RETURN

RET

F3 ENDP

   

;SUBPROCESS 4

F4 PROC NEAR

;INPUT THE TIME

INPUT:

    MOV DX,SI

    MOV BL,10

;HOUR

    MOV AH,0AH

    INT 21T

    CMP BYTE PTR[SI+1],2

    JNE INPUT

    SUB BYTE PTR[SI+2],30H

    SUB BYTE PTR[SI+3],30H

    MOV AL,[SI+2]

    MUL BL

    ADD AL,[SI+3]

    MOV CH,AL

    CALL CHANGE_LINE

;MINUTE

    MOV AH,0AH

    INT 21T

    CMP BYTE PTR[SI+1],2

    JNE INPUT

    SUB BYTE PTR[SI+2],30H

    SUB BYTE PTR[SI+3],30H

    MOV AL,[SI+2]

    MUL BL

    ADD AL,[SI+3]

    MOV CL,AL

    CALL CHANGE_LINE

;SECOND

    MOV AH,0AH

    INT 21T

    CMP BYTE PTR[SI+1],2

    JNE INPUT

    SUB BYTE PTR[SI+2],30H

    SUB BYTE PTR[SI+3],30H

    MOV AL,[SI+2]

    MUL BL

    ADD AL,[SI+3]

    MOV DH,AL

    CALL CHANGE_LINE

;1/100 SECOND

    MOV DL,0

   

;SET THE TIME

    MOV AH,2DH

    INT 21H

;CHECK

    CMP AL,00

    JNE INPUT

   

;GET THE TIME

    MOV SI,OFFSET BUFF

    ADD SI,2

GET:

    MOV AH,2CH

    INT 21H

    MOV [SI],CH

    MOV [SI+2],CL

    MOV [SI+4],DH

;BINARY TO ASCII

    MOV BL,10

;HOUR

    MOV AH,0

    MOV AL,[SI]

    DIV BL

    ADD AH,30H

    ADD AL,30H

    MOV [SI],AL

    MOV [SI+1],AH

;MINUTE

    MOV AH,0  

    MOV AL,[SI+2]

    DIV BL

    ADD AH,30H

    ADD AL,30H

    MOV [SI+2],AL

    MOV [SI+3],AH

;SECOND

    MOV AH,0

    MOV AL,[SI+4]

    DIV BL

    ADD AH,30H

    ADD AL,30H

    MOV [SI+4],AL

    MOV [SI+5],AH

;PRINT THE TIME

;HOUR

    MOV DL,[SI]

    MOV AH,2

    INT 21H

    MOV DL,[SI+1]

    MOV AH,2

    INT 21H

    MOV DL,':'

;MINUTE

    MOV DL,[SI+2]

    MOV AH,2

    INT 21H

    MOV DL,[SI+3]

    MOV AH,2

    INT 21H

    MOV DL,':'

;SECOND

    MOV DL,[SI+4]

    MOV AH,2

    INT 21H

    MOV DL,[SI+5]

    MOV AH,2

    INT 21H

   

;CHECK THE INPUT

    MOV AH,0BH

    INT 21H

    CMP AL,0FFH

    JE GET

;RESET OR EXIT

    MOV AH,1

    INT 21H

    CMP AL,1BH

    JE EXIT

    JMP INPUT   

   

;RETURN

EXIT:

    RET

F4 ENDP

;CHANGE LINE

CHANGE_LINE PROC NEAR

    PUSH AX

    PUSH DX

    MOV DL,0DH

    MOV AH,02

    INT 21H

    MOV DL,0AH

    MOV AH,02

    INT 21H

    POP DX

    POP AX

RET

CHANGE_LINE ENDP   

CODE ENDS

   END START

实验心得

1、                对于汇编程序,书上的内容有限,更多的内容需要自己上网查找甚至自己发现。比如DOS和BIOS的一些功能调用,书上只列出了简单常用的一部分,但DOS和BIOS的强大功能不仅于此。因此实验后可以更进一步了解了汇编语言。

2、                实验过程中,代码第一次完成就没有出错的情况是比较少见的,更多的时间会花在调试、检查和修改上。其中语法错误最容易发现,因为编译不能通过,如将一个2字节的存储器数据赋给了1字节的寄存器,编译就会报错,只需按所学知识修改即可。而逻辑错误就难以发现,因为编译和生成EXE文件步骤上都是没有问题的,但运行时往往得不到正确的结果,这时就需要仔细地逐步去调试,发现问题所在并修改之。

3、                实验2和实验3的代码都比较简单,都是一些比较简单的改动内存的数据后运行程序,使另一处内存得到预期结果。但实验4代码比较繁琐,每一点细微的差错都可能造成整个程序输出乱码。实验4的子程序2和子程序3有一部分代码其实是相同的,可以用另一个子程序去替代,但鉴于初学,目前仅用复制代码去完成。其中实验4的第4个子程序仍没有正确写出。瓶颈在于如何获取到键盘有无输入的同时且获取到所需输入的按键是哪一个,以及如何定点显示。我相信在我更深一步学习汇编语言之后会很好地突破这个瓶颈。

相关推荐