汇编语言程序设计(第二版)答案 高等教育出版社 下载本文

第四章

4.1、判断下列标识符的合法性。 1)、code 合法 2)、Data 合法 3)、ABCDH 合法

4)、1abcH 不 5)、eax 不

6)、???01 合法 7)、A?@ 合法

8)、www@zsu 合法

9)、www@zsu.edu.cn 不 10)、AX$DX 合法 11)、_BX 合法 12)、CX 不

4.2、按下面要求写出相应的数据定义语句(未指定变量名的,可任意指定或省缺)。 1)、定义一个字节区域,第一个字节的值为20,其后跟20个初值为0的连续字节; DB 20,20 DUP(0)

2)、定义一个以0为结束符的字符串,其初值为:The course is easy; DB “The course is easy”,0

3)、定义一个以'$'为结束符的字符串,该串中含有换行符和回车符; DB 0D,0A,”$”

4)、定义100个字,其初值为0;

DW 100 DUP(0)

5)、从一个偶地址开始定义一个字变量word; EVEN WORD DW ?

6)、先定义一个字符串String,其偏移量指定为10,其初值为\,然后再定义3个字类型的数组Data,要求String和Data的偏移量相同;

ORG 10

STRING DB \ORG 10

DATA DW 3 DUP(?)

7)、定义一个字符串String,其初值为\,再定义4个字类型的数组Data,要求String和Data共享同一片内存单元; STRING DB \ORG $-8

DATA DW 4 DUP (?)

4.3、把下列C语言的变量定义语句改写成与之等价的汇编语言语句。 1)、char ch1, ch2[3], ch3[]=\CH1 DB ?

CH2 DB 3 DUP (?)

CH3 DB \

CH4 DB “Q”

2)、int w1, w2[5], w3=0x1234, w4[]={90, 89, 432, 344}; W1 DW ?

W2 DW 5 DUP (?) W3 DW 1234H

W4 DW 90,89,432,344

3)、long int d1=1234, d2, d3[10], d4[]={1, 2, 3, 4, 5, 6}; D1 DD 1234 D2 DD ?

D3 DD 10 DUP(?)

D3 DD 1,2,3,4,5,6

4.4、假设4.3题中三组变量在内存中是连续存放的,且变量ch1的偏移量是20H,试求出其它每个变量的偏移量。 变量 Ch1 Ch2 Ch3 Ch4

4.5、按下列要求分别写出汇编语言的结构定义,如果没有说明结构分量的类型,请根据日常习惯自行指定其数据类型(可使用已有的结构定义)。

1)、定义日期结构类型Date,其包括:Year(年)、Month(月)和Day(日); DATA STRUC 偏移量 YEAR DB ? 0 MONTH DB ? 1 DAY DB ? 2 DATA ENDS

2)、定义时间结构类型Time,其包括:Hour(小时)、Minute(分)、Second(秒)和centsec(百分之一秒); TIME STRUC

HOUR DB ? 0 MINUTE DB ? 1 SECOND DB ? 2 CENTSEC DB ? 3 TIME ENDS

3)、定义结构Peason,其包括:name(姓名,字符,长度为8)、Birth(出生日期,Date),stature(身高,以厘米为单位的整数),Address(地址,30个字符)

偏移量 20H 21H 24H 33H 变量 W1 W2 W3 W4 偏移量 34H 36H 40H 42H 变量 D1 D2 D3 D4 偏移量 4AH 4EH 52H 7AH PERSON STRUC

NAME DB 8 DUP(?) 0 BIRTH DATA < > 8 STATURE DB ? 0BH ADDRESS DB 30 DUP (?) 0CH PERSON ENDS

4.6、试求出4.5题各结构中字段的偏移量。

4.7、把下列C语言的结构或结构变量的定义改写为与之等价的汇编语言定义语句。

1)、struct ScreenBuffer {

char c1; //字符

char attr; //字符属性 } Buffer[2000]; ScreenBuffer struc

C1 DB ? ATTR DB ?

ScreenBuffer ENDS

BUFFER ScreenBuffer 2000 DUP(< >) 2)、struct FILE {

int level, flags; char fd, hold;

int bsize, istemp, token; };

3)、struct CELLREC { char attrib;

union {char text[201]; long value;

struct {long fvalue;

char formula[201]; } f; } v;

}; 答:

STRUC_F STRUC FVALUE DD ?

