汇编语言-第7章-更灵活的定位内存地址的方法-检测

汇编语言-第7章-检测

1、我们以前的章节的标题是什么?

第1章基础知识
第2章查存器
第3章寄存器(内存访问)
第4章第一个程序
第5章[BX]和loop指令
第6章包含多个段的程序
第7章更灵活的定位内存地址的方法
第8章数据处理的两个基本问题

2、这一章有多少页?

173-150=23页。

7.1节 and和or指令

3、以前我们学了什么?这章要干嘛?

用[0]、[bx]的方法,在访问内存的指令中,定位内存单元的地址。
通过具体问题,讲解更灵活的定位内存地址的方法。

4、and指令是什么意思?有什么作用?

名称:与指令。
动作:按位进行与指令。
当两操作数对应位都为“1”时结果的相应位为“1”,否则结果相应位为“0”。

比如
mov al, 01100011B
and al,00111011B
执行后: al=00100011B

作用?
可将操作对象的相应位设为0,其他位不变。

al
11110000
右边开始是al的第0位。
左边开始是al的第7位。

将al的第6位设为0的指令是: and al,10111111B
将al的第7位设为0的指令是: and al,0111111B
将al的第0位设为0的指令是: and al,11111110B

5、or指令是什么意思?有什么作用?

名称:或指令。
动作:按位进行或指令。
当两操作数对应位都为“0”时结果的相应位为“0”,否则结果相应位为“1”。

mov al, 01100011B
or al, 00111011B
执行后: al=01111011B

作用?
可将操作对象的相应位设为1,其他位不变。

将al的第6位设为1的指令是: or a1,01000000B
将al的第7位设为1的指令是: or al,10000000B
将al的第0位设为1的指令是: or al,00000001B

7.2节 关于ASCII码

8、ASCII码是什么?

一套编码方案。

9、在文本编辑过程中,如何利用ASCII码显示在屏幕上?

按下a键,计算机用ASCII码的规则进行编码,
转化为61H存储在内存指定空间中
文本编辑软件从内存中取出61H,
将其送到显卡上的显存中。
工作在文本模式下的显卡,用ASCII码解释显存中的内容,
61H=a,显卡驱动显示器,将字符a的图像花在屏幕上。

7.3节 以字符形式给出的数据

db是定义一个字节
db 'unIX’这个有4个字符,所以4个字节

10、解释这段代码

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

db 'unIX’相当于db 75H,6EH,49H,58H
“mov al,'al” 相当于“mov al,61H",“a” 的ASCII码为61H;

11、如何用debug查看data段的内容?

先用r命令,找到data段的地址,
这里ds=0B2D,所以程序从0B3DH段开始。

什么段是程序中的第一个段?
data段。它是程序的起始处。所以它的段地址是0B3DH。

右边符号是什么意思?
用d命令查看data段,Debug以十六进制数码和ASCII码字符的形式显示出其中的内容。
可以看出data段中的每个数据所对应的ASCII字符。
75对应u

在这里插入图片描述

7.4节 大小与转换的问题

12、小写字母和大写字母ASCII码有什么规律?

小写比大写字母大20H。
a-20H=A
A+20H=a

13、如何将大小写,互相转换?

上面的规律。我们现在没有可以使用的用于判断的指令。所以不用上面的规律。

重新找一个规律。
11110000
左边第7位
右边第0位
从ASCII码的二进制来看,除第5位以外,大小写字母其他位是一样的。
大写第5位是0
小写第5位是1

新规律:
大写第5位是0
小写第5位是1

使用的思路?
将第5位置于0,变大写字母。
将第5位置于1,变小写字母。

所以现在用这个规律, 不需要再处理前判断字母的大小写。

如何实现?
用or和and指令。转换大小写。

14、大小写互换的代码

assume cs:codesg, ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start: 
	mov ax, datasg
	mov ds, ax;设置ds指向datasg段
	mov bx, 0;设置(bx)=0,ds:bx指向'BaSiC'的第一个字母
	mov cx, 5;设置循环次数5,因为'BaSiC'有5个字母
s:
	mov al, [bx];将ASCII码从ds :bx所指向的单元中取出
	and al, 11011111B;将al中的ASCII码的第5位置为0,变为大写字母
	mov [bx],al;将转变后的ASCII码写回原单元
	inc bx; (bx)加1,ds:bx指向下一个字母
	loop s
	mov bx, 5;设置(bx)=5, ds:bx指向' iNfOrMaTiOn'的第一个字母
	
	mov cx, 11;设置循环次数11,因为'iNfOrMaTiOn'有11个字母
s0:
	mov al, [bx]
	or al, 00100000B;将al中的ASCII码的第5位置为1,变为小写字母:
	mov [bx] ,al
	inc bx
	loop s0
	mov ax, 4c00h
	int 21h
codesg ends
end start

7.5节 [bx+idata]

15、以前我们是用[bx]来指明内存单元,原理是?

首先
mov ax,dataseg
mov ds,ax
然后用ds:[bx]来指明内存单元。

16、现在用更加灵活的[bx+idata]来指明内存单元

