【汇编】5内存寻址方式

目录

5.1、处理字符串问题

1、规定

2、大小写转换

5.2、[bx+idata]方式寻址

1、含义

2、应用

5.3、SI和DI寄存器

1、变址寄存器

2、应用

5.4、[bx+si]和[bx+di]

1、基址变址寻址方法

5.5、[bx+si+idata]和[bx+di+idata]

1、应用

5.6、不同的寻址方式的灵活运用

1、对内存的寻址方式

2、案例1:灵活应用不同的寻址方式

3、案例2:灵活应用不同的寻址方式

5.7、寻址方式总结

1、内存的寻址方式(全)

5.8、用于内存寻址的寄存器

1、有哪些寄存器?

2、用法

5.9、关于数据的两个基本问题

1、处理的数据在什么地方?

2、要处理的数据有多长?

5.10、用div指令实现除法

1、div指令

2、div指令示例

3、在内存单元中实施除法

5.11、用dup设置内存空间

1、dup功能和用法

2、dup用途


5.1、处理字符串问题

1、规定

汇编中用‘……’的方式指明数据是以字符的形式给出的,编译器将把他们转化为相应的ASCII码。

assume cs:code,ds:data
data segment
    db 'unix'
    db 'fork'
data ends

code segment
start:mov al,'a'
    mov bl,'b'
    mov ax,4c20h
    int 21h
code ends
end start

2、大小写转换

逻辑与指令:and dest,src

逻辑或运算:or dest,src

大写转小写:add al,11011111b

小写转大写:or al,00100000b

例如:将BaSic转为全部大写,iNfOrMaTion转小写。

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,[bx]
    and al,11011111b
	mov [bx],al
	inc bx
	loop s
    ;BaSic
	
	mov bx,5
	mov cx,11
 s0:mov al,[bx]
	or al,00100000b
	mov [bx],al
	inc bx
	loop s0
    ;iNfOrMaTiOn
	
	mov ax,4c20h
	int 21h
code ends
end start

28cc059552b2473eb26b284d544e9615.png

95412916ec554f5bad0b140a1c7caed6.png

 

5.2、[bx+idata]方式寻址

1、含义

[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata

指令mov ax,[bx+200]的含义

        将1个长度为2字节的内存单元的内容送入ax

        该内存单元的段地址在ds中,偏移地址为200加上bx中的数值。

        即:(ax)=((ds)*16+200+(bx))

2、应用

例如:将下列字符串分别改为大写和小写

assume cs:code,ds:data
data segment
    db 'StaDIum'
    db 'cHicKen'
data ends
code segment
start:mov ax,data
    mov ds,ax
    
    mov ax,0
    mov bx,0
    mov cx,7
  s:mov al,[bx]
    and al,11011111b
    mov [bx],al
    
    mov al,[bx+7]
    or al,00100000b
    mov [bx+7],al
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end start

17407d9862b1409dbeb2ef0b4bf3a28d.png

 

5.3、SI和DI寄存器

1、变址寄存器

SI和DI是8086CPU中和BX功能相近的寄存器,执行与地址有关的操作。

BX:通用寄存器,在计算地址时,常用作基址寄存器用。

SI:源变址寄存器

DI:目标变址寄存器

与bx的区别
SI和DI是纯粹的16位寄存器,
不能分成两个8位寄存器来使用。

 

2、应用

例如:用寄存器SI和DI实现将字符串"welcome to masm!"复制到它后面的数据区中

源数据起始地址:datasg:0,用ds:si指向要复制的原始字符串

目标数据起始地址:detasg:16,用ds:di指向目的空间

assume cs:code,ds:data
data segment
db'welcome to masm!'
db'0000000000000000'
data ends

code segment
start:
    mov ax,data
    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
code ends
end start

be11d07c7f654be7904987261aeb831a.png

 

5.4、[bx+si]和[bx+di]

1、基址变址寻址方法

[bx+si]表示一个内存单元,偏移地址位(bx)+(si),其中(bx)为基址,(si)为变址。该寻址方式称为基址变址寻址方式。

 

例如:内存中有数据,2000:1000 BE 00 06 00 00 00 .. .. ..

程序执行后, ax、bx、cx中的内容

(ax)=6h        (bx)=1000h        (cx)=600h

mov ax,2000H
mov ds,ax
mov bx,1000H
mov si,0
mov ax,[bx+si]
;(ax)=00BEh

inc si
mov cx,[bx+si]
;(cx)=0600h

inc si
;(si)=2

mov di,si
mov ax,[bx+di]
;(ax)=0006h

 

5.5、[bx+si+idata]和[bx+di+idata]

1、应用

[bx+si+idata]表示一个内存单元

 例如:程序中数据:2000:1000 BE 00 06 00 6A 22 00 00

执行程序后,ax,bx,cx中的内容?
 

mov ax,2000h
mov ds,ax
mov bx,1000h
mov si,0
mov ax,[bx+2+si]
;(ax)=0006h

inc si
mov cx,[bx+2+si]
;(cx)=6a00h

inc si
mov di,si
mov ax,[bx+2+di]
;(ax)=226ah

0a43330836374851a9cf8d850a777f83.pngc09b7e54e2cc49f585037de5028d74db.png

 

5.6、不同的寻址方式的灵活运用

1、对内存的寻址方式

0f3e50e52e97433195121dd24d073602.png

 

2、案例1:灵活应用不同的寻址方式

问题:编程将detasg段中的每个单词的头字母改为大写字母

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,4c00h
    int 21h
codesg ends
end start

分析及程序执行结果如下:

根据datasg中的数据的存储结构,采用[bx+idata]方式

 0123456789ABCDEF
001.file          
102.edit          
203.search        
304.view          
405.options       
506.help          
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+2]
	and al,11011111b
	mov [bx+2],al
	add bx,16
	loop s
	
    mov ax,4c00h
    int 21h
