第10章 应用程序的设计
在前面各章节中,我们侧重介绍了汇编语言程序设计中各组成部分的作用,本章的重点是对前面所学知识的综合运用。希望通过各种不同类型的例子,使读者能够掌握用汇编语言编程的基本技巧。
10.1 字符串的处理程序
字符或字符串是一类重要的非数值计算的处理对象。许多编辑软件都具有字符串查找、替换、大小写的转换、单词的自动识别等功能,网络上的信息搜索也是现在一种常用的功能等,这些功能的实现无疑都要涉及到字符串的处理功能。
为了方便对字符串 的处理,各种常用的编程环境也都给予了足够的支持。如:C语言编程环境提供了大量处理字符串的标准函数,象strlen、strcmp和strcpy等函 数;C 、VC或VB等编程环境提供了字符串类String等。这些函数或类大大方便了程序员的编程。
在计算机系统内,为了加快字符串的处理,在其指令系统中设置了多条处理字符串的指令,其详细内容请参阅第5.2.11节中的介绍。
下面我们将通过几个例子来学习汇编语言处理字符串的方法。
例10.1 编写一个求字符串长度的子程序Strlen,要求字符串的首地址为入口参数,且以ASCII码0为结束符,CX为出口参数,其存放该字符串的长度。
解: |
|||
|
.MODEL SMALL, C |
||
.DATA |
|||
buff |
DB "This is a example.", 0 |
||
.CODE |
|||
Strlen |
PROC USES AX BX, String:PTR BYTE |
||
MOV |
BX, String |
||
XOR |
CX, CX |
||
MOV |
AL, [BX] |
||
.WHILE AL!=0 |
|||
INC |
CX |
||
INC |
BX |
||
MOV |
AL, [BX] |
||
.ENDW |
|||
RET |
|||
Strlen |
ENDP |
||
.STARTUP |
|||
INVOKE Strlen, ADDR buff |
|||
.EXIT 0 |
|||
END |
例10.2 编写一个把字符串中的所有小写字符转换成大写字符的子程序Strupr,要求字符串的首地址和结束符为其入口参数。
解: |
|||
|
.MODEL SMALL, C |
||
.DATA |
|||
buff |
DB "This is a example.", 0 |
||
.CODE |
|||
Strupr |
PROC USES AX BX, String:PTR BYTE, Tail:BYTE |
||
MOV |
BX, String |
||
.REPEAT |
|||
MOV |
AL, [BX] |
||
.IF AL>='a' && AL<='z' |
|||
SUB |
AL, 20H |
||
MOV |
[BX], AL |
||
.ENDIF |
|||
INC |
BX |
||
.UNTIL |
AL==Tail |
||
RET |
|||
Strupr |
ENDP |
||
.STARTUP |
|||
INVOKE Strupr, ADDR buff, 0 |
|||
.EXIT 0 |
|||
END |
例10.3 编写一个从字符串中拷贝子串的子程序Strncpy,它有四个参数str1、str2、idx和num,其具体功能为把字符串str2中从第idx个(从 0开始记数)字符开始、num个字符传送给str1,字符串str1和str2都是以ASCII码0为结束符。
解: |
||||
|
.MODEL |
SMALL, C |
||
.DATA |
||||
str1 |
DB "12345ABCDEF", 0 |
|||
str2 |
DB 20 DUP('A') |
|||
.CODE |
||||
Strlen |
PROC USES AX BX, String:PTR BYTE |
|||
…… |
;参见例10.1 |
|||
Strlen |
ENDP |
|||
Strncpy |
PROC USES AX CX DI SI DS ES, str1:FAR PTR BYTE, str2:FAR PTR BYTE, idx:WORD, num:WORD |
|||
LES |
DI, str1 |
|||
LDS |
SI, str2 |
;取两个字符串的首地址 |
||
INVOKE |
Strlen, SI |
;计算源字符串的长度,在CX中 |
||
MOV |
AX, idx |
|||
.IF AX >= CX |
;若字符起点就超过源串的长度 |
|||
MOV |
BYTE PTR ES:[DI], 0 |
;拷贝的字符串为“空” |
||
JMP |
over |
|||
.ENDIF |
||||
ADD |
SI, AX |
;定源串中字符的起点SI |
||
MOV |
CX, num |
|||
CLD |
||||
.REPEAT |
||||
LODSB |
||||
STOSB |
||||
.UNTILCXZ AL==0 |
||||
.IF AL!=0 |
;设置目标串的结束符 |
|||
MOV |
BYTE PTR[DI], 0 |
|||
.ENDIF |
||||
over: |
RET |
|||
Strncpy |
ENDP |
|||
.STARTUP |
||||
INVOKE |
Strncpy, ADDR str2, ADDR str1, 3, 5 |
|||
.EXIT |
0 |
|||
END |
例10.4 编写一个把字符串中空格和TAB压缩掉的子程序Compress,字符串String是以ASCII码0为结束符。
解: |
|||||
|
.MODEL |
SMALL, C |
|||
.DATA |
|||||
SPACE |
EQU 20H |
||||
TAB |
EQU 9H |
||||
Buff |
DB "12 3 4 Ab cdef", 0 |
||||
.CODE |
|||||
Compress |
PROC USES AX BX SI DS, String:FAR PTR BYTE |
||||
LDS |
SI, String |
;SI用于扫描字符串的指针 |
|||
MOV |
BX, SI |
;BX用于存放结果的指针 |
|||
.REPEAT |
|||||
MOV |
AL, [SI] |
||||
INC |
SI |
||||
.IF AL!=SPACE && AL!=TAB |
|||||
|
MOV |
[BX], AL |
|||
INC |
BX |
|
|||
.ENDIF |
|||||
.UNTIL AL==0 |
|||||
RET |
|||||
Compress |
ENDP |
||||
.STARTUP |
|||||
INVOKE Compress, ADDR Buff |
|||||
.EXIT |
0 |
||||
END |
从上面四个例子,我们不难看出处理字符串的一般方法,感兴趣的读者可自行编写实现字符串变小写、整体拷贝、逆转和查找等功能的子程序,甚至还可以建立起自己的字符串处理库文件。