汇编第3次上机实验报告

第三次上机实验报告

时间:20##/4/26,18:30-21:30

地点:      南一楼803室      

实验人员:           

一、题目

输入一组有符号字数据。对该组数进行排序,按照从大到小的顺序以用户指定的进制形式输出排序后的结果。

运行时:

        Please input numbers:

        123   0   -100   -50  300  25

      Output  Format (1: decimal; 2 :hex; 3: Octal) : 1

300, 123, 25, 0, -50, -100

运行时:

        Please input numbers:

        123   0   -100   -50  300  25

      Output  Format (1: decimal; 2 :hex; 3: Octal ) : 2

        12CH, 7BH, 19H, -32H, -64H

二、要求:

(1)  画出程序流程图,给出寄存器、存储单元的分配方法,子程序的功能、入口参数及出口参数(对于各个子程序,也要说明其寄存器、存储单元的分配情况。在流程图中也列出相应子程序的名称)。

(2) “数字串到字数据的转换”用子程序实现。要求:该子程序只实现一个数字串的转换。对于多个数字串,要多次调用该子程序。(可以借鉴教材中的示例,注意每个模块前都应该加上“.386”)。对于非数字串,以及超过一个字大小的数字串应给出提示。

(3)“排序”使用子程序实现。

(4) “数值数据到串的转换”用子程序实现。要求该子程序只实现一个数值数据的转换。

(5) 输入时,数字串之间的分割符可以是一个空格,也可以是一个标点符号(如逗号),数字串前可有一个正号或负号。输出时,数字串之间的分割符号为一个逗号加上一个空格。

(6) 观察执行CALL指令时,堆栈的变化,以及IP、CS的变化。

(7) 掌握跟踪进入子程序的方法。

(8) 定义宏并使用宏指令,观察宏扩展后的结果。

(9) 采用模块化程序的方法设计该程序。

(10)写下必要的设计文档可以帮助我们理清思路,减少写程序时的错误;

(11)同学们可以相互讨论算法思想,理清思路;

(12)可以先不用子程序来实现程序的功能,然后再改写成子程序,最后拆分到不同模块;

(13)在源程序中加上适当的注释。

三、寄存器和存储单元分配和说明

AX——中间寄存器。

BX——往ARR字存储区送数指针,初值为ARR。

CX——作以逗号分隔的一个十进制数字串长度计数器,初值为0。

DX——按系统功能调用的规定使用。

DI——往BUF字节存储区送输入的字符指针,初值为BUF。

SI——调用F10T2子模块的入口参数,作从BUF区取字符指针。

BUF——输入缓冲区首址。

ARR——经转换得到的二进制数组存储区首址。

COUNT——ARR存储区中数组元素个数计数器,初值为0。

SIGN——输入字符串处理结束标志,1—处理结束,0—处理未结束。

四、程序流程图

子模块F2TN流程图:

汇编第3次上机实验报告

汇编第3次上机实验报告

NAME    MAIN

EXTRN   F10T2:NEAR  ,F2T10:NEAR  ,QUEUE:NEAR

IF1

       INCLUDE  MACRO.LIB           ;将宏汇编在第一次扫描时加入一起回汇编

ENDIF

.386

DATA     SEGMENT     USE16    PARA     PUBLIC  'DATA'

BUF DB  8     DUP(0)   ;输入一个十进制数字串存储区

ARR       DB  32    DUP(0)   ;转换后的二进制数组存储区

SIGN      DB  0     ;标记是否输入完0:未输完,1:输完

COUNT  DW 0     ;转换后的二进制数组元素个数计数器

ERROR   DB  'IS ILLEGAL DIGIT!$'

INPUT1  DB  'Please Input Numbers:$'

INPUT2  DB  'Output  Format (1:decimal; 2:hex; 3:Octal):$'

DATA     ENDS

       STACK0 <200      DUP(0)>

CODE     SEGMENT     USE16    PARA     PUBLIC  'CODE'

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

START:   MOV      AX, DATA

       MOV      DS,  AX

       MOV      ES,  AX

       LEA BX, ARR       ;数组首址ARR->BX

       MOV      COUNT,  0

       MOV      SIGN,     0

       WRITE   INPUT1

BEG:      LEA DI,  BUF ;数字串存储区首址

       MOV      CX, 0

NEXT0:  MOV      AH, 1

       INT 21H

       CMP       AL,  ' '     ;输入数字用空格分隔

       JE   DIGIT

       CMP       AL,  0DH ;判断是否为回车符

       JNE P

       CMP       COUNT,  0

       JE   EXIT

       INC SIGN             ;已全部输完,标识置1

       JMP DIGIT            ;转digit调用F10T2子模块

