汇编语言学习第七章
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' 0100 0001
'a' 0110 0001
'Z' 0101 1010
'z' 0111 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 ;少用一个寄存器,甘拜下风
大道五十,天衍四九,人遁其一!