VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
楼主: qqion1988

关于堆栈段SS寄存器的问题。

[复制链接]

0

主题

70

帖子

42.00

积分

新手上路

Rank: 1

积分
42.00
发表于 2020-7-22 13:30:01 | 显示全部楼层
据我所知,在实模式在,SS:SP共同寻址堆栈段,如此一来,寻址范围就是SS*16+0~SS*16+SP,SS*16是堆栈段的基地址。假设CPU是80X86系列,这种CPU用堆栈段的高地址作为栈底,也就是说SS*16应该是堆栈的栈顶(低地址),堆栈为空时,SP指向栈底,也就是说,SP应该指向堆栈段的末尾才对,不知道我的推理对不对?

*******************************************************************************
不对, 在 80x86 系列,SS*16D 应该是是高地址,而SP指向的仅仅是段内的偏移而已,只有 SS:SP才能描述是栈底还是栈顶。
回复

使用道具 举报

2

主题

18

帖子

15.00

积分

新手上路

Rank: 1

积分
15.00
 楼主| 发表于 2020-7-27 08:45:01 | 显示全部楼层
首先,SS*16D表示堆栈段的基地址,毋庸置疑。如果这个基地址是堆栈段的高地址,这个高地址也就是堆栈的栈底(高地址)。如此以来,SS*16D就表示了栈底,SP指向栈顶。当堆栈为空时,栈底=栈顶,SP->栈顶,此时只能为0,才能保证“栈顶=栈底”,即SS*16D=SS*16D+SP。若向堆栈中压入元素,SP该如何呢?增大还是减小?都不合适。增大,就成了堆栈向高地址发展;若SP减小,就有问题了,SP已经为0了,难道减到复数不成?如果SP初始化为堆栈大小,SS:SP定位到栈底,因为初始化时SP等于堆栈的大小,即非0,显然SS:SP要大于SS:0000,那么SS就只有指向堆栈段的低地址栈底了。
回复

使用道具 举报

0

主题

70

帖子

42.00

积分

新手上路

Rank: 1

积分
42.00
发表于 2020-7-27 10:00:01 | 显示全部楼层
首先,SS*16D表示堆栈段的基地址,毋庸置疑。如果这个基地址是堆栈段的高地址,这个高地址也就是堆栈的栈底(高地址)。如此以来,SS*16D就表示了栈底,SP指向栈顶。当堆栈为空时,栈底=栈顶,SP->栈顶,此时只能为0,才能保证“栈顶=栈底”,即SS*16D=SS*16D+SP。若向堆栈中压入元素,SP该如何呢?增大还是减小?都不合适。增大,就成了堆栈向高地址发展;若SP减小,就有问题了,SP已经为0了,难道减到复数不成?如果SP初始化为堆栈大小,SS:SP定位到栈底,因为初始化时SP等于堆栈的大小,即非0,显然SS:SP要大于SS:0000,那么SS就只有指向堆栈段的低地址栈底了。

****************************************************************************

初始化一个栈的时候,sp 怎么可能是0 呢,想想看下面的代码,在看看图

mov ax, stack
mov ss, ax
mov sp, 10h

执行完上面的代码结果是这样的

0x0000|      |
0x0001|      |
0x0002|      |
0x0003|      |
0x0004|      |
0x0005|      |
0x0006|      |
0x0007|      |
0x0008|      |
0x0009|      |
0x000A|      |
0x000B|      |
0x000C|      |
0x000D|      |
0x000E|      |
0x000F|______|<-------- ss
0x0010        <-------- sp






回复

使用道具 举报

0

主题

70

帖子

42.00

积分

新手上路

Rank: 1

积分
42.00
发表于 2020-7-27 11:00:01 | 显示全部楼层
也就是说 sp 是要根据栈的大小进行设定的
回复

使用道具 举报

0

主题

70

帖子

42.00

积分

新手上路

Rank: 1

积分
42.00
发表于 2020-7-27 11:30:01 | 显示全部楼层
上面图画错了

0x0000|      |
0x0001|      |
0x0002|      |
0x0003|      |
0x0004|      |
0x0005|      |
0x0006|      |
0x0007|      |
0x0008|      |
0x0009|      |
0x000A|      |
0x000B|      |
0x000C|      |
0x000D|      |
0x000E|      |
0x000F|______|<-------- ss
0x0010        <-------- ss:sp (sp = 10h)
回复

使用道具 举报

2

主题

18

帖子

15.00

积分

新手上路

Rank: 1

积分
15.00
 楼主| 发表于 2020-7-27 16:45:01 | 显示全部楼层
0x000F|______|<-------- ss
0x0010        <-------- ss:sp (sp = 10h)
根据上面第二行,得出SS的值为0。
根据上面第一行,得出SS不为零,令外SS是错误的,SS左移4bit后,应该是16的倍数,可是SS却指向0x000F。


回复

使用道具 举报

0

主题

70

帖子

42.00

积分

新手上路

Rank: 1

积分
42.00
发表于 2020-7-27 20:00:01 | 显示全部楼层

0x00000|      |
0x00010|      |
0x00020|      |
0x00030|      |
0x00040|      |
0x00050|      |
0x00060|      |
0x00070|      |
0x00080|      |
0x00090|      |
0x000A0|      |
0x000B0|      |
0x000C0|      |
0x000D0|      |
0x000E0|      |
0x000F0|______|<-------- ss = 0x000f
0x00100        <-------- ss:sp (sp = 0010h)

这回在算 呵呵
回复

使用道具 举报

2

主题

18

帖子

15.00

积分

新手上路

Rank: 1

积分
15.00
 楼主| 发表于 2020-7-28 00:30:01 | 显示全部楼层
>0x000F0|______|<-------- ss = 0x000f
>0x00100        <-------- ss:sp (sp = 0010h)

似乎堆栈的范围是:0x000F0~0x00100,SS*16D表示堆栈的栈顶(堆栈段低地址),SS*16D+SP寻址整个堆栈空间,初始化时,SP等于堆栈的大小,SS:SP指向栈顶(堆栈段高地址)。
回复

使用道具 举报

0

主题

70

帖子

42.00

积分

新手上路

Rank: 1

积分
42.00
发表于 2020-7-28 07:15:01 | 显示全部楼层
SS*16D表示堆栈的栈顶(堆栈段低地址),

应该是 堆栈的高地址

堆栈的范围是 0x000f:0000 - 0x000f:0010 20位的物理地址等于 0x000F0 + 0x0010 = 0x00100

回复

使用道具 举报

2

主题

18

帖子

15.00

积分

新手上路

Rank: 1

积分
15.00
 楼主| 发表于 2020-7-28 11:45:01 | 显示全部楼层
>0x00100        <-------- ss:sp (sp = 0010h)

SP初始化为堆栈的大小:0010h,堆栈的大小就应该是堆栈的范围大小。

>堆栈的范围是 0x000f:0000 ~ 0x000f:0010 ,20位的物理地址等于 0x000F0 + 0x0010 = 0x0100

上面的范围应该是:0x000f:0000 - 0x000f:0010 计算成20位的物理地址0x000F0+0000~0x000F0 + 0x0010 ,即:0x000F0~ 0x00100,堆栈的大小就是 0x00100-0x000F0 =0x0010。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表