为什么需要使用栈结构?

在以往学习高级语言时,提到栈,下意识都会反映上来FILO,它是暂存数据的一种数据结构,但是为什么会用到栈?却一直讳莫如深,这是高级语言不会涉及到的底层的实现,最近在学习王爽老师的《汇编语言》,其中有一段点醒了我,现整理如下。

(一)这个问题的由来是对如下datasg段中每个单词改写为大写字母。

assume cs:codesg,ds:datasg
 
datasg segment
	db 'ibm             '
	db 'dec             '
	db 'dos             '
	db 'vax             '
datasg ends
 
codesg segment
start:	
 
codesg ends
end start

(二)分析:需要进行4x3次的二重循环,使用bx来定位要修改的行,用si定位要修改的列,用[bx+si]的寻址方式对目标单元进行寻址,实现如下

assume cs:codesg,ds:datasg
 
datasg segment
	db 'ibm             '
	db 'dec             '
	db 'dos             '
	db 'vax             '
datasg ends
 
codesg segment
start:	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
		
		mov ax,4c00h
		int 21h
 
codesg ends
end start

这种实现方式有个问题,由于2层循环使用同一个计数器cx,内层循环在运行过程中修改了外层循环的计数器,导致这个程序会无限循环下去,破坏其他内存地址的数据。

其中cx为命令loop对应循环次数所保存的寄存器。

给CX一个初始值(循环次数),当loop指令中标号(如:loop_one)所标识的地址被再次访问,CX的值减去1(即loop执行一次,CX值自减1)。当CX的值为0时结束循环,执行loop指令的下一条指令。

我在datasg段后面接着添加一个测试段,作一个测试

datasg segment
	db 'ibm             '
	db 'dec             '
	db 'dos             '
	db 'vax             '
datasg ends
 
ceshi segment
	db 'abc             '
	db 'def             '
	db 'ghi             '
ceshi ends

debug调试,程序运行前各寄存器的状态和程序的反汇编状态:

程序运行前各寄存器状态和反汇编的程序

内存状态:

程序循环4次之后,内存状态:

此时,程序退出内循环,再次进入外循环s0处,cx被重新赋值为3:

由此继续下一次内循环,将继续修改不应被修改的数据,进入无限循环……程序失控。

(三)为解决这个问题,选择在每次内循环开始之前,将外层循环的cx值保存起来,在进行外循环时再进行恢复:

codesg segment
start:	mov ax,datasg
		mov ds,ax
		mov bx,0
		
		mov cx,4
	s0:	mov dx,cx             #将外循环的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
                move cx,dx            #恢复cx的值
		loop s0
		
		mov ax,4c00h
		int 21h
 
codesg ends
end start

这样使用寄存器来对数据进行临时存储,在这样的小程序中固然可行,但若程序稍大些、复杂些,剩余的寄存器也不够我们使用的,所以引出使用内存空间来对数据进行暂存。

datasg segment
	db 'ibm             '
	db 'dec             '
	db 'dos             '
	db 'vax             '
	dw 0                     #开辟一个内存空间,暂存数据
datasg ends

但是这种方式会造成程序猿的极大困扰,要记得每个临时性数据在什么地方存储不是容易的事情,也不便于维护,这样很不方便使用。

最后引出栈的使用,开辟一个内存空间用做栈段,通过push和pop操作便捷地对临时性数据进行暂存,解放了程序猿要记忆和寻找数据内存地址的痛苦过程。

stacksg segment
	dw 0,0,0,0,0,0,0,0
stacksg ends

安全又便捷。

 

所以,为什么要使用栈这样的数据结构呢?

1.cpu内部寄存器数量有限。

2.解放程序猿。

转发:https://blog.csdn.net/benben_dog/article/details/100148313

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值