FORMULA DB 201 DUP(?) STRUC_F ENDS UNION_V UNION

TEXT DB 201 DUP(?) VALUE DD ? F STRUC_F< > UNION_V ENDS CELLREC STRUC ATTRIB DB ? V UNION_V< > CELLREC ENDS

4.8、按下列要求分别写出汇编语言的记录定义。

1)、定义标志位寄存器低8位标志位,其相应位用其标志位的符号来命名,未用部分的命名自行确定;

FLAGS RECORD SF:1,ZF:1,EMPTY1:1, EMPTY2:1,PF:1, EMPTY3:1,CF:1 2)、定义一个压缩型的BCD码类型;

3)、把一个字节分成三部分:0~2位、3~5位和6~7位,每部分可独立存取,它们的初值分别为4,5和2;

4)、把一个字分割成:0~1位、2~6位、7~12位,其中第一部分的初值位3,第三部分的初值为25。

4.9、试求出4.8题各记录中字段的宽度和屏蔽属性值。

4.10、假设变量B1的偏移量为12H,试求出它们的属性OFFSET、TYPE、LENGTH和SIZE的值。

B1 W1 D1 P1 U1 B1 W1 D1 P1 U1

4.11、试用三种方法定义字节变量(或字段名)B1和字变量(或字段名)W1,它们共享20个存储单元。 1.U1 UNION

B1 DB 20 DUP (?) W1 DW 10 DUP (?) U1 ENDS

2. W1 EQU THIS WORD B1 DB 20 DUP (?) 3. B1 DB 20 DUP (?) ORG $-20

W1 DW 10 DUP (?)

4.12、强制属性操作符会改变变量的定义属性吗?在C语言中存在类似功能的语句吗?若存在,请举例说明。

DB \DW 10 DUP(1, 2), 1234 DD 20 DUP(0),

PEASON <>, <> ;结构PEASON的定义见4.4.2

UNION1 3 DUP(<>) ;联合UNION1的定义见4.4.3

OFFSET 12H 33H 5DH 0ADH 0CBH TYPE 1 2 4 15 2 LENGTH 1 10 20 1 3 SIZE 1 20 80 15 6 4.13、假设有题4.10题中的变量定义,试写出符合要求的地址表达式。

1)、取从B1开始的字母'p'和第一个'm'; [b1+4],[b1+10]

2)、访问从W1开始的第3个字单元(从序数1开始计数,第1、第2、??)的值为2的存储单元; [w1+10]

3)、访问从D1开始的第10个双字单元; [d1+36]

4)、访问从P1开始的第2个结构中的字段NO; [p1+15]

5)、访问从U1开始的第3个联合中的字段WW; [u1+4]

4.14、把下列C语言程序中的说明性语句改写成等价的汇编语言语句。

#define N 200 struct buffer {

char len1, len2, buff[N]; } buff;

int Data[N]; N EQU 200 BUFFER STRUCT LEN1 DB ? LEN2 DB ? BUFF DB N DUP(?) BUFFER ENDS BUFF BUFFER < >

DATA DW N DUP (?)

4.15、简述数值表达式与地址表达式的主要区别。 4.16、计算下列各数值表达式的值。

1)、12H AND 78H 0010H

2)、1234 MOD 3 + 23H 0024H

3)、5467H XOR 12FFH 4698H

4)、'A' OR 20H 0061H

5)、10 LT 9 0

6)、4567 / 13 + 10H 016FH

7)、1234H+89H SHL 1 1346H

8)、8910H SHR 2 AND 506H 0004H

5.3 习题

5.1、书写正确的MOV指令,需要符合哪些规定?在32位CPU中,增加了什么指令来克

服不同数据类型之间的数据传送? 5.2、简述指令MOV BX, 1234H、MOV BX, [1234]和MOV BX, offset [1234H]的功能和它们之间区别。

MOV BX, 1234H将通用寄存器BX的当前值设为1234H

MOV BX, [1234]取出内存地址1234H的当前值赋予通用寄存器BX

MOV BX, offset [1234H] 取出内存地址1234H的偏移量,而地址【1234H】的偏移量就是1234H

5.3、简述指令MOV BX, Data和MOV BX, offset Data之间的区别。 MOV BX, Data将DATA的值赋予通用寄存器BX

MOV BX, offset Data将data的偏移地址赋予通用寄存器BX

