| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2378 人关注过本帖
标题:C语言如何指定堆栈的起始地址
只看楼主 加入收藏
绿茶盖儿
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:1
帖 子:363
专家分:1852
注 册:2011-9-3
结帖率:84.62%
收藏
已结贴  问题点数:50 回复次数:9 
C语言如何指定堆栈的起始地址
一个64位的程序,是否能够指定堆栈的起始地址为0x100000000,使得程序中的变量都分配在高于4G的内存中,也就是说变量的地址的高32位不为0,其目的是测试程序中是否有地址高位被截断的问题。

或者有没有其他方法来测试地址高位截断问题?

开发环境为win10+VS2017

恳请大家指教!
搜索更多相关主题的帖子: 指定 高位 堆栈 C语言 地址 
2020-07-29 15:18
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:17 
其目的是测试程序中是否有地址高位被截断的问题
听不懂

程序代码:
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    for( ; ; )
    {
        void* p = malloc( 0x10000 );
        printf( "%p\n", p );
        if( p >= (void*)0x100000000 )
            break;
    }
}
2020-07-29 16:51
绿茶盖儿
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:1
帖 子:363
专家分:1852
注 册:2011-9-3
收藏
得分:0 
回复 2楼 rjsp
你这个检测确实可以达到目的,不过代码量有点大,不太可能给每个变量都加一个这样的检测
2020-07-29 16:59
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
以下是引用绿茶盖儿在2020-7-29 16:59:01的发言:

你这个检测确实可以达到目的,不过代码量有点大,不太可能给每个变量都加一个这样的检测

我不知道你想干什么
2020-07-29 19:40
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
收藏
得分:17 
1、首先来说一下“是否能够指定堆栈的起始地址为0x100000000”这个问题。
我不知道你说的这个0x100000000的地址到底是物理地址还是线性地址,还是说是段内偏移地址(或者严格地说是逻辑地址)。当然说这一段话的前提是在x86平台上,其他平台可能是另外一回事。对于物理地址,x86保护模式(甚至是其他非实模式)下,用户程序是根本无法接触到物理地址的。对于线性地址,用户程序也是无法直接涉及的。因为x86平台下物理地址是CPU在特定场合下给操作系统设计人员提供的,其他场合也不能直接设计,除非操作系统设计人员压根就没打算从实模式切换到保护模式,实模式下确实在用物理地址。能够使用线性地址的地方也不是很多,也就是那几个特殊场景。只要是保护模式下的用户程序,编程过程中绝对用的是逻辑地址,而且程序猿也无法自己决定逻辑地址中的段选择符,程序猿自己能确定的也只是段内偏移。因为段选择符是由操作系统决定的。
但感觉你要问的应该是段内段内偏移吧。因为,既然你问这个问题,那么你应该没有接触过底层设计。
2020-07-29 19:49
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
收藏
得分:0 
2、我们来说一下“使得程序中的变量都分配在高于4G的内存中”的问题。
这个在x86_64平台上,理论上是可以实现的,因为x86_64位平台实际上是有48根地址总线,所以理论上用户程序的段内偏移是可以超过4GB这个地方的。但这也只是理论上,因为操作系统可能会对此做限制。你提到的“开发环境为win10+VS2017”,这个没有多大价值,因为现在可以做到在交叉编译,也就是说开发环境和运行环境不是同一个环境,要看用户程序的宿主环境到底是怎样的。
2020-07-29 19:55
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
收藏
得分:0 
3、我们来说一下“也就是说变量的地址的高32位不为0”的问题。
这个不是特别确定,但前面我提到了x86 64位系统的地址总线实际只有48根,但地址又是64位的,所以CPU在设计的做了特殊的处理,对于高位,确实都是设定高电平,也就是那些位的值是1,但具体这样处理了多少位,我没有具体看,Intel和AMD的貌似处理方式不太一样,需要你具体看看相关用户手册。如果你需要Intel的用户手册,我可以QQ发送给你。
2020-07-29 19:59
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
收藏
得分:0 
4、我们来说一下“其目的是测试程序中是否有地址高位被截断的问题。”
首先确实和rjsp一样,不是完全明白你的意思,但猜测你想表达的是“64位系统上,对于高于4GB的地址,是否又回环回从0开始,例如4GB+1B的地址,被处理成1B的地址了”。
如果你想表达的意思是我的这种猜测,可以明确的告诉你,高于4GB的地址,普通的区域确实没有你所谓的“截断”,5GB地址就是5GB地址,不可能变成4GB地址。但是,物理内存地址空间,X86_64平台会单独划分出几个很小但又非常重要的区域,这些区域有些被映射到显卡这些设备上,有些被重新映射到低端内存(例如1MB以下的一部分)。当然需要强调的是,这一段表述中的地址是物理地址,而不是用户程序直接接触到的逻辑地址中的段内偏移。所以,如果你要测试的是物理地址,严格地说你没有办法测试。
2020-07-29 20:06
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
收藏
得分:0 
5、我们来说一下测试的问题。
如果你想测试,那也只能测试逻辑地址中的段内偏移。测试代码也很简单,例如你想测试的是0xfffffffffffffff0这个地址,那么可以对这个无符号整数进行强转,使其变成一个地址(指针),然后对其进行读写,看看能否实现。
int * p = (int *)0xfffffffffffffff0;
*p = 0x12345678;
当然也可能我能力有限,这种测试做不到你想要的结果。你可以参考以下。
2020-07-29 20:11
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:17 
预先创建一个额外的堆,起始地址能满足要求就可以。
2020-07-29 21:36
快速回复:C语言如何指定堆栈的起始地址
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035935 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved