user-0 提问: c语言，实际上就是函数调用

回复:
user: user-1
content: 25楼  引用 25 楼 hdt 的回复:建议了解 8086 14个寄存器 数据寄存器 A B C D 指针寄存器 SP BP 变址寄存器 SI DI 控制寄存器  IP(注意 这个与运行代码有关)  FLAG （通过标志位确定下一步如何执行） 段寄存器 CS 代码段寄存器； DS数据段寄存器； SS 堆栈段寄存器； ES 附加段寄存器； 注意红字，你应该能想到代码是在内存中代码段的，通过IP确定执行哪一个代码 ，所以寄存器中间不会存储代码！ 楼上对于8086CPU来讲，上述的描述是对的。使用IP与CS配合到内存代码段读取下一个指令O(∩_∩)O 而我所讲的是目前，新型CPU(当然兼容8086)内部结构，及优势如图这种CPU当然可以当作8086来用O(∩_∩)O

user: user-2
content: 引用 29 楼 zhao4zhong1 的回复:试问哪个厂商敢只出品新CPU，而不附带出品最能发挥该型号CPU性能的汇编器或C编译器？！  80386位早就推出了，试问真正32操作系统何时推出！

user: user-3
content: 《The Intel 64 and IA-32 Architectures Software Developer's Manual》

user: user-3
content: 试问哪个厂商敢只出品新CPU，而不附带出品最能发挥该型号CPU性能的汇编器或C编译器？！

user: user-1
content: 楼主借你的帖子回答一些东东，谢谢了O(∩_∩)O  首先，感谢赵4老师，《The Intel 64 and IA-32 Architectures Software Developer's Manual》已经下载了共计11个PDF文件。   大家在学习汇编语言或C语言时不必过分纠结于自己的电脑是什么类型的CPU，目前最新的CPU都提供了三种工作模式，如上图所示，虚拟8086模式，保护地址模式和实地址模式。一般考虑软件的兼容性通常使用虚拟8086模式比较好O(∩_∩)O

user: user-2
content: 还有就是想问一下，目前的主流的c++编译器，那个是完全符合这个新cpu要求的？

user: user-2
content: 引用 26 楼 HomerRo 的回复:25楼  [quote=引用 25 楼 hdt 的回复:] 建议了解 8086 14个寄存器 数据寄存器 A B C D 指针寄存器 SP BP 变址寄存器 SI DI 控制寄存器  IP(注意 这个与运行代码有关)  FLAG （通过标志位确定下一步如何执行） 段寄存器 CS 代码段寄存器； DS数据段寄存器； SS 堆栈段寄存器； ES 附加段寄存器； 注意红字，你应该能想到代码是在内存中代码段的，通过IP确定执行哪一个代码 ，所以寄存器中间不会存储代码！ 楼上对于8086CPU来讲，上述的描述是对的。使用IP与CS配合到内存代码段读取下一个指令O(∩_∩)O 而我所讲的是目前，新型CPU(当然兼容8086)内部结构，及优势如图这种CPU当然可以当作8086来用O(∩_∩)O[/quote] 哦，看看我的知识体系落后了！

user: user-4
content: 引用 11 楼 qq_36179095 的回复:[quote=引用 1 楼 自信男孩的回复:]函数都有自己的函数栈，main函数也是，程序在运行时是将可执行文件加载到内存，即将函数load到栈上，根据栈的特性逐步执行。所以，不是将函数放到CPU寄存器，而是放在栈上的吧。个人见解 cpu工作的时候，运行的肯定是cpu的寄存器里的数据，所以某段数据要执行的时候，系统就自动把它放到寄存器中。不是么[/quote] 不一定是寄存器的，有可能直接从内存里拿

user: user-2
content: 建议了解 8086 14个寄存器 数据寄存器 A B C D 指针寄存器 SP BP 变址寄存器 SI DI 控制寄存器  IP(注意 这个与运行代码有关)  FLAG （通过标志位确定下一步如何执行） 段寄存器 CS 代码段寄存器； DS数据段寄存器； SS 堆栈段寄存器； ES 附加段寄存器； 注意红字，你应该能想到代码是在内存中代码段的，通过IP确定执行哪一个代码 ，所以寄存器中间不会存储代码！

user: user-1
content: 教课书上所讲到的内存四区，以及函数调用时的压栈数据到内存中等都是为了同学们的理解需要。其实，现在的计算机cpu内存除了指令寄存器包存将要执行的几条指令序列，数据寄存器保存中间数据，结果数据和将要用到的数据外。还有一级指令缓冲和二级指令缓冲，一级数据缓冲和二级数据缓冲，i7与i5系列还有高达3M字节的三级缓冲区，集成到cpu中用于保存数据与指令和作为堆栈区，用以加快程序的执行速度，同时减低计算机的功耗。