5.4、选择指令实现下列要求,OPN1 ← OPN2的含义:把操作数OPN2的值传送给OPN1。

1)、EBX ← EDX MOV EBX,EDX

2)、BX ← CL MOVSX BX,CL 3)、SI ← BX 4)、DS ← AX 5)、AL ← BH 6)、AL ← 12H 7)、AX ← 13AH

8)、CX ← 0CDH 9)、SI ← 1000H

(假设0CDH为无符号数) 10)、EBX ← 1200A2H

5.5、PUSHA指令能把哪些寄存器压栈?它们进栈的顺序是什么?可用什么指令把这些寄存器依次弹出堆栈?POPA

5.6、PUSHAD指令完成什么操作?它与什么操作的作用相反?

5.7、在16位/32位CPU中,标志位寄存器的内容进栈和出栈的指令是什么?

5.8、写出下列指令序列中每条指令的执行结果,请在Debug环境下验证之,并注意各标志位的变化情况。 MOV BX, 23ABH ADD BL, 0ACH MOV AX, 23F5H ADD BH, AL SBB BX, AX ADC AX, 12H SUB BH, -9

5.9、假定DS=1123H,SS=1400H,BX=0200H,BP=1050H,DI=0400H,SI=0500H,LIST的

偏移量为250H,试确定下面各指令访问内存单元的地址。 1)、MOV AL, [1234H] 1234H

2)、MOV AX, [BX] 0200H

3)、MOV [DI], AL 0400H

4)、MOV [2000H], AL 2000H

5)、MOV AL, [BP+DI] 1450H

6)、MOV CX, [DI] 0400H

7)、MOV EDX, [BP] 1050H

8)、MOV LIST[SI], EDX 0750H

9)、MOV CL, LIST[BX+SI] 0950H

10)、MOV CH, [BX+SI] 0700H

11)、MOV EAX, [BP+200H] 1250H

12)、MOV AL, [BP+SI+200H] 1750H

13)、MOV AL, [SI-0100H] 0400H

14)、MOV BX, [BX+4] 0204H

5.10、用一条指令实现把BX和SI之和传送给CX。 CX,[BX+SI] LEA CX,[BX+SI]

5.11、试比较下列三组指令的功能。

1)、LDS SI, [DI]

相当于MOV SI,[DI] MOV DS,[DI+2]

2)、MOV SI, [DI] 3)、MOV DS, [DI+2] 改变了DS的值,因此随后执行 MOV DS, [DI+2] MOV SI, [DI]

功能与1同

5.12、标志位CF有着重要的作用,请简述之,并至少写出三种把CF置0的方法。 CLC XOR AX,AX SUB AX,AX

5.13、写一个计算DL三次方的指令序列,假设幂不超过16位二进制。 MOV AL,DL

MUL DL ;(AX)乘积 MOV BX,AX MOV AL,DL

CBW ;(AX)扩展值 MUL BX

计算结果放在AX中

5.14、写出一个指令序列实现:用CL中数据除BL中的数据,然后商乘2,最后的结果存入DX中。 MOV AL,BL

CBW ;(AX) DIV CL ;商(AL) CBW SHL AX,1 MOV DX,AX

5.15、按下列要求编写指令序列。

1)、清除DH中的最低三位而不改变其它位,结果存入BH中; AND DH,0F8H

MOV BH,DH

2)、把DI中的最高5位置1而不改变其它位;

OR DI,0F800H

3)、把AX中的0~3位置1,7~9位取反,13~15位置0; OR AX,000FH XOR AX,0380H AND AX,1FFFH

4)、检查BX中的第2、5和9位中是否有一位为1; AND BX,0224H ;如BX!=0,则至少1位为1 5)、检查CX中的第1、6和11位中是否同时为1; AND CX,0842H XOR CX,0842H

6)、检查AX中的第0、2、9和13位中是否有一位为0; OR AX,0DDFA

如AX!=0FFFFH则至少一位为0

7)、检查DX中的第1、4、11和14位中是否同时为0; AND DX,4812H

如果DX为0,说明同时为0

5.16、简述指令AND和TEST、NOT和NEG之间的区别。

5.17、选择适当的指令实现下列功能。

1)、右移DI三位,并把零移入最高位; MOV CL,3

SHR DI,CL

2)、把AL左移一位,使0移入最低一位; SHL AL,1

3)、AL循环左移三位; MOV CL,3