P:    STOSB

       INC CX

       JMP NEXT0

DIGIT:    LEA SI,   BUF

       MOV      DX, 16

       CALL     F10T2            ;调用F10T2子模块

       CMP       SI,   -1    ;判断是否有非法字符和溢出,转到ERR处

       JE   ERR

       MOV      [BX],      AX

       ADD       BX, 2

       INC COUNT

       CMP       SIGN,     1

       JE   END0

       JMP BEG

END0:    MOV      CX, COUNT

       LEA SI,   ARR

       MOV      BP,  1     ;对有符号数置1

       CALL     QUEUE         ;调用QUEUE排序模块

       CRLF                    ;换行

       WRITE   INPUT2         ;输出提示信息,

       MOV      AH, 1     ;选择输出格式

       INT 21H

       SUB AL,  '1'

       XOR       AH, AH

       MOV      CX, AX

       CRLF                    ;换行

       MOV      BX, COUNT  ;

       LEA SI,   ARR       ;待输出数组的首址送SI

OUT2:    MOV      AX, [SI] ;取出一个待输出的数送到AX

       ADD       SI,   2

       MOV      DX, 16

       CALL     F2TN             ;调用F2TN子模块,将AX按用户指定格式输出

       OUT1     ' '            ;输出用空格分隔

       DEC       BX

       JNE OUT2            ;未输完,转到OUT2继续

       JMP EXIT             ;输完,到EXIT结束

ERR:      CRLF

       WRITE   ERROR          ;对非法操作输出错误提示

EXIT:     MOV      AH, 4CH

       INT 21H

CODE     ENDS

END       START

NAME    F10T2

;功能:将十进制ASCII码转换成有符号的二进制数AX/EAX,可转换的16位数范围是-32767~+32767

;入口参数:

;      SI——指向待转换的十进制ASCII码存储区首址

;      CX——存放该十进制ASCII码串的长度

;出口参数:

;      EBX——中间寄存器

;      SIGN——正负数标记

PUBLIC  F10T2

.386

DATA     SEGMENT     USE16    PARA     PUBLIC  'DATA'

SIGN      DB  ?

DATA     ENDS

CODE     SEGMENT     USE16    PARA     PUBLIC  'CODE'

       ASSUME       CS:CODE,     DS:DATA

F10T2     PROC

       PUSH     EBX

       MOV      EAX,      0

       MOV      SIGN,     0

       MOV      BL,  [SI]

       CMP       BL,  '+'

       JE   F10

       CMP       BL,  '-'

       JNE NEXT2

       MOV      SIGN,     1

F10: DEC       CX

       JZ    ERR

NEXT1:  INC SI

       MOV      BL,  [SI]

NEXT2:  CMP       BL,  '0'

       JB   ERR

       CMP       BL,  '9'

       JA   ERR

       SUB BL,  30H

       MOVZX  EBX,      BL

       IMUL     EAX,      10

       JO   ERR

       ADD       EAX,      EBX

       JO   ERR

       JS    ERR

       JC   ERR

       DEC       CX

       JNZ NEXT1

       CMP       DX, 16

       JNE PP0

       CMP       EAX,      7FFFH

       JA   ERR

PP0: CMP       SIGN,     1

       JNE QQ

       NEG       EAX

QQ: POP EBX

       RET

ERR:      MOV      SI,   -1

       JMP QQ

F10T2     ENDP

CODE     ENDS

       END

NAME    F2TN

;功能:将AX/EAX中有符号二进制数换成N进制数,N有用户指定

;入口参数:

;      AX/EAX——存放待转换二进制数

;      CX——存放用户要求的进制数的序号

;出口参数:

;      BUF——

;      FROMAT——存放对用户输入要求转换的进制数

;      EAX——存放待转换的二进制数

;      EBX——存放要转换的进制数

;      SI——存放待转换的N进制数ASCII码数字串的字节缓冲区首址

;      DI——存放各种进制数内容区的首址

;      CX——N进制数计数器(在RADIX子程序中使用)

;      EDX——按除法指令和系统功能调用的规定使用

PUBLIC  F2TN     

.386

DATA     SEGMENT     USE16    PARA     PUBLIC  'DATA'

BUF DB  12    DUP(?)

FORMAT DB  10,16,8

DATA     ENDS

CODE     SEGMENT     USE16    PARA     PUBLIC  'CODE'

       ASSUME       CS:CODE, DS:DATA