user: user-0
content: 引用 21 楼 HomerRo的回复:更正一下，main()函数在调用fun()函数时，首先要进行压栈，把main()函数运行到M点时的所有相关变量的数据，包括：未使用的数据，中间数据，用过的的数据等都进行压栈处理，等从fun()函数返回时，再把这些数据出栈，恢复到main()函数在调用fun函数前M点的运行环境，继续向下运行。其中fun()函数的返回值一般在eax寄存器中。 非常认可你这个说法，我昨天晚上也想了一下，确实不应该是只保存未执行的数据。 在此声明一下:我之前的说法是错误的

user: user-3
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

user: user-2
content: 引用 15 楼 qq_36179095 的回复:[quote=引用 14 楼 倦怠的回复:]lz把必要条件说成了充分条件 就好比，你可以说人是胎生的，但你不能说胎生的就是人 这个明白，就好比，你是人，但人不是你，你只是人的一个实例而已[/quote] 又错了，此人非彼人也，逻辑不要从字面上去解读，而是要把他符号化。 计算机语言不好，可以通过练习加强。天生的逻辑差几乎无法弥补！

user: user-1
content: 更正一下，main()函数在调用fun()函数时，首先要进行压栈，把main()函数运行到M点时的所有相关变量的数据，包括：未使用的数据，中间数据，用过的的数据等都进行压栈处理，等从fun()函数返回时，再把这些数据出栈，恢复到main()函数在调用fun函数前M点的运行环境，继续向下运行。其中fun()函数的返回值一般在eax寄存器中。

user: user-1
content: lz说的基本都对，这是C语言的函数调用过程O(∩_∩)O 个人认为在调用下一个函数时，如main()调用fun()时有个压栈过程，可能就是楼主所说的把main()函数未使用的数据保存到内存去吧，然后，调用fun()函数。 c语言的内存分为四个区，分别是“栈区,堆区,全局区,代码区”其中全局区也包括字符常量保存区，后二个区应该是只读区吧，所以，把数据保存到内存区，同保存到 栈区，也是这么一个意思O(∩_∩)O。CPU的寄存器区不同的寄存器在程序运行时要用到，在函数返回上一级函数时，也要用来保存返回值的。 据说，c语言内存有四区在面试时经常要考到。

user: user-2
content: 引用 18 楼 qq_36179095 的回复:[quote=引用 16 楼 倦怠的回复:][quote=引用 15 楼 qq_36179095 的回复:] [quote=引用 14 楼 倦怠的回复:]lz把必要条件说成了充分条件 就好比，你可以说人是胎生的，但你不能说胎生的就是人 这个明白，就好比，你是人，但人不是你，你只是人的一个实例而已[/quote] 又错了，此人非彼人也，逻辑不要从字面上去解读，而是要把他符号化。 计算机语言不好，可以通过练习加强。天生的逻辑差几乎无法弥补！ [/quote] 你这个解释说服不了我，[/quote] 我回帖从来没打算说服任何人，每个人都有各自的看法。 我只是指出问题！

user: user-0
content: 引用 16 楼 倦怠的回复:[quote=引用 15 楼 qq_36179095 的回复:] [quote=引用 14 楼 倦怠的回复:]lz把必要条件说成了充分条件 就好比，你可以说人是胎生的，但你不能说胎生的就是人 这个明白，就好比，你是人，但人不是你，你只是人的一个实例而已[/quote] 又错了，此人非彼人也，逻辑不要从字面上去解读，而是要把他符号化。 计算机语言不好，可以通过练习加强。天生的逻辑差几乎无法弥补！ [/quote] 你这个解释说服不了我，

user: user-3
content: 是吗？！#include <stdio.h> #include <setjmp.h> jmp_buf mark; int i=0; void c() {     printf( "c in\n");     if (1==i%2) longjmp( mark, i );     printf( "c out\n"); } void b() {     printf( "b in\n");     c();     printf( "b out\n"); } void a() {     printf( "a in\n");     b();     printf( "a out\n"); } void main( void ) {    int jmpret;    jmpret = setjmp( mark );    printf( "Start %d\n",jmpret);    if( jmpret == 0 ) {        printf( "First\n");        a();        i++;        a();    } else {        printf( "Second\n");    } } //Start 0 //First //a in //b in //c in //c out //b out //a out //a in //b in //c in //Start 1 //Second //

user: user-5
content: 参考，C语言反汇编  http://www.cnblogs.com/thammer/p/5303379.html

user: user-5
content: 这和C语言没关系吧  对于裸机ARM  在CPU刚上电初始化时，SP（堆栈指针寄存器R13）还没有设置，必须使用汇编先设置一个内存地址到R13中，才可以正常调用C中函数  因为C编译器，对函数编译时，首先会有压栈操作，中间是函数体，最后是出栈操作