ROL AL,CL

4)、EDX带进位位循环右移四位;

RCR EDX,4

5)、DX右移六位,且移位前后的正负性质不变。 SAR DX,CL

5.18、判断下列指令的正确性,若某指令是错误的,请说明其错误原因。 1)、MOV BL, CX 2)、MOV DS, SS

3)、MOV [BX], [DI] 4)、MOV AL, [BX][SI] 5)、MOV ES, AL 6)、MOV DS, DX 7)、MOV CS, AX 8)、MOV BX, CS 9)、MOV DS, 1230H

10)、MOVSX DS, AL 11)、XCHG BX, 3 12)、POP CS

13)、MOV IP, SI 14)、PUSH CS 15)、PUSH BL

16)、MOV [SP], BX 17)、MOV AX, BX+3 18)、MOV AX, [BX+3] 19)、MOV BX, [BX] 20)、MOV BH, [BL] 21)、XCHG ES, AX 22)、LEA AX, [BX+SI] 23)、MUL 10H

24)、IMUL DX, 10H 25)、DIV 10

26)、IDIV DX, 10H 27)、SHL AX, CX 28)、SHR BX, CH 29)、ROL BX, 20 30)、RCR AX, CL 31)、CMP AX,1234H 32)、CMP 12H, CL 33)、JCXZ next

34)、JEBXZ next (假设标号next已存在)

5.19、方向标志DF的作用是什么?用于设置或消除该标志位的指令是什么? 5.20、串指令用DI和SI寻址哪些内存段中的内存数据?

串操作指令用DI寻址ES段的内存数据,用SI寻址DS 段的内存数据 5.21、段间转移和段内转移之间的区别是什么?

5.22、SCASB指令的作用是什么?叙述指令REPE SCASB指令所完成的功能。 5.23、指令REPNE SCASB结束执行的条件是什么?

5.24、REP前缀的作用是什么?能用指令REP LODSB读取DS:SI所指内存中的每个字符来

进行处理吗?若不能,请说明原因。 5.25、编写指令序列,在字符串LIST中查寻字符'B',若找到,则转向Found,否则,转

向NotFound,假设该字符串含有300个字符。 CLD

MOV AX,SEG LIST MOV ES,AX LEA DI,LIST MOV CX,300 MOV AL,42H REPNZ SCASB JZ FOUND JMP NOTFOUND

5.26、编写指令序列,把Source存储区域中的12个字节传送到Dest存储区域内。 CLD

MOV AX,SEG SOURCE MOV DS,AX LEA SI,SOURCE MOV AX,SEG DEST MOV ES,AX LEA DI,DEST MOV CX,12 REP MOVSB

5.27、设计一个短指令序列,将32位数AX:BX中的8位BCD与CX:DX中的8位BCD相加,并把所得结果存入CX:DX中。 1. 2. 3. 4. 5. 6. 7.

PUSH AX MOV AX,BX ADD AL,DL DAA

MOV DL,AL MOV AL,BH ADC AL,DH

8. DAA

9. MOV DH,AL 10. POP AX 11. ADC AL,CL 12. DAA

13. MOV CL,AL 14. MOV AL,AH 15. ADC AL,CH 16. DAA

17. MOV CH,AL

5.28、有符号数比较后,用什么样的条件转移指令实现转移?无符号数比较后,用什么样的条件转移指令实现转移? 6.6 习题

6.1、简述ASSUME伪指令的作用,用该语句说明的段寄存器不用对其赋段地址的初值?

6.2、用二种定义方法堆栈段,并给出相应的初始化语句或说明。

6.3、把下列C语句的语句改写成功能相同的汇编语言程序片段(其中:变量都为整型变量)。

1)、h = (key & 0XFF00) >> 8; KEY DW ? H DW ? MOV AX,KEY AND AX,0FF00H MOV CL,8 SAR AX,CL

MOV H,AX

2)、k = (k + '1' – 0xabcd) / 56; K DW ? MOV AX,K ADD AX,0031H SUB AX,0ABCDH

NEXT1:

CWD MOV BX,56 IDIV BX MOV K,AX

3)、for (i = s = 0; i < 100; i++) s += data[i] * 2; I DW ? S DW ?

DATA DW 100 DUP(?) MOV S,0 MOV I,0 MOV SI,I MOV BX,I MOV AX,S

