2014年4月7日 星期一 21时52分08秒
第七章 更灵活的定位内存地址的方式
7.1 and和or指令
and 逻辑与指令,按位进行与运行。通过该指令可以将操作对象的相应位设置为0
or 逻辑或指令,按位进行或运算。通过该指令可以将操作对象的相应位设置为1
7.2 关于ASCII码
7.3 以字符形式给出的数据
在汇编中,用'......'的方式指明数据是以字符形式给出的。
assume cs:code,ds:data
data segment
db 'unIX'
db 'foRK'
data ends
code segment
start:mov al,'a'
mov bl,'b'
mov ax,4c00h
int 21h
code ends
end start
debug该段代码:
用 u 146B:0可以看到对应的代码段:
用 d 146A:0 可以看到对应的数据段:
7.4 大小写转换问题
;将大写字母变小写,将小写字母变大写
;思路:可以根据大小写字母二进制中第五位值得不用来进行判断
assume cs:code,ds:data
data segment
db 'BaSiC'
db 'iNfOrMaTiOn'
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,5
s:mov al,ds:[bx]
and al,11011111B
mov ds:[bx],al
inc bx
loop s
mov bx,5
mov dx,11
s0:mov al,ds:[bx]
or al,00100000B
mov ds:[bx],al
inc bx
loop s0
mov ax,4c00h
int 21h
code ends
end start
程序执行前:
程序执行后:
7.5 用[bx+idata]
前面我们用[bx]来指明一个内存单元,还可以用一种更为灵活的方式来指明内存单元:[bx+idata]表示一个内存单元。
指令:mov ax[200+bx]
该指令也可以写为 mov ax,[bx+200]
mov ax,200[bx]
mov ax,[bx].200
问题7.1
assume cs:code
code segment
start:mov ax,2000h
mov ds,ax
mov bx,1000h
mov ax,[bx]
mov cx,[bx+1]
mov cx,[bx+2]
mov ax,4c00h
int 21h
code ends
end start
7.6 用[bx+idata]的方式进行数组的处理
;用[bx+idata]的数组处理方式,将第一个字符串转换为大写,第二个字符串转换为小写
assume cs:code, ds:data
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,ds:[bx] ; 也可以写为 mov al,0[bx]
and al,11011111B
mov ds:[bx],al
mov al,ds:[bx+5] ; 也可以写为 mov al,5[bx]
or al,00100000B
mov ds:[bx+5],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start;
7.7 SI和DI
si和di是8086CPU中和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]
问题7.2 用si和di实现将字符串'welcome to masm!' 复制到它后面的数据区域中。
assume cs:code,ds:data
data segment
db 'welcome to masm!'
db '................'
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s:mov ax,ds:[bx]
mov ds:[bx+16],ax
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
7.8 [bx+si]和[bx+di]
[bx+si]和[bx+di]的含义相似。
指令 mov ax,[bx+si]的含义如下:
(ax)=( (ds)*16 +(bx)+(si))
还可以写成如下格式:
mov ax,[bx][si]
7.9 [bx+si+idata]和[bx+di+idata]
指令 mov ax,[bx+si+idata] 还可以写成如下格式:
mov ax,[bx+200+si]
mov ax,[200+bx+si]
mov ax,200[bx][si]
mov ax,[bx].200[si]
mov ax,[bx][si].200
7.10 不用寻址方式的灵活运用
问题7.6
;问题7.6 将datasg段中每个单词的头一个字母改为大写字母
assume cs:code,ds:data
data segment
db '1. file '
db '2. edit '
db '3. search '
db '4. help '
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,3
mov cx,4
mov si,0
s:mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
问题7.7
;问题7.7 将datasg段中的每个字母都变为大写
assume cs:code,ds:data
data segment
dd 'ibm '
dd 'dec '
dd 'dos '
dd 'vax '
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov si,0
mov cx,4
s:mov al,dx:[bx+si+0]
and al,11011111B
mov dx:[bx],al
mov al,dx:[bx+si+1]
and al,11011111B
mov dx:[bx],al
mov al,dx:[bx+si+2]
and al,11011111B
mov dx:[bx],al
inc bx
add si,16
loop s
mov ax, 4c00h
int 21h
code ends
end start
问题7.8 解决二重循环计数器的问题(用dx寄存器暂时存放外层循环的计数器)
;问题7.7 将datasg段中的每个字母都变为大写
assume cs:code,ds:data
data segment
dd 'ibm '
dd 'dec '
dd 'dos '
dd 'vax '
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s0:mov dx,cx
mov cx,3 ;设置为内层循环的次数
mov si,0
s:mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
inc si
loop s
add bx,16
mov cx,dx ;用dx中存放的外层循环的计数器回复cx
loop s0 ;外层循环的loop指令将cx中的计数值减1
mov ax, 4c00h
int 21h
code ends
end start
问题7.9
;将datasg段中每个单词的前四个字母改为大写
assume cs:code, ds:data, ss:stack
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
data segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
data ends
code segment
start:mov ax,data
mov ds,ax
mov ax,stack
mov ss,stack
mov sp,16
mov cs,4
mov si,3
mov di,0
s0: push cs
mov cs,4
s:mov ax,0
mov al,ds:[si+di]
and al,11011111B
mov ds:[si],al
inc si
loop s
add di,16
pop cs
loop s0
mov ax,4c00h
int 21h
code ends
end start
实验六 实践课程中的程序
2014-4-8 23:36 记 @sanlihe.xichengqu.beijing
第七章 更灵活的定位内存地址的方式
7.1 and和or指令
and 逻辑与指令,按位进行与运行。通过该指令可以将操作对象的相应位设置为0
or 逻辑或指令,按位进行或运算。通过该指令可以将操作对象的相应位设置为1
7.2 关于ASCII码
7.3 以字符形式给出的数据
在汇编中,用'......'的方式指明数据是以字符形式给出的。
assume cs:code,ds:data
data segment
db 'unIX'
db 'foRK'
data ends
code segment
start:mov al,'a'
mov bl,'b'
mov ax,4c00h
int 21h
code ends
end start
debug该段代码:
用 u 146B:0可以看到对应的代码段:
用 d 146A:0 可以看到对应的数据段:
7.4 大小写转换问题
;将大写字母变小写,将小写字母变大写
;思路:可以根据大小写字母二进制中第五位值得不用来进行判断
assume cs:code,ds:data
data segment
db 'BaSiC'
db 'iNfOrMaTiOn'
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,5
s:mov al,ds:[bx]
and al,11011111B
mov ds:[bx],al
inc bx
loop s
mov bx,5
mov dx,11
s0:mov al,ds:[bx]
or al,00100000B
mov ds:[bx],al
inc bx
loop s0
mov ax,4c00h
int 21h
code ends
end start
程序执行前:
程序执行后:
7.5 用[bx+idata]
前面我们用[bx]来指明一个内存单元,还可以用一种更为灵活的方式来指明内存单元:[bx+idata]表示一个内存单元。
指令:mov ax[200+bx]
该指令也可以写为 mov ax,[bx+200]
mov ax,200[bx]
mov ax,[bx].200
问题7.1
assume cs:code
code segment
start:mov ax,2000h
mov ds,ax
mov bx,1000h
mov ax,[bx]
mov cx,[bx+1]
mov cx,[bx+2]
mov ax,4c00h
int 21h
code ends
end start
7.6 用[bx+idata]的方式进行数组的处理
;用[bx+idata]的数组处理方式,将第一个字符串转换为大写,第二个字符串转换为小写
assume cs:code, ds:data
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,ds:[bx] ; 也可以写为 mov al,0[bx]
and al,11011111B
mov ds:[bx],al
mov al,ds:[bx+5] ; 也可以写为 mov al,5[bx]
or al,00100000B
mov ds:[bx+5],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start;
7.7 SI和DI
si和di是8086CPU中和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]
问题7.2 用si和di实现将字符串'welcome to masm!' 复制到它后面的数据区域中。
assume cs:code,ds:data
data segment
db 'welcome to masm!'
db '................'
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s:mov ax,ds:[bx]
mov ds:[bx+16],ax
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
7.8 [bx+si]和[bx+di]
[bx+si]和[bx+di]的含义相似。
指令 mov ax,[bx+si]的含义如下:
(ax)=( (ds)*16 +(bx)+(si))
还可以写成如下格式:
mov ax,[bx][si]
7.9 [bx+si+idata]和[bx+di+idata]
指令 mov ax,[bx+si+idata] 还可以写成如下格式:
mov ax,[bx+200+si]
mov ax,[200+bx+si]
mov ax,200[bx][si]
mov ax,[bx].200[si]
mov ax,[bx][si].200
7.10 不用寻址方式的灵活运用
问题7.6
;问题7.6 将datasg段中每个单词的头一个字母改为大写字母
assume cs:code,ds:data
data segment
db '1. file '
db '2. edit '
db '3. search '
db '4. help '
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,3
mov cx,4
mov si,0
s:mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
问题7.7
;问题7.7 将datasg段中的每个字母都变为大写
assume cs:code,ds:data
data segment
dd 'ibm '
dd 'dec '
dd 'dos '
dd 'vax '
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov si,0
mov cx,4
s:mov al,dx:[bx+si+0]
and al,11011111B
mov dx:[bx],al
mov al,dx:[bx+si+1]
and al,11011111B
mov dx:[bx],al
mov al,dx:[bx+si+2]
and al,11011111B
mov dx:[bx],al
inc bx
add si,16
loop s
mov ax, 4c00h
int 21h
code ends
end start
问题7.8 解决二重循环计数器的问题(用dx寄存器暂时存放外层循环的计数器)
;问题7.7 将datasg段中的每个字母都变为大写
assume cs:code,ds:data
data segment
dd 'ibm '
dd 'dec '
dd 'dos '
dd 'vax '
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s0:mov dx,cx
mov cx,3 ;设置为内层循环的次数
mov si,0
s:mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
inc si
loop s
add bx,16
mov cx,dx ;用dx中存放的外层循环的计数器回复cx
loop s0 ;外层循环的loop指令将cx中的计数值减1
mov ax, 4c00h
int 21h
code ends
end start
问题7.9
;将datasg段中每个单词的前四个字母改为大写
assume cs:code, ds:data, ss:stack
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
data segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
data ends
code segment
start:mov ax,data
mov ds,ax
mov ax,stack
mov ss,stack
mov sp,16
mov cs,4
mov si,3
mov di,0
s0: push cs
mov cs,4
s:mov ax,0
mov al,ds:[si+di]
and al,11011111B
mov ds:[si],al
inc si
loop s
add di,16
pop cs
loop s0
mov ax,4c00h
int 21h
code ends
end start
实验六 实践课程中的程序
2014-4-8 23:36 记 @sanlihe.xichengqu.beijing