F2TN      PROC

       PUSH     EBX

       PUSH     SI

       PUSH     DI

       LEA SI,   BUF

       MOVSX  EAX,      AX

       OR  EAX,      EAX

       JNS PLUS

       NEG       EAX

       MOV      BYTE     PTR [SI], '-'

       INC SI

PLUS:     LEA DI,  OFFSET FORMAT

       ADD       DI,  CX

       MOV      BL,  [DI]

       MOVZX  EBX,      BL

       CALL     RADIX  

       MOV      BYTE     PTR [SI], '$'

       LEA DX, BUF

       MOV      AH, 9

       INT 21H

       POP DI

       POP SI

       POP EBX

       RET

F2TN      ENDP

RADIX   PROC

       PUSH     CX

       PUSH     EDX

       XOR       CX, CX

LOP1:     XOR       EDX,      EDX

       DIV EBX

       PUSH     DX

       INC CX

       OR  EAX,      EAX

       JNZ LOP1

LOP2:     POP AX

       CMP       AL,  10

       JB   L1

       ADD       AL,  7

L1:  ADD       AL,  30H

       MOV      [SI], AL

       INC SI

       LOOP     LOP2

       POP EDX

       POP CX

       RET

RADIX   ENDP    

CODE     ENDS

       END

NAME    QUEUE

;功能:将一组16位的有或无符号二进制数按从大到小顺序排列后存储在原来的区域,用冒泡排序

;入口参数:

;      SI——从数组存储区取数指针,初值为该存储区首址

;      CX——待排序的数组元素个数

;      BP——有无符号排序的标识(BP=1为有符号数排序)

;所用寄存器:

;      DI——中间寄存器

;      AX——存放待比较数

;      DX——内循环计数器,CX为外循环计数器

PUBLIC  QUEUE

CODE     SEGMENT     USE16    PARA     PUBLIC  'CODE'

       ASSUME       CS:CODE

QUEUE  PROC

       PUSH     AX

       PUSH     DX

       PUSH     DI

       MOV      DI,  SI

       DEC       CX         ;外循环计数器

QU1:      MOV      DX, CX  ;内循环计数器

       MOV      SI,   DI

QU2:      MOV      AX, [SI]

       CMP       BP,  0

       JE   NO

       CMP       AX, [SI+2]     ;如果前一个数大于后一个数,则不交换

       JG   NOXCH

XCH:      XCHG    [SI+2],    AX

       MOV      [SI], AX

NOXCH: ADD       SI,   2

       DEC       DX

       JNE QU2

       LOOP     QU1

       POP DI

       POP DX

       POP AX

       RET

NO: CMP       AX, [SI+2]

       JBE NOXCH

       JMP XCH

QUEUE  ENDP

CODE     ENDS

       END

;      MACRO.LIB

WRITE   MACRO  A

       LEA DX,A

       MOV      AH,9

       INT 21H

       ENDM

CRLF      MACRO

       MOV      AH,2

       MOV      DL,0AH

       INT 21H

       MOV      DL,0DH

       INT 21H

       ENDM

OUT1     MACRO  A

       MOV      DL,A

       MOV      AH,2

       INT 21H

       ENDM

STACK0 MACRO  A

STACK   SEGMENT     USE16    PARA     STACK   'STACK'

DB  A

STACK   ENDS

       ENDM

六、实验步骤

1. 使用编辑程序TXT.EXE录入各个模块代码,存盘文件名分别为MAIN.ASM,F2TN.ASM,F10T2.ASM,QUEUE.ASM。

2. 使用MASM 6.0汇编各个子模块源文件。

3. 观察提示信息,若出错,则用编辑程序修改错误,存盘后重新汇编,直至不再报错为止。

4. 使用连接程序LINK.EXE将汇编生成的多个OBJ文件连接成执行文件。

即LINK MAIN+F10T2+F2TN+QUEUE;

5. 若连接时报错,则依照错误信息修改源程序。之后重新汇编和连接,直至不再报错并生成MAIN.EXE文件。

6. 执行该程序。即在命令行提示符后输入MAIN后回车,观察执行现象。

7. 使用TD.EXE观察MAIN的执行情况。即 TD  MAIN.EXE回车

(1)观察CS、IP、SP、DS、ES、SS的值。

(2)单步执行开始2条指令,观察DATA的实际值,以及DS的改变情况。

(3)观察SS:0至SS:SP区域的数据值。

(4)观察DS:0开始数据区,找到各变量在数据段中的位置和值。

七、实验记录

八、体会

相关推荐