CMP SI,100 JGE NEXT2 MOV BX,DATA[BX] SAL BX,1 ADD AX,BX INC SI ADD BX,2 JMP NEXT1 NEXT2:MOV S,AX

4)、for (s = 0, i = 100; i > 0; i--) s += i * 2;

6.4、把下列C语言的语句改写成等价的汇编语言程序段(不考虑运算过程中的溢出)。

If (a<1 || b/4 > 10 && c%8==5) { a = 20+b++; c <<= 2; }

else {a = 21-(++c); b--; }

其中:变量a、b和c都是有符号的整型(int)变量。 A DW ? B DW ? C DW ? ? MOV BX,B MOV CL,2 SAR BX,CL MOV CX,C AND CX,0007H CMP BX,10 JBE NEXT1 CMP CX,5 JNE NEXT1

NEXT2:

MOV BX,B MOV AX,20

ADD AX,BX MOV A,AX INC BX MOV B,BX MOV CX,C SAL CX,1 SAL CX,1 MOV C,CX JMP NEXT3

NEXT1:

MOV AX,A CMP AX,1 JB NEXT2 MOV CX,C INC CX MOV C,CX MOV AX,21 SUB AX,CX MOV A,AX MOV BX,B DEC BX MOV B,BX

NEXT3:

6.5、假设内存单元中有三个字a、b和c,编写一个程序,它可判断它们能否构成一个三

角形,若能,CF为1,否则,CF为0。 判断三边是否能构成一个三角形的原则是:任意一边的变长都不得大于另外两边的边长之

和。对应 c 语言语句如下: IF((A+B)>C&&(A+C)>B&&(B+C)>A){ //能构成三角形 } ELSE{

//不能构成三角形 }

6.6、假设有三个无符号字存放在以Buffer为开始的缓冲区中,编写一个程序把它们从低到高排序好。 BUFFER DW 3 DUP (?) MOV AX,BUFFER MOV BX,BUFFER[2] MOV CX,BUFFER[4] CMP AX,BX JBE NEXT1 XCHG AX,BX NEXT1: CMP BX,CX JBE NEXT3 XCHG BX,CX NEXT2: CMP AX,BX

JBE NEXT3 XCHG AX,BX NEXT3: MOV BUFFER,AX MOV BUFFER[2],BX MOV BUFFER[4],CX

6.7、编写一个程序,它把一位十六进制数转化成相应的数字字符或大写字母。 答:假设这个十六进制数存储在寄存器AL中,该数的值必须小于0X10.该数被转换后输出到寄存器BL 中。 MOV BL,AL AND BL,0FH CMP BL,0AH JB NEXT1 ADD B1,7H NEXT1: ADD B1,30H

6.8、编写一个程序,它把一个合法的十六字符转化成相应的数值。

答:这个字符必须是‘0’-‘9’,’A’-‘F’,’a’-‘f’中的某一个,否则它就不是合法的十六进制字符。

假设该字符放在al中,并且已经通过了合法判断。 该字符被转换后输出结果将存放在bl中。 MOV BL,AL CMP BL,’a’ JB NEXT1

6.9、编写一个程序,它可统计32数DX:AX中二进制位是1的位数。 6.10、编写一个程序,它把CH和CL中的二进制位依次交叉存入AX中。

6.11、编写一个程序,求出从内存单元1000:0000开始的1024个字的32位累加和,并

把该值存入程序中的变量Data中。 6.12、假设从变量Buff开始存放了200个字,编写一个程序统计出其正数、0和负数的

个数,并把它们分别存入N1、N2和N3中。 6.13、用双重循环把下三角乘法表存入从product开始的45个字节中。 6.14、表示源程序结束的伪指令是什么?在其后所编写的指令在被汇编吗? 答:END.在其后编写的任何内容都不会被汇编程序处理。

6.15、汇编语言程序一定会从代码段的第一条指令开始执行吗?如果不是,如何指定程序的入口地址?

汇编语言程序可以不从代码段的第一条指令开始执行。

在伪指令END后面可以附带一个在程序中已经定义的标号,该标号指明程序的入口地址。 6.16、编写一个程序,它把字符串String两端的空格删除(字符串以0结束)。 6.17、编写一个程序,它把字符串String中的数字字符删除掉(字符串以0结束)。 6.18、编写一个程序,它把AX的值以二进制字符串的形式存放在以buff开始的缓冲区中。

6.19、假设有一个以Data为首地址的字缓冲区,其缓冲区的大小在第一个字中,试编写

一个程序,求出该缓冲区数值的最大值和最小值,并分别存入DI和SI中。 6.20、编写一个程序片段,把32位数DX:AX向左移六位。

第七章

7.1、汇编语言的子程序是如何定义的?所使用的关键字有哪些?

7.2、为了编写具有良好风格的子程序,一般需要书写哪些重要的说明性信息? 7.3、简述调用指令CALL和转移指令JMP之间的主要区别。

答:call指令是一种特殊的转移操作。当调用一个子程序时,程序的执行顺序被改变,CPU将转而执行子程序的指令序列,在这方面,CALL指令含有转移指令的功能。

JMP转移指令是一种“一去不复返”的操作,而当子程序执行结束后,还要求CPU能转而执行CALL指令后续的指令,它是一种“有去有回”的操作。 7.4、简述段内和段间子程序调用指令CALL的主要区别。

答:子程序的调用指令分为近(near)调用和远(far)调查。近调用即段内子程序调用,远调用即段间子程序调用。

如果被调用子程序的属性是近的,那么,CALL指令将产生一个近调用,它把该指令之后地址的偏移量(用一个来表示)压栈,把被调用子程序入口地址的偏移量送给指令指针寄存器IP即可实现执行程序的转移。

如果被调用子程序的属性是远的,那么,CALL指令将产生一个远调用。这时,调用指令不仅要把该指令之后地址的偏移量压进栈,而且也要把段寄存器CS的值压进栈。在些之后,再把被调用子程序入口地址的偏移量和段值分别送给IP和CS,这样完成了子程序的远调用操作。

7.5、子程序返回指令RET的功能能否用JMP指令来模拟,若可以,请用段内子程序的返

回加以说明,否则,说明理由。 可以

以段内子程序的返回为例 POP AX JMP AX

7.6、子程序返回指令“RET 6”的功能是返回数值“6”给调用程序吗?若不是,那其作用是什么?

表示在得到返回地址之后,SP的值还要另外加6

7.7、在子程序中要使其所用寄存器对调用者是透明的,请举例说明达到其目的的方法。 SAMPLE PROC ?

MOV AX,100 ? POP AX

PUSH AX

RET SAMPLE ENDP

7.8、编写子程序实现下列功能,参数的传递方式可自行决定(假设所有变量都是字类型)。

1)、ABS(x)=|x|