codesg ends
end start

2db93f4601684781add15098186f118d.png

 

3、案例2:灵活应用不同的寻址方式

问题:编程将datasg段中的每个单词改为大写字母。

assume cs:code,ds:data,ss:stack
data segment
	db 'ibm 			'
	db 'dec 			'
	db 'dos 			'
	db 'vax 			'
data ends

 分析及代码执行结果如下:

根据数据在内存中的存储结构,采用[bx+si]方式

二重循环问题的处理——用栈保存数据

 0123456789ABCDEF
00ibm             
10dec             
20dos             
30vax             

 

assume cs:code,ds:data,ss:stack
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 bx,0
	mov cx,4
	
  s:push cx
	;将外层循环的cx值压栈
    mov cx,3
	;设置内层循环次数
    mov si,0
   s1:mov al,[bx+si]
	and al,11011111b
	mov [bx+si],al
	inc si
	loop s1
    add bx,16
	pop cx
	;从栈顶弹出外层循环的cx值
	loop s
	
	mov ax,4c00h
	int 21h
code ends
end start

cb8bf792da604bdbafcf071d3825e2c7.png

 

5.7、寻址方式总结

1、内存的寻址方式(全)

b1f5ae24064b447492fbb92dbfbbfbb2.png

 

5.8、用于内存寻址的寄存器

1、有哪些寄存器?

BX(base):基址寄存器,常用于地址索引,默认指ds段

BP(base pointer):栈基址指针寄存器,bp默认指ss段

SI(Source Index):源变址寄存器,可用来存放相对于DS段之源变址指针

DI(Destination Index):目的变址寄存器,可用来存放相对于ES 段之目的变址指针。

 

2、用法

(1)只有bx、bp、si、di可以用在[...]对内存单元寻址。

(2)bx以外的通用寄存器、段寄存器不可以用在[...]中。

(3)dx、bp不能一起用,[bx+bp]格式错误;si、di不能一起用,[si+di]格式错误。

(4)具体含义

36e4ffc87255466f91c8aa82acb29db5.png

 

5.9、关于数据的两个基本问题

1、处理的数据在什么地方?

1、立即数(idata)2、寄存器

3、内存:段地址:偏移地址(SA:EA)

对于直接包含在机器指令中的数据,称为立即数,数据包含在指令中。

指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。

 

