c语言,实际上就是函数调用

淡怀 2017-10-13 10:56:12
欢迎指点。
...全文
773 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
HomerRo 2017-10-17
  • 打赏
  • 举报
回复
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
真相重于对错 2017-10-17
  • 打赏
  • 举报
回复
引用 29 楼 zhao4zhong1 的回复:
试问哪个厂商敢只出品新CPU,而不附带出品最能发挥该型号CPU性能的汇编器或C编译器?!
80386位早就推出了,试问真正32操作系统何时推出!
赵4老师 2017-10-17
  • 打赏
  • 举报
回复
《The Intel 64 and IA-32 Architectures Software Developer's Manual》
赵4老师 2017-10-17
  • 打赏
  • 举报
回复
试问哪个厂商敢只出品新CPU,而不附带出品最能发挥该型号CPU性能的汇编器或C编译器?!
HomerRo 2017-10-17
  • 打赏
  • 举报
回复
楼主借你的帖子回答一些东东,谢谢了O(∩_∩)O

首先,感谢赵4老师,《The Intel 64 and IA-32 Architectures Software Developer's Manual》已经下载了共计11个PDF文件。


大家在学习汇编语言或C语言时不必过分纠结于自己的电脑是什么类型的CPU,目前最新的CPU都提供了三种工作模式,如上图所示,虚拟8086模式,保护地址模式和实地址模式。一般考虑软件的兼容性通常使用虚拟8086模式比较好O(∩_∩)O
真相重于对错 2017-10-17
  • 打赏
  • 举报
回复
还有就是想问一下,目前的主流的c++编译器,那个是完全符合这个新cpu要求的?
真相重于对错 2017-10-17
  • 打赏
  • 举报
回复
引用 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] 哦,看看我的知识体系落后了!
自信男孩 2017-10-16
  • 打赏
  • 举报
回复
引用 11 楼 qq_36179095 的回复:
[quote=引用 1 楼 自信男孩的回复:]函数都有自己的函数栈,main函数也是,程序在运行时是将可执行文件加载到内存,即将函数load到栈上,根据栈的特性逐步执行。所以,不是将函数放到CPU寄存器,而是放在栈上的吧。个人见解
cpu工作的时候,运行的肯定是cpu的寄存器里的数据,所以某段数据要执行的时候,系统就自动把它放到寄存器中。不是么[/quote] 不一定是寄存器的,有可能直接从内存里拿
真相重于对错 2017-10-16
  • 打赏
  • 举报
回复
建议了解 8086 14个寄存器 数据寄存器 A B C D 指针寄存器 SP BP 变址寄存器 SI DI 控制寄存器 IP(注意 这个与运行代码有关) FLAG (通过标志位确定下一步如何执行) 段寄存器 CS 代码段寄存器; DS数据段寄存器; SS 堆栈段寄存器; ES 附加段寄存器; 注意红字,你应该能想到代码是在内存中代码段的,通过IP确定执行哪一个代码 ,所以寄存器中间不会存储代码!
HomerRo 2017-10-16
  • 打赏
  • 举报
回复
教课书上所讲到的内存四区,以及函数调用时的压栈数据到内存中等都是为了同学们的理解需要。其实,现在的计算机cpu内存除了指令寄存器包存将要执行的几条指令序列,数据寄存器保存中间数据,结果数据和将要用到的数据外。还有一级指令缓冲和二级指令缓冲,一级数据缓冲和二级数据缓冲,i7与i5系列还有高达3M字节的三级缓冲区,集成到cpu中用于保存数据与指令和作为堆栈区,用以加快程序的执行速度,同时减低计算机的功耗。
淡怀 2017-10-15
  • 打赏
  • 举报
回复
引用 21 楼 HomerRo的回复:
更正一下,main()函数在调用fun()函数时,首先要进行压栈,把main()函数运行到M点时的所有相关变量的数据,包括:未使用的数据,中间数据,用过的的数据等都进行压栈处理,等从fun()函数返回时,再把这些数据出栈,恢复到main()函数在调用fun函数前M点的运行环境,继续向下运行。其中fun()函数的返回值一般在eax寄存器中。
非常认可你这个说法,我昨天晚上也想了一下,确实不应该是只保存未执行的数据。 在此声明一下:我之前的说法是错误的
赵4老师 2017-10-14
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
真相重于对错 2017-10-14
  • 打赏
  • 举报
