本章主要学习了汇编语言程序如何实现模块化设计和常用的子程序设计规范、模块间调用规范,并简要介绍了Windows下汇编的编程和汇编在C++开发中的直接引用。
1.填空题
(1)根据下列程序,SUB1子过程的属性是 。
CODE1 SEGMENT
……
SUB1 PROC
……
RET
SUB1 ENDP
……
CALL SUB1
……
CODE1 EDNS
……
CODE2 SEGMENT
……
CALL SUB1
……
CODE2 ENDS
(2)Win32 API的核心由 、 、 3个DLL提供。
(3)有如下程序:
DSEG SEGMENT
BUF DB 'This is a character string ! $'
NUM DB 0
DSEG ENDS
SSEG SEGMENT STACK
DB 256 DUP(0)
SSEG ENDS
CSEG SEGMENT
ASSUME DS:DSEG,SS:SSEG,CS:CSEG
START: MOV AX,DSEG
MOV DS,AX
LEA SI,BUF
LP: MOV AL,[SI]
INC SI
CMP AL,'$'
JZ DONE
CMP AL,61H
JNE NEXT
INC NUM
NEXT: JMP LP
DONE: MOV AH,4CH
INT 21H
CSEG ENDS
END START
上面程序中,MOV AL,[SI]和INC SI两条指令可以用一条功能等效的 指令替换。
(4)
DSEG SEGMENT
BUF DB 'This is a character string ! $'
NUM DB 0
DSEG ENDS
SSEG SEGMENT STACK
DB 256 DUP(0)
SSEG ENDS
CSEG SEGMENT
ASSUME DS:DSEG,SS:SSEG,CS:CSEG
START: MOV AX,DSEG
MOV DS,AX
LEA SI,BUF
LP: MOV AL,[SI]
INC SI
CMP AL,'$'
JZ DONE
CMP AL,61H
JNE NEXT
INC NUM
NEXT: JMP LP
DONE: MOV AH,4CH
INT 21H
CSEG ENDS
END START
若将程序中的JZ DONE指令修改为JNZ DONE,则程序执行后,NUM单元中的数据是 。
(5)若定义DATA DB 0A5H,5BH,在指令MOV BX, DATA中填空,使指令能正确执行。
2.选择题
(1)若要调用其他模块中的过程,则对此过程要用 伪操作命令说明。
A.PUBLIC B.EXTRN
C.COMMON D.ASSUME
(2)在80x86汇编语言的段定义伪指令中,下列 定位类型用来指定段的起始地址为任意地址。
A.BYTE B.PARA
C.WORD D.PAGE
(3)为了使程序能够在内存空间浮动,使用无条件转移指令时应选用 。
A.段内直接转移指令 B.段内间接转移指令
C.段间直接转移指令 D.段间间接转移指令
(4)根据下面的数据段定义:
DSEG SEGMENT
A DW 1234H
B DB 56H
C EQU A+1
DSEG ENDS
执行MOV BX,C指令后,BX寄存器中的内容是 。
A.0001H B.1234H C.3456H D.5612H
(5)假设保护方式下Pentium微处理器的(DS)=0103H,则下列哪一种类型的段能被访问 。
A.DPL=00 B.DPL=01 C.DPL=10 D.DPL=11
3.上机操作题
部分程序已给出,其中原始数据由过程LOAD从文件INPUT1.DAT中读入SOURCE开始的内存单元中。运算结果要求从RESULT开始存放,由过程SAVE保存到文件OUTPUT1.DAT中。
在BEGIN和END之间填空使已给出的一段源程序完整(空白已用横线标出,每行空白一般只需一条指令,但采用功能相当的多条指令亦可),或删除BEGIN和END之间原有的代码并自行编程来完成要求的功能。
对程序必须进行汇编,并与IO.OBJ链接产生PROG1.EXE执行文件,最终运行程序产生结果(无结果或结果不正确者均不得分)。调试中若发现整个程序中存在错误之处,请加以修改。
(1)试编制程序,其功能是:内存中连续存放着16个二进制字节数,在原16个数的第4和第5个数之间插入00H,在原16个数的第8和第9个数之间插入55H,在原16个数的第12和第13个数之间插入0AAH,在原16个数最后加入0FFH。将按上述方法插入4个字节数后得到的20个字节数存入内存中。
例如:
内存中有10H,20H,30H,40H,50H,…,8FH(共16个字节),结果为10H,20H,30H,40H,
00H,50H,…,8FH,FFH(共20个字节)。
EXTRN LOAD:FAR,SAVE:FAR
N EQU 16
STAC SEGMENT STACK
DB 128 DUP(?)
STAC ENDS
DATA SEGMENT
SOURCE DB N DUP(?)
INDATA DB 0FFH,0AAH,55H,00H
RESULT DB N+4 DUP(0)
NAME0 DB 'INPUT1.DAT',0
NAME1 DB 'OUTPUT1.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX ; 置附加段寄存器
LEA DX,SOURCE ; 数据区起始地址
LEA SI,NAME0 ; 原始数据文件名
MOV CX,N ; 字节数
CALL LOAD ; 从'INPUT1.DAT'中读取数据
;****BEGIN****
MOV DI,0
MOV CX,4
MOV BX,4
CHAN:
MOV RESULT[DI],AH
INC DI
DEC CX
JZ INSER1
JMP CHAN
INSER1:PUSH SI
MOV SI,BX
MOV AH,INDATA[SI-1]
MOV RESULT[DI],
DEC BX
JZ
MOV CX,04H
INC DI
JMP
EXIT: POP SI
;****END****
LEA DX,RESULT ; 结果数据区首地址
LEA SI,NAME1 ; 结果文件名
MOV CX,N+4 ; 字节数
CALL SAVE ; 保存结果到文件
RET
START ENDP
CODE ENDS
END START
(2)试编制程序,其功能是:内存中连续存放着20个无符号8位二进制数,每个数为摇号机一次摇出的两个号码的压缩BCD码表示。每个号码为1~4之间的数。现统计此20次摇号中两个号码相加值分别为2、3、4、5、6、7、8的次数,将结果存入内存。
例如:
内存中有12H,32H,31H,11H,22H,24H,41H,44H,11H,14H,33H,21H,13H,33H,23H,42H,22H,
34H,43H,11H,结果为03H,02H,04H,04H,04H,02H,01H。
EXTRN LOAD:FAR,SAVE:FAR
N EQU 20
STAC SEGMENTSTACK
DB 128 DUP(?)
STAC ENDS
DATA SEGMENT
SOURCE DB N DUP(?) ; 顺序存放10个字节数
RESULT DB 7 DUP(0) ; 存放结果
NAME0 DB 'INPUT1.DAT',0
NAME1 DB 'OUTPUT1.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
LEA DX,SOURCE ; 数据区起始地址
LEA SI,NAME ; 原始数据文件名
MOV CX,N ; 字节数
CALL LOAD ; 从'INPUT1.DAT'中读取数据
;****BEGIN****
LEA SI,SOURCE
MOV CX,20
AGN0: MOV ,0
MOV AH,[SI]
MOV AL,AH
AND AL,0FH
AND AH,0F0H
PUSH CX
MOV CX,4
AGN1: AH,1
LOOP AGN1
POP CX
ADD AL,
ADD ,
ADC BH,0
BX,2
INC SI
NEXT: LOOP AGN0
;****END****
LEA DX,RESULT ; 结果数据区首地址
LEA SI,NAME1 ; 结果文件名
MOV CX,7 ; 字节数
CALL SAVE ; 保存结果到文件
RET
START ENDP
CODE ENDS
END START
(3)试编制程序,其功能是:内存中连续存放着两个有符号字节数序列AK和BK(K=0,…,9),求序列CK,CK=AK×BK(CK以有符号字的形式按C0,…,C9的顺序连续存放)。
例如:
序列AK为80H,C0H,81H,00H,…,序列BK为80H,C0H,81H,7FH,…,则结果CK为4000H,1000H,3F01FH,0000H,…。
EXTRN LOAD:FAR,SAVE:FAR
N EQU 10
STAC SEGMENT STACK
DB 128 DUP(?)
STAC ENDS
DATA SEGMENT
SOURCE DB N*2 DUP(?)
RESULT DW N DUP(0)
NAME0 DB 'INPUT1.DAT',0
NAME1 DB 'OUTPUT1.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
LEA DX,SOURCE ; 数据区起始地址
LEA SI,NAME0 ; 原始数据文件名
MOV CX,N*2 ; 字节数
CALL LOAD ; 从'INPUT1.DAT'中读取数据
;****BEGIN****
MOV DI,
MOV CX,N
PRO: MOV AL,
SOURCE[BX]
MOV [DI],AX
ADD
INC BX
JNZ PRO
;****END****
LEA DX,RESULT ; 结果数据区首地址
LEA SI,NAME1 ; 结果文件名
MOV CX,N*2 ; 字节数
CALL SAVE ; 保存结果到文件
RET
START ENDP
CODE ENDS
END START