指令要处理的数据在内存中,由SA:EA确定内存单元。

 

2、要处理的数据有多长?

1、字word操作2、字节byte操作3、用word ptr或byte ptr声明
ax、bxal、bl

mov word ptr ds:[0],1

inc word ptr [bx]

mov word ptr ds:[0],1

inc word ptr [bx]

注释:在没有寄存器参与的内存单元访问指令中,用word ptr或byte ptr显性地指明所访问的内存单元的长度是很必要的,否则,CPU无法得知所要访问的是字单元,还是字节单元。

 

5.10、用div指令实现除法

1、div指令

div是除法指令,使用div作除法的时候

被除数:(默认)放在AX(8位除法)或DX和AX(16位除法)中
除数:8位或16位,在寄存器或内存单元中

div指令格式

div 寄存器
div 内存单元
被除数AXDX和AX
除数8位内存或寄存器16位内存或寄存器
结果ALAX
余数AHDX
示例指令被除数除数余数
div bl(ax)(bl)(al)(ah)
div byte ptr ds:[0](ax)((ds)*16+0)(al)(ah)
div byte ptr [bx+si+8](ax)((ds)*16+(bx)+(si)+8)(al)(ah)
div bx((ds)*10000H+(ax))(bx)(ax)(dx)
div word ptr es:[0]((ds)*10000H+(ax))((es)*16+0)(ax)(dx)
div word ptr [bx+si+8]((ds)*10000H+(ax))((ds)*16+(bx)+(si)+8)(ax)(dx)
切记提前在默认的寄存器中设置号被除数,且默认寄存器不作别的用处。

 

2、div指令示例

(1)编程:利用除法指令计算100001/100。

分析:100001D=186A1H,使用16位除法;dx与ax联合存放被除数186A1H,bx存放除数100D=64H。

mov dx,1

mov ax,86a1

mov bx,64

div bx

9485110b517341cbb5a8a9deab809d63.png

 

 

(2)编程:利用除法指令计算1001/100

分析:1001D=3E9H,进行8位除法,存入AX中;BX存放除数100D=64H。

mov ax,3E9

mov bl,64

div bl

97f3d40dfb0f459fab300287fa33057f.png

 

3、在内存单元中实施除法

(1)双字型数据的定义
 

data segment
    db 1 ;定义1个字节数据01h,在data:0处,占1个字节空间
    dw 1 ;定义1个字数据0001h,在data:1处,占2个字节空间
    dd 1 ;定义1个双字数据0000 0001h,在data:3处,占4个字节,或2个字空间
data ends

(2)例如

用div计算data段中的第1个数据除以第2个数据后的结果,商存放在第3个数据的存储单元中。

 0123456789ABCDEF
ds10000100001000         
 1000011000         
assume cs:code,ds:data
data segment
	dd 100001
	dw 100
	dw 0
data ends
code segment
start:
	mov ax,data
	mov ds,ax
	
	mov ax,ds:[0]
	mov ds,ds:[2]
	div word ptr ds:[4]
	mov ds:[6],ax
	
	mov ax,4c00h
	int 21h
code ends
end start

dbfb1e0987f445a7a50c08a0910b78db.png

 

 

5.11、用dup设置内存空间

1、dup功能和用法

(1)功能:dup和db、dw、dd等数据定义伪指令配合使用,用来进行数据的重复。

注释:duplicate复制

(2)示例

44ff2c628165465ca821bed84d69c7a6.png

 (3)dup的使用格式

db重复的次数dup(重复的字节型数据)

dw重复的次数dup(重复的字型数据)

dd重复的次数dup(重复的双字型数据)

 

2、dup用途

示例1:定义1个容量位200个字节的栈空间。

stack segment
    db  200 dup(0)
stack ends

示例2:

assume cs:code,ds:data
data segment
	db 7 dup(0)
	db 3 dup(0,1,2)
	db 64 dup(0)
	db 3 dup('abcd','ABCD')
data ends
code segment
start:
	mov ax,data
	mov ds,ax
	
	mov ax,4c00h
	int 21h
code ends
end start

8217709e0c3a4344851d48356c1d8f2c.png

 

 

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值