前言
在计算机编程的世界中,处理字符是一项常见而又关键的任务。字符处理不仅仅是涉及到文本的大小写转换,还包括了字符的过滤、编码的转换以及其他一系列操作。在底层编程语言中,如汇编语言,我们能够直接操纵内存中的字符数据,通过一系列的指令来实现各种字符处理任务。
本文将深入探讨一个8086汇编程序,通过该程序我们将学习如何处理字符串中的字符。具体而言,我们将看到如何将字符串中的小写字母转换为大写,并将大写字母转换为小写。通过这个例子,我们将理解如何使用汇编语言中的一些基本指令来完成字符级别的操作,以及如何利用寄存器和循环结构来实现这些操作。
一、处理字符问题
1.1 汇编语言如何处理字符
汇编程序中,用 ‘……’ 的方式指明数据是以字符的形式给出的,编译器将
把它们转化为相对应的ASCII码。
1.2 ascii
ascii码是什么?
ASCII(American Standard Code for Information Interchange)码是一种用于将文本字符和控制字符编码成数字的标准系统。简而言之,它是一种将文字转换为计算机可以理解的二进制形式的方法。
ascii码表是什么?
ASCII 码表包含了一系列的字符,包括字母、数字、标点符号和一些控制字符(比如换行和回车),共计128个。每个字符都用一个唯一的7位二进制数表示,因此 ASCII 码表是一个将字符与二进制数对应的表格。
例如,字母 “A” 在 ASCII 码表中对应的二进制值是 01000001。数字 “1” 对应的是 00110001。通过这种方式,计算机可以使用二进制数字来表示和处理文本,而不仅仅是数字和符号。
ASCII 码表的设计旨在实现文本的标准化表示,使得不同计算机和设备之间可以更容易地交换文本信息。虽然 ASCII 码表只包含了128个字符,但它奠定了字符编码的基础,后续的编码系统如 Unicode 扩展了这个范围,以支持更多的字符。
1.3 汇编语言字符示例代码
assume cs:codesg,ds:data codesg segment data segment db 'BaSic' db 'iNfOrMaTiOn' data ends start: mov al ,'a' mov bl,'b' mov ax,4c00h int 21h codesg ends end start
这段汇编代码是一个简单的8086汇编程序,用于将字符串 “BaSic” 和 “iNfOrMaTiOn” 存储在数据段中,然后将 ‘a’ 和 ‘b’ 存储在寄存器 AL 和 BL 中。最后,程序使用 DOS 调用结束程序的执行。
现在逐步解释每一部分:
1.Segment Definitions:
codesg segment
这定义了一个代码段,称为 codesg 段。
data segment
db ‘BaSic’
db ‘iNfOrMaTiOn’
data ends
这定义了一个数据段,称为 data 段,其中包含两个字符串 “BaSic” 和 “iNfOrMaTiOn”。
2.Data Initialization:
mov al, ‘a’
mov bl, ‘b’
这两行将字母 ‘a’ 放入 AL 寄存器,将字母 ‘b’ 放入 BL 寄存器。
3.DOS Interrupt Call:
mov ax, 4c00h
int 21h
这两行用于进行 DOS 中断调用。AX 寄存器被设置为 4C00H,这是 DOS 中断 21H 的一种调用方式,它表示程序要求终止执行。这将导致程序退出并返回到 DOS 操作系统。
4.Segment End and Program End:
codesg ends
end start
这标志着代码段的结束和程序的结束。
综合起来,这个程序的主要目的是在数据段中存储两个字符串,然后将 ‘a’ 和 ‘b’ 存储在寄存器中,最后通过 DOS 中断调用结束程序的执行。实际上,这个程序没有输出任何信息到屏幕上,仅仅是一个简单的示例程序。
用DOSBox编译,链接,debug运行他
可以看到mov al,'a’变成了mov al,61,a就变成了ascii的十进制了
二、大小写转换
观察下面这个图片
可以发现,大写和小写仅仅差20H
2.1 问题:对datasg中的字符串
第一个字符串:小写字母转换为大写字母
第二个字符串:大写字母转换为小写字母
对第一个字符串,
若字母是小写,转大写;
否则,不变
对第二个字符串,
若字母是大写,转小写;
否则,不变
如果这样,是不是要用分支结构了呢?
我们可以使用逻辑与和逻辑或运算
2.2 逻辑与和逻辑或
逻辑与指令:and dest, src
逻辑或指令:or dest, src
2.3 程序:解决大小写转换的问题
一个新的汇编指令inc指令
当涉及到汇编语言中的 INC 指令时,可以将其想象成是一个增加器。它的作用就像是一个计数器一样,把某个东西的值加一。
比方说,你有一个盒子里放着一堆苹果,然后你想数数盒子里到底有多少个苹果。每当你数到一个苹果时,你会在一个纸上记录下来,然后继续数下一个。INC 就像是你在数苹果的时候,每数一个,记录上面的数字加一一样。
在汇编语言中,INC 指令用于将某个特定的数值增加一。无论是一个存储在寄存器里的数值还是存在内存中的数据,INC 都能将其加一。就像是对盒子里的苹果进行计数一样,只是在计算机中,这个计数是以二进制数字的形式进行的。
如果你学过C/C++这些语言,你可以理解成变量++/变量+=1
程序
assume cs:codesg,ds:data codesg segment data segment db 'BaSic' db 'iNfOrMaTiOn' data ends start: mov ax,datasg mov ds,ax mov bx,0 mov cx,5 s: mov al,[bx] and al,11011111b mov [bx],al inc bx loop s mov bx,5 mov cx,11 s0: mov al,[bx] or al,00100000b mov [bx],al inc bx loop s0 mov ax,4c00h int 21h codesg ends end start
这段汇编代码是一个8086汇编程序,它处理两个字符串并做了一些修改。下面是逐步的解释:
1.Segment Definitions:
codesg segment
定义了一个代码段,称为 codesg 段。
data segment
db ‘BaSic’
db ‘iNfOrMaTiOn’
data ends
定义了一个数据段,称为 data 段,其中包含两个字符串 “BaSic” 和 “iNfOrMaTiOn”。
2.Data Initialization:
mov ax, datasg
mov ds, ax
这两行将数据段 datasg 的地址加载到 DS 寄存器,以便程序可以访问数据段的内容。
mov bx, 0
mov cx, 5
初始化寄存器 BX 为0,CX 为5。这将用于处理第一个字符串 “BaSic”。
3.String Processing (s):
s: mov al, [bx]
and al, 11011111b
mov [bx], al
inc bx
loop s
这一部分是对第一个字符串的处理。通过逐个处理字符串中的字符,将每个字符的第五位(从右边数起)设置为0,实现了将小写字母转换为大写。
4.String Processing (s0):
mov bx, 5
mov cx, 11
s0: mov al, [bx]
or al, 00100000b
mov [bx], al
inc bx
loop s0
这一部分是对第二个字符串的处理。同样,通过逐个处理字符串中的字符,将每个字符的第五位设置为1,实现了将大写字母转换为小写。
5.DOS Interrupt Call:
mov ax, 4c00h
int 21h
最后,这两行是进行 DOS 中断调用,用于结束程序的执行。
总体来说,这个程序的主要目的是处理两个字符串,将第一个字符串中的小写字母转换为大写,将第二个字符串中的大写字母转换为小写。然后,程序通过 DOS 中断调用结束执行。
总结
在本文中,我们深入研究了一个汇编程序,旨在展示如何处理字符串中的字符。通过对两个字符串的处理,我们学到了如何使用位运算指令,如 AND 和 OR,来修改字符的特定位。这使得我们能够在字符的二进制表示中进行精确的位操作,实现大小写字母的转换。
此外,我们看到了如何使用寄存器来迭代访问字符串中的字符,以及如何使用循环结构来简化重复的操作。这些是汇编语言中非常重要的概念,因为它们使我们能够以底层的方式直接操作计算机的内存。
通过这个例子,我们不仅仅学到了字符处理的具体技术,还对汇编语言的基本思想有了更深刻的理解。字符处理是计算机编程中一个基础而又必要的技能,而汇编语言为我们提供了直接而强大的工具,用于在底层级别精细控制字符数据。这使得我们能够更好地理解计算机底层的运行原理,并在需要时能够编写高效的字符处理程序。