2)、f(x)=3x2 + 5x – 8

3)、strlen(String) //返回字符串String的长度,该字符串以0结束 4)、判断三条边a、b和c能否构成三角形,若能,CF为1,否则,CF为0 7.9、编写计算将CX值三次方的子程序,结果也存入CX(不考虑溢出问题)。 7.10、编写计算表达式AX=DI×SI/100H的子程序(不考虑溢出问题)。

7.11、编写计算EAX=EAX+EBX+ECX+EDX的子程序。在计算过程中,若产生进位,则EDI=1,否则,EDI=0。

7.12、在MASM 6.x编程环境下,简述子程序定义中USE说明语句的作用是什么? 7.13、调用子程序指令CALL和调用伪指令INVOKE的主要区别是什么?

7.14、在子程序的完全定义形式中,其语言类型所起的作用是什么?可用哪二种方法来设定子程序的语言类型?

7.15、如何指定子程序的传递参数是动态的,对动态参数有哪些规定?

7.16、编写一个子程序,其功能是把其所有参数数值之和存入AX中,每个参数都数16位二进制数,但个数不定。

7.17、子程序的参数传递有传值和传地址之分,在汇编语言中,如何实现传地址?请举例说明。

7.18、在高级语言中,子程序可定义其局部变量,在汇编语言中,能定义其局部变量吗?若能,请举例说明。

7.19、使用.REPEAT和.UNTIL语句编写一个子程序,其功能是从DS:SI开始的内存单元

中查找是否有与AL相同的数值。若找不到,CF=0,否则,CF=1,且SI指向所找到位置。假设查找区域以0为结束标志。 7.20、用.REPEAT和.UNTILCXZ语句编写一个子程序,用以在内存缓冲区中填入00H。内

存缓冲区的首址及长度分别由DS:SI和CX来确定。 7.21、用.WHILE和.ENDW语句实现7.16和7.17的功能。 7.22、在程序模块中,伪指令PUBLIC和EXTRN的作用是什么?

