程序7.1
实现功能:查看编译器将用db定义的数据转化为的ASCLL码值以及字符'a'、'b'的ASCLL码值
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跟踪,用R命令查看寄存器的值,DS=075A所以定义的数据段起始位置为DS+0010=076A,使用D命令查看076A:0内存单元的值可以看到‘u’、'n'、'I'、'X'的ASCLL码值为75H、6EH、49H、58H,'f'、'o'、'R'、'K'的ASCLL码值为66H、6FH、52H、4BH。
程序7.2
实现功能:将db中定义的数据进行大小写转换
程序如下:由于大写字母ASCLL码值的二进制的第五位都是0,小写字母ASCLL码值的二进制的第五位都是1,所以使用and指令将需要变为大写的数据的第五位置0,使用or指令将需要变为小写的数据的第五位置1。
assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start: mov ax,datasg
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,5
mov cx,11
s0: mov al,[bx]
or al,00100000B
mov [bx],al
inc bx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
编译连接后使用Debug跟踪,先使用D命令查看原始字符的ASCLL码值
再用U命令查看指令的位置,用g命令将程序执行完毕
最后查看数据所在内存单元的值得变化
可以看出,ASCLL码值得变化规律符合‘小写字母=大写字母+20H’的规律。
程序7.3
实现功能:对程序7.2的改进,采用[bx+idata]的形式代替第二次循环。(也可以写成idata[bx]的形式,不过就没有再写这个了)
assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5
s: mov al,[bx]
and al,11011111B
mov [bx],al
mov al,[bx+5]
or al,00100000B
mov [bx+5],al
inc bx
loop s
mov ax,4c00h
int 21h
codesg ends
end start
程序7.4
实现功能:将db定义的字符串复制到他后面的数据区中
assume cs:codesg,ds:datasg
datasg segment
db 'welcome to masm!'
db '................'
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov si,0
mov di,16
mov cx,8
s: mov ax,[si]
mov [di],ax
add si,2
add di,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
总结:
(1)SI和DI寄存器,不能分成两个8位的寄存器来使用。
(2)SI和DI寄存器的功能与bx相近
(3)可以对上面的程序进行改进,即将[di]修改为[si+16]表示,这样就不用使用di寄存器,代码更简洁。
程序7.5
实现功能:将datasg段中的每个单词的头一个字母改为大写字母
由于两个需要改变大小写的字母的间隔为16,所以可以使用[bx+16]的形式定位下一个需要变化的字母,只需要循环六次。
assume cs:codesg,ds:datasg
datasg segment
db '1. file '
db '2. edit '
db '3. search '
db '4. view '
db '5. options '
db '6. help '
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,6
s: mov al,[bx+3]
and al,11011111B
mov [bx+3],al
add bx,16
loop s
mov ax,4c00h
int 21h
codesg ends
end start
程序7.6
实现功能:将datasg段中的没一个单词改为大写字母
由于二层循环需要两个循环计数器,但loop默认cx为循环寄存器,所以我们只能暂时将cx的值储存在dx中,在执行外层循环的loop之前在恢复cx的值。
assume cs:codesg,ds:datasg
datasg segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0: mov dx,cx
mov si,0
mov cx,3
s: mov al,[bx+si]
and al,11011111B
mov [bx+si],al
inc si
loop s
add bx,16
mov cx,dx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
但是CPU的寄存器始终是有限的,如果我们不能选择寄存器,那么我们也可以选择内存,将数据暂时储存在内存单元中,需要的时候再从内存单元中恢复。但注意,使用内存来暂时存储数据时,也需要用dw进行定义。如果有许多数据需要储存的话,必须记住数据都放在了哪个单元,容易混乱,所以我们应该使用栈来储存。该写程序为:
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
datasg ends
stacksg segment
dw 0,0,0,0,0,0,0,0
stacksg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov ax,stacksg
mov ss,ax
mov sp,16
mov bx,0
mov cx,4
s0: push cx
mov si,0
mov cx,3
s: mov al,[bx+si]
and al,11011111B
mov [bx+si],al
inc si
loop s
add bx,16
pop cx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
程序6.7
实现功能:将datasg段中每个单词的前4个字母改为大写字母
assume cs:codesg,ds:datasg,ss:stacksg
stacksg segment
dw 0,0,0,0,0,0,0,0
stacksg ends
datasg segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov ax,stacksg
mov ss,ax
mov sp,16
mov bx,3
mov cx,4
s0: push cx
mov cx,4
mov si,0
s: mov al,[bx+si]
and al,11011111B
mov [bx+si],al
inc si
loop s
add bx,16
pop cx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
编译连接,使用debug跟踪
达到实验目的。