打印

不要有火*味

[复制链接]
楼主: djyos
手机看帖
扫描二维码
随时随地手机跟帖
21
xwj| | 2008-2-24 21:33 | 只看该作者 回帖奖励 |倒序浏览

LZ的理解过于片面,圈圈17楼的才是正解

非要“从计算机实现方面来回答”的话除了读写不一致的特殊寄存器(比如SBUF),其他的100%能实现,只要你有耐心去分析汇编后的代码来确定编译器的编译、分配、优化规则;

但是!
你必须的明白并确信:
不同的处理器、不同的编译器、甚至不同的优化方式或优化级别,它们生成的代码和内存分配方式完全不同,一种方法条件稍微更改可能就不对了!
这根本就不是通用的方法,也根本就没必要这么做!这么做也只有百害而无一利!


不讨论更不建议讨论这个的最根本的原因还是C下面变量作用域的理解和定义,搞懂了并能正确选择“作用域”,根本就不存在这样的问题



我之所以一再发贴回复、说明,只是怕你的所谓“高深理论”会误导初学者!
请初学者或没搞清楚“作用域”的,看贴时一定先去看书,并且多想一想!

切记!
切记!

使用特权

评论回复
22
computer00| | 2008-2-24 21:51 | 只看该作者

问题的根源还是在于我们更习惯这样的逻辑思维

所以我们这样去定义。


如果我们的C语言一开始就定义了可以这样调用的,那么也就不会存在着如你所说的“都要求“你清楚特定CPU和特定编译器的行为,用非常手段””
问题了,因为任何C编译器都必须要支持这个功能。假设标准C语言规定了可以这样调用,那么我们直接调用就行了,不用做特殊考虑,要搞清楚这个因果关系。

理所当然,对于不同的处理器,肯定是要开发不同的C编译器的。那么这个功能是在开发编译器的时候加上去的,而不是我们编程的时候。

另外,对于函数指针调用这些问题,我想通过由编译器自己添加传递类似象C++中的this指针那样的过程,应该也是可以实现的,具体是否
可行,懒得去细想了,很烦琐的。

我觉得这个问题的关键点不在于如何去实现编译,而更关键的是如何方便我们编程,以及符合我们自己的逻辑思维。

使用特权

评论回复
23
wolver| | 2008-2-24 21:57 | 只看该作者

re:16楼,你在钻牛角尖!

可能你的程序简短,只有两个函数,因此在gcc编译应用中,你通过“非常”手段获得SP。如果你的函数段或局部变量多了,你无法预测SP和它们的变量位置。

但事无绝对!你可以自己写ld的脚本连接描述文件,来定位精确函数段和局部变量分配位置...

楼主连gcc都没学精,“嵌入式系统开发功力”麻...就不想多说了。

使用特权

评论回复
24
maychang| | 2008-2-24 21:59 | 只看该作者

21楼22楼二位的回复才是开发功力的体现

楼主就不要谈“功力”了,所谓“行家一伸手,就知有没有”。

使用特权

评论回复
25
平常人| | 2008-2-24 22:05 | 只看该作者

抬杠:从计算机实现角度来理解楼主的题目

因为任何一种计算机程序设计语言都有函数变量作用域的规定,可以设想有一种计算机,为了更好地实现变量作用域的保护,内存的保护是依照函数作用范围提供,这样因为硬件的保护机制,无论如何被调用函数无法访问母函数中的变量。
-----------------------------

另外6楼的论点也十分重要:按照17楼的说明fa()调用fb()时,编译器有办法知道变量a的位置,但如果另一个fc()也调用fb()时,fb()如何操作呢?fc()中可能有一个对应的变量a,也可能没有。

再进一步,即使fb()可以访问fa()作用域下的变量,fa()如何知道这个变量是否被修改过,如果被修改过,fa()做何处理?

-----------------------------
楼主也在16楼承认,这个命题本身逻辑上荒唐,执行上困难,只是在特定环境中用“非常”手段;但问题是这种“非常”手段是否有必要,C语言提供了手段让你实现在被调用函数访问母函数中变量的方法,你只需要调用fb时把变量a的地址传下去即可:
void fa(void)
{
    int a;
    fb(&a)
}
void fb(int *pa)
{
  *pa = 0;
}
何必兜一个大圈子?
-----------------------------

完全同意17楼的观点,母函数的变量保存在哪里,编译器是知道的,因此16楼所说的计算机实现角度讲子函数不知道母函数变量的论断是错误的!

所以这个问题还是要从程序设计理论的角度去分析,可以说计算机完全是程序设计的理论去实现的,如果果真程序设计的理论要求子函数可以访问母函数的变量,实现这样的要求并不难,编译器会很好地做到的。

使用特权

评论回复
26
xwj| | 2008-2-24 22:21 | 只看该作者

呵呵,LS所说的情况很常见,对于有MMU的CPU超出“作用域”的

对于有MMU(内存控制器)的CPU,超出“作用域”的话,访问就必然被拒绝,并触发内存访问错误中断

当然,这种情况下,通过一系列的权限、优先级切换,人工改变作用域,仍然可以实现“非法”访问,但这实际上还是有安全措施认可了的正常访问



