1. and 指令
进行 逻辑与 运算
and ax, 0FFH ;获取低四位的值
eg:
0111 1101 ; 设这个是AX的存放的值
and 0000 1111 ; 0FFH 的二进制
--------------
0000 1101 ; AX的最终结果
简单来说, 就是 按位 与, 有 0 即为 0
同 1 方为 1, and 运算一般用于 将某些位置0
或者 取出数据某几位
eg:
0110 0001
and 1101 1111
--------------
0100 0001
2. or 指令
进行 逻辑或 运算
or ax, 0FFH ;第四位全部置1
eg:
0111 1101 ; 设这个是AX的存放的值
or 0000 1111 ; 0FFH 的二进制
--------------
0111 1111 ; AX的最终结果
简单来说, 就是 按位 或, 有 1 即为 1
同 0 方为 0, or 运算一般用于 将某些位置1
3. 以字符形式给出数据
db 'ABCDEFG'
mov ax, 'a' ; 0061H
mov al, 'a' ; 0061H
mov ah, 'a' ; 6100H
汇编的字符表示也是ASCII,在ASCII中'A' 与 'a'
相差 32 也就是 20H,这样设计是为了方便将大小写字母
进行快速转换,无需判断它是大写还是小写,直接转换
eg:
'A' 01
00 0001
'a' 01
10 0001
'Z' 01
01 1010
'z' 01
11 1010
很明显的可以发现, 从 A~Z ,它们的 二进制 表示只有一位有区别 高四位 的 第二位, 所以当我们想要将 大写 转成 小写 只需要 or 上 20H,小写 转换成 大写 只需要 and DFH 即可.
当然我们可以通过
sub ax, 20H 和
add ax, 20H 来实现这个过程.不过 逻辑运算 的速度 是 算数运算的 数倍 无需通过加法器来实现.
所以一般用逻辑运算来实现大小写转换
4. 新的内存地址定位方式:
[bx+idata],其数学表达式为: ((ds)*16 + (bx) + 200)
ps:约定()表示被()括起的 寄存器 或 内存地址上的值, idata 表示常量
eg:
(bx)表示 bx 寄存器 上的内容
(2000H)表示 内存地址2000H 上的内容
eg:
mov ax, [200+bx]
mov ax, 200[bx]
mov ax, [bx].200
200[bx]这种写法其实很接近,高级语言的数组 a[i] 了
8086 内部还有两个和bx相近的寄存器 si 和 di ,不过这两个寄存器
无法拆分成8位寄存器, 其它操作 与 bx 寄存器无异.
eg:
mov ax, bx
mov ax, [si]
mov ax, [di]
mov ax, [bx+123]
mov ax, [si+123]
mov ax, [di+123]
上面两组代码效果相同
[bx+si] 和 [bx+di]:
数学表达式: ((ds)*16 + (bx)+(si 或 di))
鉴于[bx+idata]的方式不够灵活, idata 毕竟是常量,无法变化
所以诞生了寄存器+寄存器 的方法
eg:
mov ax, [bx+di]
mov ax, [bx][di]
上式等价
[bx+si+idata]
不用想,花式组合肯定是少不的了,自行领悟啦
总结:
这次的核心是,花式 内存地址 定位,这是一个非常重要的问题,
适当的寻址方式 可以让我们以 一种 更合理的结构来 看待 或 分析 所要处理的 数据
本章习题:
7.6:;首字母大写
assume cs:code, ss:stack
a segment
db '1. file '
db '2. edit '
db '3. search '
db '4. view '
db '5. option '
db '6. help '
a ends
stack segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
code segment
start: mov ax, a;
mov ds, ax
mov bx, 0
mov cx, 6
Loop1: mov al, 3[bx+si]
and al, 0DFH
mov 3[bx], al
add bx, 16
loop Loop1
mov ax, 4c00h
int 21
code ends
end start
7.7:;单词改成大写字母
assume cs:code, ss:stack
a segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
a ends
stack segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
code segment
start: mov ax, a;
mov ds, ax
mov ax, stack
mov ss, ax
mov ax, 0
mov bx, 0
mov cx, 4
Loopfloor1: mov si, 0
push cx
mov cx, 3
Loopfloor2: mov al, [bx+si]
and al, 0DFH
mov [bx+si], al
inc si
loop Loopfloor2
add bx, 10H
pop cx
loop Loopfloor1
mov ax, 4c00h
int 21
code ends
end start
7.9:;前四个字母改为大写
assume cs:code, ss:stack
a segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
a ends
stack segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
code segment
start: mov ax, a;
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 20H;
mov ax, 0
mov bx, 0
mov cx, 4
Loopfloor1: push cx
mov si, 0
mov cx, 4
Loopfloor2: mov al, 3[bx+si]
and al, 0DFH
mov 3[bx+si], al
inc si
loop Loopfloor2
add bx, 10H
pop cx
loop Loopfloor1
mov ax, 4c00h
int 21
code ends
end start
;大佬思路:
; mov bx, 0
; mov cx, 4
;upRow: push cx
; push bx
; mov cx, 4
;
;upLetter: mov al, ds:[bx+3]
; and al, 11011111B
; mov ds:[bx+3], al
; inc bx
; loop upLetter
;
; pop bx
; pop cx
; add bx, 16
; loop upRow
;少用一个寄存器,甘拜下风