汇编程序设计笔记(四),如何熟练实现数据段间数据的传输(使用栈来寄存数据)(王爽汇编语言实验七)
一.前言
汇编学习的过程参考了王爽老师的《汇编语言》第三版,在笔记当中会相应的书目页数,可以翻书查阅。
看到实验感觉可以写,但是开始写之后感觉寻址没思路的初学者可以参考下
本次实验的内容在《汇编语言》的172页实验7,实验七的核心在于寻址和除法运算,本篇是关于本实验的第四篇博客,是第二篇的延续,主要记录如何通过栈来寄存数据。
emmm…这篇博客之后应当琢磨一下措辞怎么才能说得更清楚些,虽然自己明白了,但写到最后感觉写的却不是很明白…
二.实现
(一)树立一个思想:寄存数据,首选栈
寄存器不够用啊,真的不够用!不能什么事都赖着寄存器
(二)在嵌套循环中使用栈寄存cx
1.如果使用了嵌套循环,那肯定非用栈寄存cx不可。
之前每次用loop的时候总会犹豫下循环标记应该放在哪,那么现在记好了,在这种情况下,
循环标记的位置放在push cx这句代码前总没错
mov cx,21
s0: push cx
mov cx,4 ;1层循环,用来定位字符串中的字符
s1: push cx
....
pop cx
loop s1 ;单个字符串赋值完成
....
loop s0
(三)在某些情况下为了复用寄存器而使用栈
1.直接看代码,这是实验7在复制年份字符串时的一段代码。
问题描述:我想在s0循环中完成所有所需数据的复制,包括年份,收入,雇员数量。
然而寄存器数量有限,所以要复用寄存器。
可是某些寄存器的值在循环中不断变化,不敢轻易地将寄存器初始化然后复用
s0: push cx
mov si,0
mov cx,4
s1: push cx ;复制字符串的内层循环
mov al,ds:[bp][si]
mov es:[bx][si],al
inc si
pop cx
loop s1
add bp,4
add bx,16
pop cx
loop s0 ;出外层循环
我想在s0循环的剩余部分中继续使用si,bp和bx,哪个合适?思考后看分析
2.分析:其实三个都可以!!!能不能复用的主要因素是看你要如何复用!
看起来有点说了等于白说,下面详细说明
3.对于这三个寄存器si,bp,bx,根据使用情况可以将他们归为两类
(1)情况一:si——在内层循环中*变化,不受外层循环的影响
你看这si,不管外层的cx怎么变,它在内层永远是从0变到3
(2)情况二:bx和bp——始终受外层循环的影响。
你看他俩,每次外层cx变化,他俩都要增加一点。
4.如果你的要在情况一下复用一个寄存器,那么恭喜你,这三个寄存器都可以使用,只要你在复用之前把寄存器的原值push一下存进栈里,复用结束之后你再pop一下取出来就可以了
但如果你要在情况二下复用一个寄存器,那么只有si可以供你复用了。复用的方法与上面一样。以下的代码是情况二的复用
s0: push cx
push si ;之后要复用si的值,故将si的初值入栈;这是我研究了老半天的核心步骤啊啊啊啊啊啊啊啊啊啊啊啊!!!
mov si,0
mov cx,4
s1: push cx ;字符串第1层循环;不可以在循环中初始化数据,数据只能在循环外面初始化
mov al,ds:[bp][si]
mov es:[bx][si],al
inc si
pop cx
loop s1
pop si ;恢复si的初值了!!!
mov ax,ds:[si+84]
mov es:[bx].5,ax
mov ax,ds:[si+86]
mov es:[bx].7,ax
add si,4
;收入复制完成
mov ax,ds:[di+168]
mov es:[bx].10,ax
add di,2
;雇员数目复制完成
add bp,4
add bx,16
pop cx
loop s0 ;出外层循环