第七章 更灵活的定位内存地址的方法 其一
引言
前面,我们用[0]、[bx]的方法,在访问内存的指令中,定位内存单元的地址。
在这一章中,我们主要讲解一些更灵活的定位内存地址的方法和相关的编程方法
首先我们介绍两条指令and和or,因为我们下面的例子中要用到他们。
1)and指令:逻辑与指令,按位进行与运算。
如mov al, 01100011B
and al, 00111011B
执行后:al=00100011B
通过该指令可将操作对象的相应位设为0,其他位不变。
2)or指令:逻辑或指令,按位进行或运算。
如 mov al,01100011B
or al,00111011B
执行后:al=01111011B
通过该指令可将操作对象的相应位设为1,其他位不变。
7.2关于ASCII码
世界上有很多编码方案,有种方案叫做ASXII编码,是在计算机系统中通常被采用的。
简单的说,所谓编码方案,就是一套规则,它约定了用什么样的信息来表示显示对象。
比如说,在ASCII编码方案中,用61H表示‘a',62H表示’b'。
7.3以字符形式给出的数据
我们可以在汇编程序中,用‘,,,’的方式指明数据是以字符的形式给处的,编译器将把他们转化为相对应的ASCII码。
例如以下程序:
7.4 大小写转换的问题
首先分析一下,我们知道同一个字母的大写字符和小写字符对应的ASCII码是不同的,比如‘A’的ASCII码是41H,a的ASCII码是61H。
要改变一个字母的大小写,实际上就是要改变它所对应的ASCII码
通过对比,我们可以看出来,小写字母的ASCII码值比大写字母的ASCII码值大20H。
这样我们可以想到,如果将a的ASCII码值减去20H,就可以得到A,如果将A的ASCII码值加上20H就可以得到a。
要注意的是:
对于字符串BaSic,我们应只对其中的小写字母所对应的ASCII码进行减20H的处理,将其转为大写,而对其中的大写字母不进行改变。
对于字符串iNforMaTIOn,我们应支队其中的大写字母所对应的ASCII码进行加20H的处理,将其转为小写;而对于其中的小写字母不进行改变,
另一种方法:
可以看出,就ASCII码的二进制形式来看,除第5位(位数从0开始计算)外,大写字母和小写字母的其他各位都一样。
大写字母ASCII码的第5位(位数从0开始)为0,小写字母的第5位为1.
这样,我们有了新方法
一个字母,我们不管它原来是大写还是小写:
我们将它的第五位置0,他就必变为大写字母
将它的第五位置1,它就必将变为小写字母。
代码如下:
1 assume cs:codesg,ds:datasg 2 datasg segment 3 db 'BaSiC' 4 db 'iNfOrMaTiOn' 5 datasg ends 6 7 codesg segment 8 start: mov ax,datasg 9 mov ds,ax ;设置ds指向datasg段 10 11 mov bx,0 ;设置(bx)=0,ds:bx指向“BaSiC”的第一个字母 12 13 mov cx,5 ;设置循环次数5,因为“BaSiC”的有5个字母 14 s: mov al,[bx] ;将ASCII码从ds:bx所指向的单元中取出 15 and al,11011111b ;将al中的ASCII码的第5位置为0,变为大写字母 16 mov [bx],al ;将转变后的ASCII码写回原单元 17 18 inc bx ;(bx)加1,ds:bx指向下一个字母 19 loop s 20 21 22 mov bx,5 ;设置(bx)=5,ds:bx指向“iNfOrMaTiOn”的第一个字母 23 24 mov cx,11 ;设置循环次数11,因为“iNfOrMaTiOn”的有11个字母 25 s0: mov al,[bx] 26 or al,00100000b ;将al中的ASCII码的第5位置为0,变为小写字母 27 mov [bx],al 28 inc bx 29 loop s0 30 31 mov ax,4c00h 32 int 21h 33 codesg ends 34 end start
7.5 [bx+idata]
在前面,我们可以用[bx]的方式来指明一个内存单元,我们还可以用一种更为灵活的方式来指明内存单元:
[bx+idata]表示一个内存单元,他的偏移地址为bx中的数值加上idata。
指令mov ax,[bx+200]也可以写成如下格式(常用):
mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
7.6用[bx+idata]的方式进行数组的处理
有了[bx+idata]这种表示内存单元的方式,我们就可以用更高级的结构来看待所要处理的数据。
我们可以把上节中关于字母大小写转换的代码改写成上面那样,就像是一个数组。
7.7 si和di
si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。
代码如下:
更简洁的代码:
7.8 [bx+si]和[bx+di]
在前面,我们用[bx]和[bx(si、di)+idata]的方式来指明一个内存单元,我们还可以用更灵活的方式:
{bx+si]
[bx+di]
[bx+si]表示一个内存单元,它的偏移地址bx中的数值加上si中的数值。
7.9[bx+si+idata]和[bx+di+idata]
[bx+si+idata]表示一个内存单元,他的偏移地址是bx中的数值加上si中的数值再加上idata。