回复
引用 15 楼 qq_36179095 的回复:
[quote=引用 14 楼 倦怠的回复:]lz把必要条件说成了充分条件 就好比,你可以说人是胎生的,但你不能说胎生的就是人
这个明白,就好比,你是人,但人不是你,你只是人的一个实例而已[/quote] 又错了,此人非彼人也,逻辑不要从字面上去解读,而是要把他符号化。 计算机语言不好,可以通过练习加强。天生的逻辑差几乎无法弥补!
HomerRo 2017-10-14
  • 打赏
  • 举报
回复
更正一下,main()函数在调用fun()函数时,首先要进行压栈,把main()函数运行到M点时的所有相关变量的数据,包括:未使用的数据,中间数据,用过的的数据等都进行压栈处理,等从fun()函数返回时,再把这些数据出栈,恢复到main()函数在调用fun函数前M点的运行环境,继续向下运行。其中fun()函数的返回值一般在eax寄存器中。
HomerRo 2017-10-14
  • 打赏
  • 举报
回复
lz说的基本都对,这是C语言的函数调用过程O(∩_∩)O 个人认为在调用下一个函数时,如main()调用fun()时有个压栈过程,可能就是楼主所说的把main()函数未使用的数据保存到内存去吧,然后,调用fun()函数。 c语言的内存分为四个区,分别是“栈区,堆区,全局区,代码区”其中全局区也包括字符常量保存区,后二个区应该是只读区吧,所以,把数据保存到内存区,同保存到 栈区,也是这么一个意思O(∩_∩)O。CPU的寄存器区不同的寄存器在程序运行时要用到,在函数返回上一级函数时,也要用来保存返回值的。 据说,c语言内存有四区在面试时经常要考到。
真相重于对错 2017-10-14
  • 打赏
  • 举报
回复
引用 18 楼 qq_36179095 的回复:
[quote=引用 16 楼 倦怠的回复:][quote=引用 15 楼 qq_36179095 的回复:] [quote=引用 14 楼 倦怠的回复:]lz把必要条件说成了充分条件 就好比,你可以说人是胎生的,但你不能说胎生的就是人
这个明白,就好比,你是人,但人不是你,你只是人的一个实例而已[/quote] 又错了,此人非彼人也,逻辑不要从字面上去解读,而是要把他符号化。 计算机语言不好,可以通过练习加强。天生的逻辑差几乎无法弥补! [/quote] 你这个解释说服不了我,[/quote] 我回帖从来没打算说服任何人,每个人都有各自的看法。 我只是指出问题!
淡怀 2017-10-14
  • 打赏
  • 举报
回复
引用 16 楼 倦怠的回复:
[quote=引用 15 楼 qq_36179095 的回复:] [quote=引用 14 楼 倦怠的回复:]lz把必要条件说成了充分条件 就好比,你可以说人是胎生的,但你不能说胎生的就是人
这个明白,就好比,你是人,但人不是你,你只是人的一个实例而已[/quote] 又错了,此人非彼人也,逻辑不要从字面上去解读,而是要把他符号化。 计算机语言不好,可以通过练习加强。天生的逻辑差几乎无法弥补! [/quote] 你这个解释说服不了我,
赵4老师 2017-10-13
  • 打赏
  • 举报
回复
是吗?!
#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
//
「已注销」 2017-10-13
  • 打赏
  • 举报
回复
参考,C语言反汇编 http://www.cnblogs.com/thammer/p/5303379.html
「已注销」 2017-10-13
  • 打赏
  • 举报
回复
这和C语言没关系吧 对于裸机ARM 在CPU刚上电初始化时,SP(堆栈指针寄存器R13)还没有设置,必须使用汇编先设置一个内存地址到R13中,才可以正常调用C中函数 因为C编译器,对函数编译时,首先会有压栈操作,中间是函数体,最后是出栈操作
加载更多回复(12)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