主要是记录《汇编语言》这本书的第七章
目录
一.and 和 or
1.and 和 or 介绍
2.ascii和大小写问题
二.寻址的几种方式
1.[bx + idata]
2.si和di
3.[bx + si] 和 [bx + di]
4.[bx + si + idata] 和 [bx + di + idata]
三.总结
一.and 和 or
1.and 和 or
我们知道代码最终都是由二进制来存储的,那么对二进制数据最直接的运算也就是位运算了,在汇编中,有两种命令来直接操控二进制数据,and和or
<1 and
and: 逻辑与指令, 按位进行与运算
mov al, 11111111b
and al, 11101111b
结果al 是 11101111b
这个不难想,就是把第5位清0了,and指令一般用于指定位清0
<2 or
or:逻辑或指令, 按位进行或运算
mov al, 00000000b
or al, 00010000b
结果al 是00010000b
or指令一般用来指定位变为1
2.ascii和大小写问题
<1 ascii
汇编程序中 '.....' 的方式指名数据是以字符形式给出的, 编译器将他们转化为对应的ASCII
比如 db 'unIX'
相当于 db '75H, 6Eh, 49H, 58H'
<2 大小写转换
最开始学c的时候老师们都让我们写过大小写转换问题,无非就是ASCII加32减32的问题
我们知道了and和or那就好办多了
32无非是2^5
00010000b也就是二进制第5位
那么我们直接用and或or指令将指定db的第五位换为0或1即可
二.寻址的几种方式
1.[bx + idata]
[bx]在没指定段寄存器的情况下默认的段寄存器是ds,
所以[bx]表示ds:[bx] , 也就是ds*16 + bx
那么[bx + idata],也就是用了一种更加灵活的方式来指名了要访问的内存
ds*16+bx+idata
比如修改每个db中的第三位,bx每次+8, idata设置为3即可,很方便
2.si 和 di
si 和 di 是8086cpu中和bx功能相近的寄存器, si和di不能分为两个8位寄存器来使用
查询了资料,si 是源变址寄存器, di是目的变址寄存器,可以用来存放数据,地址,功能类似,用法类似。
但是需要注意的是:在串处理指令中, si 用作隐含的源串地址, 默认在ds中, di用作隐含的目的串得知,默认在es中,此时不能混用
3.[bx+si] 和 [bx+di]
这种方式是第一种方式的补充,也是一种灵活的方式,因为si 和 di也是两种寄存器,里面存储的数据可变。
[bx+si]也可以写成[bx][si]
ds*16+bx+si
4.[bx+si+idata] 和 [bx+di+idata]
这种有在源基础上添加了idata也就是又增加了它的灵活性,可能说体会不到。
我们举个例子,
比如我在汇编中定义了个二位数组
db ' hello '
db ' world '
如果我想把每个单词的前三个字母变为大写。怎么办
用[bx]: 找到串的首个字符,修改bx定位到第一个字母,改完该第二个字母,第三个字母,在跳第二个单词。。。在跳第三个。。。
用[bx+si]:找到串的首个字符,修改si定位到第一个字母,修改si。。。,跳转第二个单词时,修改si,这样变成会不会很类- - 。
用[bx+si+idata]:idata设置为3,每次自动定位到串中单词的第一个字母,si控制行内变换,bx控制行变化,是不是清晰简单了很多。
三.总结
[idata] 用一个常量来表示地址。可以用于直接定位到一个内存单元
[bx] 用一个变量来表示内存地址,可以于间接定位到一个内存单元
[bx + idata]用一个变量和一个常量来表示地址, 可在一个起始地址的基础上用变量间接定位到一个内存单元
[bx + si] 用两个变量表示地址
[bx + si + idata] 用两个变量和一个常量来表示地址
这几种方式并不是很难理解,我们目的是理解为什么cpu要用这么多种方式来寻址
在我们使用的高级语言c/c++/java也都有数组和二维数组等等,字符串等等,其底部的根本就是用这些来实现的,理解了这些对我们运用高级语言时是有很多好处的
补充:
cpu中的寄存器数量有限
8086cpu中只有14个寄存器
如果程序中有很多需要保存的数据,那么寄存器就不够用了
一种好的方法是,在需要暂存数据的时候,我们应该使用栈