只有严格控制了作用域,操作系统的安全才得到真正的保护,比如100%保证Guest用户无法获得Administra用户的密码、文件,
否则(没有MMU的话),任何电脑系统都将毫无安全可言

使用特权

评论回复
27
djyos|  楼主 | 2008-2-24 22:36 | 只看该作者

不要有火*味

    这本身就是极具争议性的问题,是没有唯一正确答案的,能对这个问题提出独到的见解的,难倒不能算答对么?不能算有一定功力么?
    计算机实现确实是根据程序设计理论来的,但是,C语言也确实是在不违反程序设计理论的前提下,它的语法是按照计算机怎么实现容易就怎么来的,这两者并不矛盾。

补充说明:28楼没有仔细看本楼。

使用特权

评论回复
28
平常人| | 2008-2-24 22:48 | 只看该作者

程序设计理论不是按照计算机怎么实现容易就怎么来的

请问设计C++,Java等OOP语言的出发点是按照计算机怎么实现容易就怎么来的吗?

使用特权

评论回复
29
computer00| | 2008-2-24 22:57 | 只看该作者

回复一下25楼

按照17楼的说明fa()调用fb()时,编译器有办法知道变量a的位置,但如果另一个fc()也调用fb()时,fb()如何操作呢?fc()中可能有一个对应的变量a,也可能没有。

编译器可以这么干:如果没有全局变量的a,但是又存在着另一个fc()也调用fb(),并且fc中无a时,那么编译通不过,抛出变量未定义错误。

使用特权

评论回复
30
xwj| | 2008-2-24 23:03 | 只看该作者

是的,既然是C语言,那就只能按C“语言”的规定来定义编译

而不是按“从计算机实现方面来回答”来定的

合格的编译器,就必须的让它自己的每一条语句解析、每一个编译行为都满足“C语言”的规定和标准
而不能限制死超出规定的操作的,拿就是漏洞(但不是BUG)


当然,对于应用者,只要经验够丰富、够聪明,是可以钻法律(规定)的空子的,也就是用合法的语句(手段)来实现非法的操作(目的)
但是,
一则这不是人人都可以做到或任何场合都可以用同样的方法做到的;
二者这样做一般也是不允许的,不合规定的很可能就会为此付出代价(错误、BUG、死机等);
三则是完全有更简单、更通用且合乎规范绝对安全的方法,又何必这么做呢?又何必如此的费力不讨好呢???


有的时候“非典”确实能带来一定的便利(不一定的),但随处乱用“非典”并且随意传播、推荐大家“非典”的话,可是会被打PP的哦

使用特权

评论回复
31
judge| | 2008-2-24 23:16 | 只看该作者

我以为啥高深的东西。 经不起推敲啊。

嵌入式定义也很广,拿一个编绎环境说事,太勉强了。
重剑无锋,大巧不工。    小技巧讲的太多。未必是好事。

使用特权

评论回复
32
mikesullen| | 2008-2-25 02:15 | 只看该作者

一道破题,不要与嵌入式系统扯上关系

大家可以争论出很多理论来,但这和嵌入式系统没有必然的什么关系。。
楼主的话说的有点大了。。。真的。。。

使用特权

评论回复
33
HWM| | 2008-2-25 08:08 | 只看该作者

看了实在是忍不住了,什么母函数,子函数,全都是扯蛋!

若fb()是在fa()内定义的,a就完全可以被fb()使用,因为它限制了在fa()外对fb()的调用(PASCAL就可以实现)。但在C中所有函数定义都是在顶级实现的,正如LZ所示,fb()并不从属于fa(),又如何允许访问与它同级的函数内的变量呢。

使用特权

评论回复
34
dld2| | 2008-2-25 08:14 | 只看该作者

莫名其妙帖留名

使用特权

评论回复
35
mohanwei| | 2008-2-25 08:41 | 只看该作者

人为规定不能访问而已,如果规定可以,实现这样的C

编译器还是不难的。

类似于变量定义,传统的规定是,定义在函数开头,但是现在的VC,BC……还有谁遵守它?

使用特权

评论回复
36
sz_kd| | 2008-2-25 09:28 | 只看该作者

路过留名

使用特权

评论回复
37
gooog| | 2008-2-25 10:24 | 只看该作者

理论指导实践

使用特权

评论回复
38
yewuyi| | 2008-2-25 13:13 | 只看该作者

所长上来打他PP~~

呵呵,那样的实现即无必要也不安全,更不容易看清,如果真那么用,那么不睡觉也会做噩梦的~~

使用特权

评论回复
39
龙飞天下| | 2008-2-25 14:40 | 只看该作者

如果保证了fb()只在fa()中调用是完全可以的

也就是保证fb()是子,fa()是母的关系。就像儿子去拿着母亲的钱去买东西是完全合法的。前提是这个是亲生子,而不是偷生子。
fa()
{
   int a;
   fb(a)
}

fb(a)
{
a=1;
}

使用特权

评论回复
40
HWM| | 2008-2-25 16:49 | 只看该作者

LS:你拿什么来保证他们是母子关系?亲子鉴定?

这不仅是偸生子,还可能是“**”。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则