第七章 更灵活的定位内存地址的方法
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 cx, 5
s : mov al,
and al, 11011111B
mov , al
inc bx
loop s
mov bx, 0
mov cx, 11
s0: mov al,
or al, 00100000B
mov , al
inc bx
loop s0
mov ax, 4c00H
int 21H
code ends
end start
7.5节
movax,表示在ax中存放两个字节,偏移地址为bx ,加上idata,段地址在ds中
mov ax, 、mov ax, 200和mov ax, .200都表示同一个意思,只是不同的形式。
7.6节 用方式进行数组的处理
问题: 将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,
and al, 11011111B
mov , al
inc bx
loop s
mov bx, 0
mov cx, 11
s0: mov al,
or al, 00100000B
mov , al
inc bx
loop s0
mov ax, 4c00H
int 21H
code ends
end start
现在用可以用一个循环就实现:
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,
and al, 11011111B
mov , al
mov al, 5
or al, 00100000B
mov 5, 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,
(2)mov si, 0
mov ax,
(3)mov di, 0
mov ax,
问题:用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,
mov , al
inc bx
loop s
mov ax, 4c00h
int 21H
code ends
end start
7.8节 和
mov ax, 表示将偏移地址为(bx中的值加上si中的值),段地址在ds 中的数据放入ax中。
mov ax, 也是差不多
7.9节 和
mov ax, 将偏移地址为bx中的数值加上si中的数值再加上idata的和,段地址在ds中的数据放入ax中。
mov ax, 也是差不多
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
and al, 11011111B
mov 3, 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,
andal, 11011111B
mov , al
inc bx
loop s1
mov bx, 0
mov cx, 3
s2: mov al, 16
and al, 11011111B
mov 16, al
inc bx
loop s2
mov bx, 0
mov cx, 3
s3: mov al, 32
and al, 11011111B
mov 32, al
inc bx
loop s3
mov bx, 0
mov cx, 3
s4: mov al, 48
and al, 11011111B
mov 48, 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,
and al, 11011111B
mov , 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
and al, 11011111B
mov 3, 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,用、、等方式定位内存
(2)二重循环应该用栈将要重复使用的寄存器push起来相应的要pop出去,这两者要一一对应
(3)大小写转换的问题,将数据的二进制的第五位(从0开始算)该为0或1
(4)and和or指令,本章主要将它应用到转换大小写
页:
[1]