第七章 更灵活的定位内存地址的方法 其一

引言

前面,我们用[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。

原文地址:https://www.cnblogs.com/fate-/p/12916737.html