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

前面几节都比较简单,直接总结到最后一节

SI和DI

si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。
SI:Source index(源变址寄存器)
DI:Destination index(目的变址寄存器)

灵活运用

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

编程,将datasg段中的每个单词的头一个字母改为大写字母

asssume cs:codesg,ds:datasg
datasg sgement
db ‘1.file‘(省略后面的的空格)
db ‘2.edit’(**注意:**这里为了直观,每个字符串的后面都加上了空格符
每个长度为16个字节)
db ‘3.search’
db ‘4.view’
db ‘5.options’
db ‘6.help’
datasg ends
codesg segment
start:
codesg ends
end start
我们可以把上面的字符串看成,一个6行16列的二维数组。
在这里插入图片描述
分析上面问题
要把每个字符串的第4列的字符改成大写
我们运用6次循环,用一个变量R定位行,用常量3定位列。
大致的思路是
R=第一行的地址
mov cx,6
s: 改变R行,3列的字母为大写
R=下一行的地址
loop s

程序
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,6
s: mov al,[bx+3]
and al,11011111b
mov [bbx+3],al
add bx,16
loop s

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

可以看到我们最后是实现了,这里本来有一个PSP的数据区,但我们看到,指令中
mov ax,076A
这里数据段就是076A

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

assume cs:codesg,ds:datasg
datasg segment
db 'ibm '(这里和上面的题目一样是一共是16个字符没有的用空格)
db 'dec ’
db 'dos ’
db 'vax ’
datasg ends
codesg segment
start:
codesg ends
end start
这里我有一个自己解决问题的方法
我们可以确定这里有4行,也就是最开始我们就确定好,四次改变,一次循环改变四行第一列的字母,第二次循环改变第二字母…
当然我这个想法有个问题,要是数据里的字符串,不止4行呢?更多?
那是不是要写更多重复一样的代码段。
显然这里行不通,所以我们引进了双循环!
思路
R=第一行的地址;
mov cx,4
s0:C=第一列的地址
mov cx,3
s: 改变R行,C列的字母为大写
C=下一列的地址
loop s
R=下一行的地址
loop s0

程序
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0: 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
loop s0

仔细阅读上面这个程序,发现问题。
这个CX寄存器的值被改了,什么意思?
CX的寄存器只有一个,我们发现,进入内循环的时候CX的值已经被减少为0了
外循环也就不能执行了
怎么解决
这里我们再介绍一个寄存器dx
用来临时保存CX中的数值
如果我们可以保存进入循环后CX的值,最后回去的时候又把这个值返回给CX,这样就能保证外循环
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

这样些我们就能把问题解决,可还有个问题,我们知道,8086CPU的寄存器一共才14个如果每个程序段,都需要这么干,那是不是不行?万一DX已经用来存储其他数据了呢?
那就不行了
所以,这里我们可以指定单元内存去存储我们想要临时存储的数据
改进
assume cs:codesg,ds:datasg
datasg segment
db 'ibm '(同上)
db 'dec ’
db ’dos‘
db 'vax ’
db ‘0’
datasg ends
codesg segment
start :mov ax,datasg
mov ds,ax
mov bx,0
mob cx,4
s0:mov ds:[40H],cx
mov ds,ax
mov bx,0
mov cx,3
s: mov al,[bx+si]
and al,110111111b
mov [bx+si],al
inc si
loop s
add bx,16
mov cx,ds:[40H]
loop s0
mov 4c00h
int 21h
codesg ends
end start

上面这个程序,是可以的,但还有问题,要是多个数据的时候,你能记住你保存的每个数据的地址嘛?我想是很难的!
尤其是忘了,就完了
所以我们用栈,也就是所谓真栈保护
程序
assume cs:codesg,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,stacksg
mov ss,ax
mov sp,16
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0:push cx
mov si,0
mov cx,3
s: mov al,[bx+si]
and al,110111111b
mov [bx+si],al
inc si
loop s
add bx,16
pop cx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start

实验问题

编程,将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 :
codesg ends
end start

程序:
在这里插入图片描述
在这里插入图片描述
最后生成运行即可

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Back~~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值