汇编语言———数据段、程序段、栈段

汇编语言 专栏收录该内容
19 篇文章 0 订阅

1. 段的概念

转载:https://blog.csdn.net/qq_38176439/article/details/69220124

 我们注意到,“段地址”这个名称中包含着“”的概念。这种说法可能对一些学习者产生了误导,使人误以为内存被划分成一个一个的段,每一个段都有一个地址。如果我们在一开始形成了这种认知,将影响以后对汇编语言的深入理解和灵活应用。

 

    其实,内存并没有分段,段的划分来自于CPU。由于8086CPU用“基础地址(段地址×16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存

 

 如下图所示,我们可以认为:地址10000H~100FFH的内存单元组成一个段,该段的起始地址(基础地址)为10000H,段地址为1000H,大小为100H;我们也可以认为地址10000H~1007F、10080H~100FHH的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址为:1000H和1008H,大小都为80H。


分段

 

    以后,在编程时可以根据需要,将若干个地址连续的内存单元看做一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元

 

    有两点需要注意:段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址为16位,16位的寻址能力为64KB,所以一个段的长度最大为64KB。

 

内存单元地址小结

 

    CPU访问内存单元时,必须向内存提供内存单元的物理地址。8086CPU在内部用段地址和偏移地址移位相加的方法形成最终的物理地址。

 

    思考下面的两个问题。

 

    (1)观察下面的地址,你有什么发现?

 

    

物理地址

段地址

偏移地址

21F60H

2000H

1F60

 

2100H

0F60

 

21F0H

0060H

 

21F6H

0000H

 

1F00H

2F60H

 

    结论:CPU可以用不同的段地址和偏移地址形成同一个物理地址

 

 比如CPU要访问21F60H单元,则它给出的段地址SA和偏移地址EA满足SA×16+EA=21F60H即可。

 

    (2)如果给定一个段地址,仅通过变化偏移地址来进行寻址,最多可以定位多少个内存单元?

 

 结论:偏移地址16位,变化范围为0~FFFFH,仅用偏移地址来寻址最多可以寻64KB个内存单元。

 

 比如给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H~1FFFFH。

 

 在8086PC机中,存储单元的地址用两个元素来描述,即段地址和偏移地址。

 

    “数据在21F60H内存单元中。”这句话对于8086PC机一般不这样讲,取而代之的是两种类似的说法:①数据存在内存2000:1F60单元中;②数据存在内存的20000H段中的1F60H单元中。这两种描述都表示“数据在内存21F60H单元中”。

 

    可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。

 

    问:什么是段地址?

    答:段地址是针对内存的分段而言的,将每一段的段首地址定义为段地址。段地址的存在是由系统的分段存储决定的,通过段地址和偏移地址就能对数据进行寻访。

 

 问:什么是偏移地址?

 答:偏移地址也称为偏移量,由于8086/8088CPU内部的ALU只能进行16位的运算,而8086/8088有20条地址线,直接寻址能力1MB。因此,8086/8088所使用的20位物理地址,是由相应的段地址加上偏移地址组成的。

 

 问:为什么给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H~1FFFFH?

    答:把段地址1000H,乘以16,就是在1000H后面加上个0,可得到10000H。

 把10000H,加上偏移量的范围0000H~FFFFH,

 即有CPU的寻址范围:10000H~1FFFFH。

    ----------

 偏移量的范围0000H~FFFFH,就是16位二进制数的变化范围。




2. 段寄存器

1. CS和IP。

CS为代码段存器,IP为指令指针寄存器。CPU将CS:IP指向的内容当作当前的指令。

2. DS

存放要访问的数据的段地址。8086CPU自动取ds中的数据为内存单元的段地址。同时8086CPU不支持将数据直接送入段寄存器操作。
eg:将10000H的内容,送入al。

  • mov ax,1000
  • mov ds,ax
  • mov al,[0]

3. SS和SP

SS是栈的栈底,SP是栈顶元素的位置。(可能存在越界现象)
8086CPU提供了入栈和出栈的指令push和pop。
8086CPU的入栈和出站都以字为单位。所以POP总是加减2。
(详细的内容可以参看:https://blog.csdn.net/apollon_krj/article/details/70550667)



3.数据段、程序段、栈段

  • 数据段:存放数据的段。使用时候,用DS寄存器。
  • 程序段:用来存放程序的段。使用的时候,用CS和IP寄存器。
  • 栈段:是一个栈。使用时,初始设置SS和SP寄存器。

实战操作一波:把10000H~1000FH的空间当作栈;把20000H和20002H中的数据通过栈进行对换。程序的位置在30000H ~。

debug -a 30000
/*首先是在程序段中写程序*/

//建立栈
mov ax,1000
mov ss,ax
mov sp 0010//注意

//找到数据段的位置
mov ax,2000
mov ds,ax

//兑换内存中的数据
push [0]
push [2]
pop [0]
pop [2]


//执行程序段
-r cs
3000
-r ip
0

-t//多次执行

注意:实验的时候,要注意各个寄存器的变化。Debug的T命令在执行修改寄存器SS的指令的时候,下一条指令也会紧接着执行。

  • 9
    点赞
  • 2
    评论
  • 25
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值