[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata
什么意思?
bx中数值加上idata

17、mov ax,[bx+200]什么意思?

这是一条指令。
将一个内存单元的内容送入ax,
这个内存单元的长度为2个字节(是一个字单元),
存放一个字,
偏移地址为bx中数值加上200,段地址在ds中。

数学化描述:(ax)=((ds)*16+(bx)+200)

18、还可以写成什么形式?

mov ax, [200+bx]
mov ax, 200[bx]——这个比较常用
mov ax, [bx].200

19、bx一般赋值是用来干嘛的?

和ds搭配使用。
ds:bx

20、例题:

用Debug查看内存,结果如下:
2000: 1000 BE 00 06 00 00 00
写出下面的程序执行后,ax、bx、cx中的内容。

mov ax, 2000H
mov ds, ax
mov bx, 1000H
mov ax, [bx]
mov cx, [bx+ ]
add cx, [bx+2]

mov ax, [bx]
访问的字单元的段地址在ds中,(ds)=2000H; 偏移地址在bx中,(bx)=1000H; 指令执行后(ax)=00BEH。

mov cx, [bx+1]
访问的字单元的段地址在ds中,(ds)=2000H; 偏移地址=(bx)+1=1001H;指令执行后(cx)=0600H。

add cx, [bx+2]
访问的字单元的段地址在ds中,(ds)=2000H; 偏移地址=(bx)+2=1002H;指令执行后(cx)=0606H。

7.6节 用[bx+idata]的方式进行数组的处理

21、以前和现在,处理大小写字母,转换的区别。

以前:
14中的代码

assume cs:codesg, ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start: 
	mov ax, datasg
	mov ds, ax;设置ds指向datasg段
	mov bx, 0;设置(bx)=0,ds:bx指向'BaSiC'的第一个字母
	mov cx, 5;设置循环次数5,因为'BaSiC'有5个字母
s:
	mov al, [bx];将ASCII码从ds :bx所指向的单元中取出
	and al, 11011111B;将al中的ASCII码的第5位置为0,变为大写字母
	mov [bx],al;将转变后的ASCII码写回原单元
	inc bx; (bx)加1,ds:bx指向下一个字母
	loop s
	mov bx, 5;设置(bx)=5, ds:bx指向' iNfOrMaTiOn'的第一个字母
	
	mov cx, 11;设置循环次数11,因为'iNfOrMaTiOn'有11个字母
s0:
	mov al, [bx]
	or al, 00100000B;将al中的ASCII码的第5位置为1,变为小写字母:
	mov [bx] ,al
	inc bx
	loop s0
	mov ax, 4c00h
	int 21h
codesg ends
end start

现在新的方法:可以更加简化。
思路是
观察datasg段中的两个字符串,一个起始地址为0,一个起始地址为5.
可以将这两个字符串看做两个数组。一个从0地址开始存放,一个从5开始存放。
用[0+bx]和[5+bx]的方式,在同一循环中定位两个字符串中的字符。

0/5给定了两个字符串的起始偏移地址,bx给出了从起始偏移地址开始的相对地址。
这里[bx+idata]中idata的好处就是有了起始偏移地址,如果有两个,起始地址可以不同,但是相对地址bx的变化可以相同

22、新方法的代码

在这里插入代码片
assume cs:codesg, ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start: 
	mov ax, datasg
	mov ds, ax;设置ds指向datasg段
	mov bx, 0;设置(bx)=0,ds:bx指向'BaSiC'的第一个字母
	
	mov cx, 5;设置循环次数5,因为'BaSiC'有5个字母
s:
	mov al, [0+bx];定位第一个字符串中的内容。将ASCII码从ds:bx所指向的单元中取出。
	and al, 11011111B;将al中的ASCII码的第5位置为0,变为大写字母
	mov [bx],al;将转变后的ASCII码写回原单元
	mov al, [5+bx];定位第二个字符串中的内容。
	or al,00100000b
	mov [5+bx],al;
	inc bx
	loop s
	
	mov ax, 4c00h
	int 21h
codesg ends
end start

23、也可以写成?

mov ax, datasg
mov ds, ax
mov bx, 0
mov cx, 5
s:
mov al, 0[bx]
and al, 11011111b
mov 0[bx] ,al
mov al,5[bx]
or al, 00100000b
mov 5[bx] ,al
inc bx
loop s

24、C语言是怎么写的?

char a[5]="'BaSiC" ;
char b[5]="MinIX" ;
main ()
{
int i;
i=0;
do{
	a[i]=a[i] &0xDF ;
	b[i]=b[i] | 0x20;
	i++;
	}
while(i<5) ;
}

C语言: a[i], b[i]
汇编语言: 0[bx], 5[bx]

25、[bx+idata]方式为高级语言实现数组提供了便利机制。

新规律:
大写第5位是0
小写第5位是1

与指令变0,变大写
或指令变1,变小写

7.7节 SI和DI

26、si和di寄存器,有什么特殊的吗?

si和di是和bx功能相近的寄存器,
它们不能拆分成为两个8位的寄存器。

就是说他和bx差不多呗

1、
mov bx, 0	把0给bx
mov ax, [bx] 把ds:[0]给ax
2、
mov si, 0
mov ax, [si]
3、
mov di, 0
mov ax, [di]
4、
mov bx, 0
mov ax, [bx+123]
5、
mov si, 0
mov ax, [si+123]
6、
mov di, 0
mov ax, [di+123]

27、如何利用si、di实现将字符串复制到它后面的数据区中。

datasg:0是要进行复制的数据的地址。字符串是16个字节。0-15放字符
datasg:16放复制

这里用到si和di了。
si指向原始字符串的位置
di指向复制的字符串位置

注意,在程序中,用16位寄存器进行内存单元之间的数据传送,一次复制2个字节,一共循环8次。

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

28、利用bx(si或di)+idata的方式,变得更简洁。

mov ax,datasg
mov ds,ax
mov si,0
mov cx,8
s
mov ax,[0+si]
mov [16+si],ax
add si,2
loop s
mov ax,4c00h
int 21h

codesg segment
start: 
	mov ax, datasg
	mov ds, ax
	mov si, 0
	mov CX, 8
S:
	mov ax,0[si]
	mov 16[si] , ax
	add si, 2
	loop s
	mov ax, 4c00h
	int 21h
codesg ends
end
start

mov ax, 4c00h
int 21h:
你的程序运行时 操作系统将控制权交给你的程序 你的程序运行完毕 必须将控制权交回操作系统 它的作用就是交权.

7.8节 [bx+si]和[bx+di]

1、[bx]
2、[bx+idata]
3、[bx(si/di)+idata]
4、[bx+si]和[bx+di],这是一个更加灵活的方式,用来指明一个内存单元。
两个意思相近,讲解一个即可。

29、[bx+si]是什么意思?

[bx+si]表示一个内存单元,它的偏移地址是bx+si,就是bx中的数值,加上si中的数值。

30、mov ax,[bx+si]什么意思?

这是一个指令,
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为bx中的数值加上si中的数值,段地址在ds中。数学化的描述为: (ax)=((ds)* 16+(bx)+(si))
也可以写成,常用
mov ax,[bx] [si]

31、检验

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

7.9 节 [bx+si+idata]和[bx+di+idata]

在这里插入图片描述
在这里插入图片描述

32、检测

在这里插入图片描述在这里插入图片描述

7.10节 不同的寻址方式的灵活应用

在这里插入图片描述

33、将datasg 段中每个单词的头一个字母改为大写字母。


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  右边数第5位,与指令,变大写

                    mov            [bx+3],al

                    add              bx,16

                    loop             s

codesg              ends

                    end             start

34、编程,将datasg段中每个单词改为大写字母。

在这里插入图片描述
有错。这样cx会被覆盖。
在这里插入图片描述

改进:

我们应该在每次开始内层循环的时候,将外层循环的cx中的数值保存起来,在执行
外层循环的loop指令前,再恢复外层循环的cx数值。可以用寄存器dx来临时保存cx中
的数值,改进的程序如下。

在这里插入图片描述

35、暂存的数据放在寄存器不现实,应该开辟空间来放。

在这里插入图片描述在这里插入图片描述

36、用栈来暂存数据的新方法。

如果要暂存的数据很多,那么就要用栈来暂存,因为这样比较清晰。
编程,将datasg段中每个单词改为大写字母。

assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
	db 'ibm             '
	db 'dec             '
	db 'dos             '
	db 'vax             '
datasg ends

stacksg segment		;定义一个段,用来做栈段,容量为16个字节
	dw 0,0,0,0,0,0,0,0,0
stacksg ends

codesg
start: 
	mov ax,stacksg
	mov ss,ax
	mov sp,16	;这里什么意思?我们开辟一个段,一定是16的倍数。因为栈是从底部开始使用的,容量为16个字节,所以是16。
	mov ax,datasg
	mov ds,ax
	mov bx,0
	
	mov cx,4
s0: 
	puch cx 		;将外层循环的cx值压栈
	mov si,0
	mov cx,3		;cx设置为内层循环的次数
s:
	mov al,[bx+si]	;变大写
	and al,11011111
	mov [bx+si],al
	inc si			;在同一行内,往后走
	loop s
	add bx,16 		;到下一行
	pop cx			;从栈顶弹出原cx的值,恢复cx
	loop s0			;外层循环的loop指令将cx中的计数值减1	
	mov ax,4c00h
codesg ends
end start

37、将datasg 段中每个单词的前4个字母改为大写字母。

assume cs:codesg,ss:stacksg,ds:datasg

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,stacksg
        mov ss,ax
        mov sp,16
        mov ax,datasg
        mov ds,ax
        mov bx,0
        mov cx,4

     s: push cx
        mov di,3
        mov cx,4

    s0: mov al,[bx+di]
        and al,11011111b
        mov [bx+di],al
        inc di
        loop s0

        pop cx
        add bx,16
        loop s

        mov ax,4c00h
        int 21
 codesg ends
 end start

第7章我们学了啥?

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值