【发布时间】:2010-06-30 21:51:59
【问题描述】:
我知道这是一个更“重”的问题,但我认为它也很有趣。它是of my previous questions about compiler functions 的一部分,但我解释得非常糟糕,很多人只回答了我的第一个问题,所以它是:
所以,如果我的知识是正确的,现代 Windows 系统使用分页来切换任务并确保每个任务在内存中都有适当的位置。所以,每个进程从 0 开始都有自己的位置。
当多任务生效时,我相信内核必须将所有重要的寄存器保存到任务的堆栈中,而不是保存当前的堆栈指针,更改页面条目以切换到另一个进程的物理地址空间,加载新的进程堆栈指针,弹出保存的寄存器并通过调用弹出的指令指针地址继续。
由于这个很好的特性(分页),每个进程都认为它有很好的平坦内存触手可及。因此,没有远跳转、远指针、内存段或数据段。一切都很好而且是线性的。
但是,当进程没有更多的分段时,为什么编译器仍然在堆栈上创建变量,或者当全局直接在其他内存空间中,而不是直接在程序代码中?
举个例子,我有一个C代码:int a=10;
翻译成(Intel 语法):mov [position of a],#10
但是,实际上您在 RAM 中占用的字节数比需要的多。因为,前几个字节取实际指令,在该指令完成后,有一个包含值 10 的新字节。
为什么,而不是这个,当不需要切换任何段(从而降低处理速度)时,不仅仅是像这样直接将值 10 编码到程序中:
xor eax,eax //just some instruction
10 //the value iserted to the program
call end //just some instruction
因为编译器知道每条指令的确切位置,所以在操作该变量时,它只会使用它的地址。
我知道,const 变量可以做到这一点,但当你无法更改它们时,它们并不是真正的变量。
我希望我能很好地解释我的问题,但我仍在学习英语,所以请原谅我的语法甚至语义错误。
编辑:
我已经阅读了你的答案,看来我可以根据这些修改我的问题:
所以,这里有人说,全局变量实际上是直接附加到程序中的那块值,我的意思是,当变量是全局时,它是附加到程序的末尾,还是只是在执行,而不是直接在堆上的堆栈上?
如果第一种情况 - 附加到程序本身,为什么甚至存在局部变量?我知道,你会因为递归而告诉我,但事实并非如此。调用函数时,可以将任意内存空间压入栈中,因此没有程序存在。
我希望你能理解我,内存的使用总是效率低下,当某个值(甚至 0)从某个指令在堆栈上创建时,因为你需要在程序中为该指令而不是实际 var 留出空间。就像这样:push #5 //instruction that says to create local variable with integer 5
而这条指令只是让数字 5 在堆栈上。请帮助我,我真的很想知道为什么会这样。谢谢。
【问题讨论】:
-
我认为它是一个变量这一事实意味着它是对可以更改的值的一些引用。如果你做了
int a = 10; a = 5;,代码应该是什么样子?或者你只是在值不变的情况下询问编译器优化? -
我认为他的意思是:为什么不是所有的局部变量都优化为全局变量(其在内存中的位置是恒定的)。变量在内存中的存储方式似乎也存在一些严重的混淆。
标签: c windows compiler-construction