一个约定:idata表示常量
and和or
我觉得没什么值得解释的,大家应该都是明白的。
举个例子:
and al,10110101b
or al,10101010b
就是把寄存器中的值and上或or上某个数。
ASCII码
这个大家应该也都知道。
字符与字符串
汇编里的字符和字符串由’'给出。
比如:
db ’unIX‘
mov ax,'a'
其中db意思是“define byte”
而其在内存中的存储形式,就是ASCII码对应的数字。
字母大小写转换
我们先摘录作者的一句话:
如果一个问题的解决方案,使我们陷入一种矛盾之中。那么,很有可能是我们考虑问题的出发点有了问题,,或是说,我们起初应用的规律并不合适
很有道理,不是吗?
希望大家能细心体会一下这句话。
下面我们再来看正文,有人可能会说,这不简单吗?字母的大小写转换,这个恐怕是基础中的基础的问题了吧?
没错,是很简单,判断是大写字母还是小写字母,然后减去32或加上32就好了。
但是,现在,我们有一个限制条件,仅能用我们已学的汇编语句,也就是说不能用比较的操作。
那么我们应该怎么处理?
稍加思索,我们便可以观察到,一个大写字母和一个小写字母的ASCII 码的差别在哪里?
那就是25位,一个是0,一个是1,其他全部是一样的。
说到这里,也许你就明白了。
所以,有时候,换个角度考虑,就会得到全新的一篇天地。
用[bx+idata]来寻址
我们标题是更加灵活的寻址方式。
这里就是第一种。
就是用[bx+idata]
其实就相当于[(bx)+idata](debug下)
用[bx+idata]来进行数组管理
这里应该是很好理解的。
相当于bx是数组首地址,然后后面就可以用idata来当下标来使用。
SI和DI
这两个寄存器的功能和bx是类似的。
可以用来寻址。
但是不一样的是,它们不能被是为两个八字节的内存来使用。
[bx+si]和 [bx+di]
我们再来看看这两个寻址方法。
它们两个是类似的。
而他们其实与[bx+idata]类似。
这里的含义也就是[bx+(si)]
我们举个例子:
mov ax,[bx+si]
但这样并不是我们常用的形式。
一种更为常用的等价写法如下:
mov ax,[bx][si]
[bx+si+idata]和[bx+di+idata]
没错,又复合了一层。
他们两个的含义类似,所以我们以[bx+si+idata]为例。
其实呢,含义还是类似的,就是三个数值相加进行寻址。
使用方法如下:
mov ax,[bx+si+idata]
同样,它也有很多的等价写法:
mov ax,[idata+bx+si]
mov ax,idata[bx][si]
mov ax,[bx].idata[si]
mov ax,[bx][si].idata
提示:bx和si的相对位置可以换,即si可以放在bx之前,注意后面两种写法需要在常数前加点
不同寻址方式的灵活运用
现在我们已经有很多的寻址方式了。
那么我们应该怎么去灵活地运用呢?
我们来总结一下各个寻址方式适用的条件:
- [bx]:一个变量定位,间接定位
- [idata]:常量定位,不能更改,直接定位
- [bx+idata]:数组,一个地址的基础上进行寻址
- [bx+si]:两个变量访问地址
- [bx+si+idata]:两个变量和一个常量
我们都知道,在写代码时,会用到很多的变量。
其中有些是有实际意义,有些可能是一些临时的变量。
当我们的程序越来越复杂,变量越来越多,但是CPU的寄存器就只有14个(8086型),用完了该怎么办?
我们通过之前的学习知道,在汇编过程中,我们保存数据的地方,只有两个:寄存器和内存。
那么既然寄存器用完了,我们就只能用内存了。
所以,在编程中,我们更多的临时数据一个放在一个栈中,这样不仅可以存放更多的数据,而且数据的结构也更加清晰。
结束语
这就是第七章的主要内容了。