七、更灵活的寻址方式:37/77
1. and/or
and
和or
是逻辑指令
and
的功能是按位与(有没有想起子网掩码,就是那个!)
and al, 11111110B
可以将al中的其他位不变,最低位(第0位)设为0
or
的功能是按位或
or al, 00000001B
可以将al中的其他位不变,最低位(第0位)设为1
逻辑是什么?逻辑就是
0
和1
,就是false
和true
。对于二进制数来说,只有两种用途。一种是由多个二进制数组合,其映射的数据或指令。一种是由单个二进制数,其直接反应的逻辑。
补充:ASCII
就是其中一种社会普遍认可的映射(编码)方案。记住这三个:48 -> 0
、65 -> A
、96 -> a
,这三个是十进制数,对应的16进制数是30H
、41H
、61H
,是不是更好记了呢?
2. ASCII
屏幕上打字符a经历了什么: (假设是ASCII编码的)
- 敲下一个字符,被CPU按ASCII码编码为30H
- 这个30H存储在内存中
- 文本编辑软件从内存中取出这个30H
- 文本编辑器把30H送到显存中
- 显卡按照ASCII解码30H,屏幕上出现a
在汇编程序中用单引号'
包住的内容,为字符。编译器 ,会将它们转化成对应的ASCII码
🌰 db '0ab'
相当于db 30H, 41H, 61H
🌰 mov al, 'a'
相当于mov al, 41H
怎么装换大小写?
- 实际上就是ASCII转换的问题,先对比一下ASCII码
- 十进制相差
32
,二进制相差10,0000B
,十六进制相差20H
- A的二进制
0100,0001B
,A的十六进制41H
a的二进制0110,0001B
,a的十六进制61H
- 可以注意到,二进制把第五位从0变1就可以变为小写
注意: 编译器只认
ASCII
编码
- 全部转换为大写: and al, 11011111B(第五位变为0)
- 全部转换为小写: or al, 00100000B(第五位变为1)
3. [bx + idata]
用法: 三种皆可(假设idata为200)
mov ax, [bx + 200]
mov ax, 200[bx]
mov ax, [bx].200
汇编&C 实现一个数组:
- 汇编数组定位方式: 0[bx],5[bx]
- C数组定位方式: a[偏移地址],b[偏移地址]
[bx + idata] 为高级语言使用数组提供了依据。
4. SI & DI
- SI & DI在功能上和bx相等(默认[bx]会以
DS
为段地址),当bx不够用时,会使用它们 - SI & DI不能被拆成两个8位寄存器来使用
S
是source
来源的缩写;d
是direction
目地的缩写
利用SI和DI,把源数组复制到目标数组:
注意: 一次性传一个字,顺序不会乱掉嘛?以第0个字 He 为例。
- 先从内存写入寄存器:ah = e,al = H
- 再从寄存器写入内存:[0] = al,[1] = ah,最后内存里为He。顺序无误
更多用法:
[SI + idata]
/[DI + idata]
[bx + SI]
/[bx + DI]
,也可以写成[bx][SI]
/[bx][DI]
[bx + SI + idata]
/[bx + DI + idata]
,也可以写成其它形式,常数在前直接写,常数在后加个点,寄存器加括号。如5[bx][SI]
作用:
DS:[idata]
直接定位内存单元[bx]
间接定位内存单元idata[bx]
在一个偏移的基础上间接定位内存单元,多用于划定一个连续的内存空间(数组)
5. 一些例子&栈
- 1. 首字母变成大写:
- 2. 所有字母变成大写: (cx如果为0,再-1,就会变为ffffH)
可以用来暂时存放cs
的值的寄存器:dx
、di
、es
、ss
、sp
、bp
。那么问题来了,这些寄存器如果都被使用了怎么办?
- 诚然,程序简单的时候,可以使用寄存器来暂存。但是,我们应该寻求一个通用的解决办法。这个解决办法就是内存
- 2的程序改进为: 注意看红色改动地
- 一个新的问题: 如果有多个地方需要暂存数据。比如,定义了一个方法,在调用前把调用处的下一个地址存入。在这个方法内部,又存在着需要暂存的数据。可以发现,这些数据,遵循后进先出原则。所以,应该使用一个数据结构栈
- 栈:
FILO
,后进先出。常用来保存方法的调用地址,暂存数据 - 改进后的代码:
总结:
- 我们用bx来索引数据行(在内存中是一条线,只是我们人为这样认为)
- 我们用idata来索引列偏转
- 我们用SI来灵活取内存
- 栈常用来临时存放数据
为要处理的数据设计一个清晰的数据结构,是程序设计里的一个关键问题
八、数据处理的两个基本问题:42/77
数据处理两大基本问题:数据地址、数据类型
描述性符号:
reg
寄存器,sreg
段寄存器
reg | sreg |
---|---|
ax 、bx 、cx 、dx | ds 、ss、 cs 、es |
sp 、bp 、si 、di |
1. 数据地址
偏移地址四小龙: bx
、bp
、si
、di
- 只有
bx
、bp
、si
、di
可以用在[]
中进行内存单元的寻址 - 它们可以单独使用或以下四种组合:
bx si
、bx di
、bp si
、bp di
- 其中,
bx
默认段地址是DS数据段
,bp默认段地址是SS栈段
数 据 处 理 = 读 取 + 运 算 + 写 入 数据处理 = 读取 + 运算 + 写入 数据处理=读取+运算+写入
- 站在机器指令的这个层面,它不关心数据的值是多少(指令执行前,都还没读取呢),只关心数据的位置
- 所要处理的数据可以在三个地方:
CPU内部
、内存
、端口