更灵活的定位内存地址的方法

1.1 and 和 or 指令

(1)and指令:逻辑与指令,按位进行与运算 (出现0则为0)
在这里插入图片描述

(2)or指令:逻辑或运算,按位进行或运算 (出现1则为1)
在这里插入图片描述

1.2 ASCII编码解码

一个文本编辑过程中,就包含着按照 ASCI编码规则进行的编码和解码。在文本编辑过程中,我们按一下键盘的 a 键,就会在屏幕上看到"a"。这是怎样一个过程呢?我们按下键盘的 a 键,这个按键的信息被送入计算机,计算机用 ASCII码的规则对其进行编码,将其转化为 61H 存储在内存的指定空间中;文本编辑软件从内存中取出 61H,将其送到显卡上的显存中;**工作在文本模式下的显卡,用 ASCII码的规则解释显存中的内容,61H 被当作字符"a",显卡驱动显示器,将字符"a"的图像画在屏幕上。**我们可以看到,显卡在处理文本信息的时候,是按照 ASCII码的规则进行的。这也就是说,如果我们要想在显示器上看到"a",就要给显卡提供"a"的 ASCII 码,61H。如何提供?当然是写入显存中。

1.3 以字符形式给出的数据

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

注:" db ‘unIX’ "相当于 “db 75H,6EH,49H,58H”,“u”、“n”、“I”、"X"的ASCII 码分别为75H、6EH、49H、58H;
"mov al,‘a’ “相当于"mov al,61H”,"a"的 ASCII码为61H;

用 d 命令查看 data 段,Debug 以十六进制数码和 ASCII 码字符的形式显示出其中的内容,从中,可以看出 data 段中的每个数据所对应的 ASCII字符。

1.4 大小写转换的问题

一个字母,不管它原来是大写还是小写,将它的第5位设置为 0,它就必将变为大写字母; 将它的第5位设置为1,它就必将变为小写字母。在这个方法中,我们不需要在处理前判断字母的大小写。

例:在这里插入图片描述
解:
在这里插入图片描述

1.5 [bx+idata]

可以用一种更为灵活的方式来指明内存单元∶
【bx+idata】表示一个内存单元,它的偏移地址为(bx)+idata(bx 中的数值加上idata)。

例:指令mov ax,[bx+200]
数学化描述为∶(ax)=((ds)*16+(bx)+200 )

该指令也可以写成如下格式(常用):
mov ax,[200+bx]

mov ax,200[bx]
mov ax,[bx].200

例题:
在这里插入图片描述
(ax) = 00BEH,(bx) = 0600H,(cx) = 0606H

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

[bx+idata] 中的idata可以用来定位不同字符串起始地址,在同一循环中使用 [a+bx] 和 [b+bx] 的方式定位两个字符串的起始偏移地址。
而长度相同的字符(cx相同),在同一循环中,每各遍历一个字符,从起始地址开始的相对地址的变化是相同的(即bx递增相同)

1.7 SI 和 DI

si和 di 是 8086CPU中和 bx 功能相近的寄存器,si和 di 不能够分成两个8位寄存器来使用。

在这里插入图片描述

1.8 [bx+si] 和 [bx+di]

注:【bx+si】和【bx+di】的含义相似

【bx+si】表示一个内存单元,它的偏移地址为(bx)+(si)(即 bx 中的数值加上 si 中的数值)。
指令mov ax,【bx+si】的含义如下∶
将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字,偏移地址为 bx 中的数值加上 si 中的数值,段地址在 ds 中。
数学化的描述为∶(ax)=((ds)*16+(bx)+(si) )

该指令也可以写成如下格式(常用)∶
mov ax,[bx][si]

1.9 [bx+si+idata] 和 [bx+di+idata]

注:【bx+si+idata】和【bx+di+idata】的含义相似

【bx+si+idata】表示一个内存单元,它的偏移地址为(bx)+(si)+idata(即 bx 中的数值加上si中的数值再加上 idata)。
指令mov ax,【bx+si+idata】的含义如下∶
将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字,偏移地址为 bx中的数值加上si中的数值再加上idata,段地址在 ds 中。
数学化的描述为∶(ax)=((ds)*16+(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

1.10 不同的寻址方式的灵活应用

(1)【idata】用一个常量来表示地址,可用于直接定位一个内存单元;
(2)【bx】用一个变量来表示内存地址,可用于间接定位一个内存单元;
(3)【bx+idata】用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元;
(4)【bx+si】用两个变量表示地址;
(5)【bx+si+idata】用两个变量和一个常量表示地址。


思考:

程序中经常需要进行数据的暂存,怎样做将更为合理 ?

这些数据可能是寄存器中的,也可能是内存中的。我们可以用寄存器暂存它们,但是这不是一个一般化的解决方案,因为寄存器的数量有限,每个程序中可使用的寄存器都不一样。我们希望寻找一个通用的方案,来解决这种在编程中经常会出现的问题。

显然,我们不能选择寄存器,那么可以使用的就是内存了。可以考虑将需要暂存的数据放到内存单元中,需要使用的时候,再从内存单元中恢复。这样我们就需要开辟一段内存空间。

一般来说,在需要暂存数据的时候,我们都应该使用栈。栈空间在内存中,采用相关的指令,如 push、pop 等,可对其进行特殊的操作。

例:
在这里插入图片描述
解:(栈段暂存数据外层循环cx的值,push&pop)

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 
stacksg 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 
        
  s0:   push cx           ;将外层循环的cx值压栈
        mov si,0 
        mov cx, 3         ;cx 设置为内层循环的次数
        
   s:   mov al,[bx+si]
        and al,11011111b 
        mov [bx+si], al 
        inc si 
        loop s
         
        add bx, 16
        pop cx             ;从栈顶弹出原 cx的值,恢复 cx      
        loop s0            ;外层循环的loop 指令将 cx 中的计数值减1

        mov ax, 4c00H 
        int 21H

codesg ends 
end start

总结:
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hvk_l

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值