|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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指令,本章主要将它应用到转换大小写 |
|