|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
7.1节 and 和 or 指令
(1)and指令,逻辑与指令,按位进行与运算。
如: mov al, 01100011B
and al, 00111011B
al的结果为:00100011B
通过该指令可以将操作对象的相应位设为0,其他位不变。例如:
将al的第6位设为0的指令是:and al, 10111111B
将al的第7位设为0的指令是:and al, 01111111B
(2)or指令,逻辑或指令按位或运算。
如: mov al, 01100011B
or al, 00111011B
al的结果为:01111011B
通过该指令可以将操作对象的相应位设置为1, 其他位不变。例如:
将al的第6位设为1的指令是:or al, 01000000B
将al 的第7位设为1的指令是:or al, 10000000B
7.3节 以字符的形式给出的数据
我们在汇编的程序中,用'......'的方式指明数据是以字符的形式给出的,编译器把他们转化为相对应的ASCII码
7.4节 大小写转换的问题
先看一副图:
从中可以看出, 就ASCII码的二进制来看,除第5位(从0开始算)的外,大写字母和小写字母的其他各位都一样,大写字母ASCII码的第五位是0,小写字母的第5位为1。知道这个规律, 我们想转换大小写字母就只需要转换其第5位的二进制是0(大写字母)还是1(小写字母)。
问题:将data段中的第一个字符串转换为大写,第二个字符串转换为小写。代码:
- assume cs: code
- data segment
- db 'BaSic'
- db 'iForMatioN'
-
- data ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov bx, 0
-
- mov [code][code][code]c
复制代码 [/code][/code]x, 5
s : mov al, [bx]
and al, 11011111B
mov [bx], al
inc bx
loop s
mov bx, 0
mov cx, 11
s0: mov al, [bx]
or al, 00100000B
mov [bx], al
inc bx
loop s0
mov ax, 4c00H
int 21H
code ends
end start
[/code]
7.5节 [bx + idata]
mov ax,[bx + idata]表示在ax中存放两个字节,偏移地址为bx ,加上idata,段地址在ds中
mov ax, [200 + bx]、mov ax, 200[bx]和mov ax, [bx].200都表示同一个意思,只是不同的形式。
7.6节 用[bx + idata]方式进行数组的处理
问题: 将data段中的第一个字符串转换为大写,第二个字符串转换为小写。原本是这样的代码他有两个循环:
- assume cs: code
- data segment
- db 'BaSic'
- db 'iForMatioN'
-
- data ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov bx, 0
-
- mov cx, 5
- s : mov al, [bx]
- and al, 11011111B
- mov [bx], al
- inc bx
-
- loop s
-
- mov bx, 0
- mov cx, 11
-
- s0: mov al, [bx]
- or al, 00100000B
- mov [bx], al
- inc bx
-
- loop s0
-
- mov ax, 4c00H
- int 21H
-
- code ends
- end start
-
复制代码
现在用[bx + idata]可以用一个循环就实现:
- assume cs: code
- data segment
- db 'BaSic'
- db 'MinIX'
-
- data ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov bx, 0
-
- mov cx, 5
- s : mov al, [bx]
- and al, 11011111B
- mov [bx], al
-
- mov al, 5[bx]
- or al, 00100000B
- mov 5[bx], al
- inc bx
-
- loop s
-
- mov ax, 4c00H
- int 21H
-
- code ends
- end start
复制代码
SI 和 DI
si 和 di是和bx功能相近的寄存器,si和di不能分成两个8位寄存器来使用,下面三组指令实现了相同的功能。
(1)mov bx, 0
mov ax, [bx]
(2)mov si, 0
mov ax, [si]
(3)mov di, 0
mov ax, [di]
问题:用bx(si 或 di)的方式是实现将data段中的数据复制到后面:
- assume cs: code
- data segment
- db 'welcome to masm!'
- db '................'
-
- data ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov bx, 0
-
- mov cx, 16
- s : mov al, [bx]
- mov [bx + 16], al
- inc bx
-
- loop s
-
- mov ax, 4c00h
- int 21H
-
- code ends
- end start
复制代码
7.8节[bx + si] 和 [bx + di]
mov ax, [bx + si]表示将偏移地址为[bx + si](bx中的值加上si中的值),段地址在ds 中的数据放入ax中。
mov ax, [bx + di]也是差不多
7.9节 [bx + si + idata]和[bx + di +idata]
mov ax, [bx + si + idata] 将偏移地址为bx中的数值加上si中的数值再加上idata的和,段地址在ds中的数据放入ax中。
mov ax, [bx + di + idata]也是差不多
7.10节 不同的寻址方式的灵活运用
编程:将data段中的每个单词的头一个字母改为大写;
- assume cs: code
- data segment
- db '1. file '
- db '2. edit '
- db '3. search '
- db '4. view '
- db '5. options '
- db '6. help '
-
- data ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov si, 0
-
- mov cx, 6
- s : mov al, 3[si]
- and al, 11011111B
- mov 3[si], al
-
- add si, 16
-
- loop s
-
- mov ax, 4c00H
- int 21H
-
- code ends
- end start
复制代码
编程:将data段中的每个单词改为大写字母:
(1)我自己写的好蠢的代码:
- assume cs: code
- data segment
- db 'ibm.............'
- db 'dec.............'
- db 'dos.............'
- db 'vax.............'
-
- data ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov bx, 0
-
- mov cx, 3
- s1: mov al, [bx]
- and al, 11011111B
- mov [bx], al
- inc bx
-
- loop s1
-
- mov bx, 0
- mov cx, 3
- s2: mov al, 16[bx]
- and al, 11011111B
- mov 16[bx], al
- inc bx
-
- loop s2
-
- mov bx, 0
- mov cx, 3
- s3: mov al, 32[bx]
- and al, 11011111B
- mov 32[bx], al
- inc bx
-
- loop s3
-
- mov bx, 0
- mov cx, 3
- s4: mov al, 48[bx]
- and al, 11011111B
- mov 48[bx], al
- inc bx
-
- loop s4
-
- mov ax, 4c00H
- int 21H
-
- code ends
- end start
复制代码
(2)这个是标准版的代码:
- assume cs: code
- data segment
- db 'ibm.............'
- db 'dec.............'
- db 'dos.............'
- db 'vax.............'
-
- data ends
- stack segment
- dw 0, 0, 0, 0, 0, 0, 0, 0
-
- stack ends
- code segment
- start : mov ax, data
- mov ds, ax
- mov ax, stack
- mov ss, ax
- mov sp, 16
-
- mov si, 0
- mov cx, 4
- s : push cx
- mov bx, 0
-
- mov cx, 3
- s1: mov al, [bx + si]
- and al, 11011111B
- mov [bx + si], al
- inc bx
-
- loop s1
-
- pop cx
-
- add si, 16
-
- loop s
-
- mov ax, 4c00H
- int 21H
-
- code ends
- end start
复制代码
这个程序让我们知道了,如果在内层循环中如果寄存器被重复使用的话,就应该用栈将它给保存下来
一般来说,在暂时需要存放数据的时候,我们都应该找栈。
编程:将data段中的每个单词的前四个单词改为大写字母:
- assume cs: code
- data segment
- db '1. display '
- db '1. brows '
- db '1. replace '
- db '1. modify '
-
- data ends
- stack segment
- dw 0, 0, 0, 0, 0, 0, 0, 0
- stack ends
- code segment
- start : mov ax, data
- mov ds, ax
-
- mov ax, stack
- mov ss, ax
- mov sp, 16
-
- mov si, 0
- mov cx, 4
- s : push cx
- mov bx, 0
-
- mov cx, 4
- s1: mov al, 3[bx + si]
- and al, 11011111B
- mov 3[bx + si], al
- inc bx
-
- loop s1
-
- pop cx
-
- add si, 16
-
- loop s
-
- mov ax, 4c00H
- int 21h
-
- code ends
- end start
复制代码
第七张总结
(1)这章我们学会了更多灵活的定位内存,如:新增8位寄存器si和di,用[bx + idata]、[bx + si ]、[bx + si + idata]等方式定位内存
(2)二重循环应该用栈将要重复使用的寄存器push起来相应的要pop出去,这两者要一一对应
(3)大小写转换的问题,将数据的二进制的第五位(从0开始算)该为0或1
(4)and和or指令,本章主要将它应用到转换大小写 |
|