7.23、在C语言程序中,存在关键字EXTERN,它与汇编语言中EXTRN的作用相似吗? 7.24、如何创建和维护自己的子程序库?使用子程序库有何好处? 8.4 习题

8.1、简述中断和子程序调用之间的主要区别? 8.2、为什么要区分IRET指令与RET指令?

8.3、编写一个子程序,它可显示以0结尾的字符串。子程序的入口参数DS:DX为待输出字符串的首地址。

8.4、编写一个子程序,用来读入一个键,并在屏幕上按十六进制的形式显示按键的扩展

ASCII码,如果按键为普通字符,则不显示。 8.5、编写一个程序,在屏幕的右下角闪烁显示编程者自己的姓名,显示颜色自定。 8.6、编写一个把屏幕上显示的字母经过大小写转换后再显示的程序。 8.7、编写一个程序,它把屏幕上的数字改位蓝绿色背景的红字。 8.8、编写一个控制光标位置和形状的程序,该程序具有以下功能:

1)、可用光标移动键↑、↓、←和→来移动光标;

2)、当光标已在第0列,且按'←'键时,光标定在上一行的最后一列;若已在屏幕

的左上角,则光标不动,且给出响铃;按'→'键时的边界处理类似; 3)、当光标在第0行,且按'↑'键时,则光标不动,且给出响铃;按'↓'键时的边界处理类似;

4)、按Home或End键,则光标移到当前行的行首或行尾;

5)、若按下数字或字母键,则把该字符从当前位置依次显示到屏幕顶(在新位置显示

字符时,原位置的符号被抹去); 6)、按Esc键,程序结束。

8.9、交换例8.5和8.6的画线方法,编写相应的子程序VLine和HLine,并验证之。 8.10、假设显示器的显示模式设定为12H,编写实现下列功能的程序:

1)、在屏幕中间从上到下显示一条明亮的蓝色线,线宽为1个像素; 2)、在屏幕底下横向画一条绿色线,线宽为2个像素;

3)、在屏幕上垂直显示16种颜色,每种颜色宽40个像素;

4)、设定屏幕背景为白色,在屏幕中间画一条青色线,线宽为10个像素。 8.11、对于256色,320X200的显示模式需要多少个字节的内存存放一屏信息? 8.12、为什么在显示数据时必须关闭鼠标?

8.13、编写程序,检测计算机是否已安装了鼠标,并以显示Yes/No来表示检测结果。 8.14、编写程序,显示鼠标的按键,若按左键,显示\,若按右键,显示\,按Esc键,程序结束。

8.15、编写一个程序,在图形模式下,打开鼠标,并显示鼠标的位置。

8.16、编写一个程序,显示驱动器C根目录下所有EXE文件。提示:用通配符\来

查找与此匹配的文件名,找到后,显示之。 8.17、编写一个程序,显示驱动器C根目录下的所有子目录。 8.18、编写一个程序,设置指定目录下的所有文件为只读文件。 8.19、编写一个程序,创建一个隐含文件Data.TXT。

8.20、编写一个程序,把键盘上输入写入文件File.dat中,类似以下DOS命令:

COPY con File.dat

8.21、使用哪个DOS功能可读取中断向量地址,哪个DOS功能可把新的中断服务程序地

址设置为指定中断的入口地址。 8.22、编写一个程序,在程序开始运行时,把中断向量表保存到程序的数据段中,在程序

结束前把数据段中的备份恢复到系统中去。 8.23、把下列C语言的子程序改写成汇编语言子程序。

1)、取当前光标的位置,并分别存入变量x和y中

get_cursor(int *x, int *y)

{union REGS in, out;

in.h.ah = 3; in.h.bh = 0; int86(0x10, &in, &out);

*x = out.h.dh; *y = out.h.dl; } 2)、把光标设置在(row, col)位置

locate(int row, int col)

{union REGS in, out;

in.h.ah = 2; in.h.bh = 0; in.h.dh = row; in.h.dl = col; int86(0x10, &in, &out); } 3)、在(row, col)位置显示字符串string disp_string(int row, int col, char string[]) {struct REGPACK in, out; int x, y;

get_cursor(&x, &y); locate(row, col);

in.r_ds = FP_SEG(string); in.r_dx = FP_OFF(string); in.r_ax = 0x900; intr(0x21, &in); locate(x, y); }