C语言和汇编语言的关系?

问题有点长,希望大家看完,谢谢!
听说过C语言经过编译以后会生成汇编代码?可是我在TC2.0里面
编译C程序后只看到了obj文件和exe文件,asm文件在哪?

我写了一个C语言程序:
#include<stdio.h>
int main(){
int i =50;
int* ip = &i;
int** ipp = &ip;
printf("the address of i is %d\n",&i);
printf("the address of ip is %d\n",&ip);
printf("the address of ipp is %d\n",&ipp);
return 0;
}

在vc6.0里面编译执行后运行结果:
the address of i is 1245052
the address of ip is 1245048
the address of ipp is 1245044
我不明白的是: 为什么每次程序编译运行的结果都是一样的???

还有,我发现这三个地址之间都差4,是不是相当于汇编里面,
在数据段中这三个变量是连续定义的,所以地址也是连续的,
并且说明了C语言中int类型的变量占4个字节,int的指针类型
也占4个字节.

(再问一个问题,为什么C语言里面int类型的变量占4个字节?)

这里的地址1245052,1245048,1245044是不是对应着C语言编译
后生成汇编文件中在数据段范围中的地址?

还有一个问题。。
C语言中分配内存空间的一个语句是:
int *p = null;
p = (int *)malloc(sizeof(int)*100);
是在堆里面分配的空间,可是在汇编里面只有代码段,数据段,
堆栈段,还有附加段,"堆" 在那个段中?
我一直认为“堆栈”就是“栈”的意思,难道说“堆栈”是
“堆”+“栈”??

还有,在8086cpu中,寄存器是16位的,所以偏移地址是16位的,
所以一个段最大就是64KB,如果我在malloc函数里面写:
int *p = null;
p = (int *)malloc(sizeof(int)*1000000000000000000);
也就是说开辟了一个大于64KB的堆空间,会有什么后果?

问题有点多,谢谢大家看到最后这句话!

程序员编写的C语言代码,首先要经过C语言编译器,生成汇编代码,这个过程称为编译阶断,当C语言编译器生成汇编代码后,再调用汇编器来将汇编代码编译成汇编指令。

这是一种站在巨人肩人的作法,最早的C++编程语言也是这样的实现方法,只不过那时候叫Cfront程序,Cfront程序的作用是将C++代码转换成C语言代码,类似于一个文本处理器,然后再调用C语言编译器,将C源码编译成汇编代码,然后再调用汇编器将汇编代码编译成机器码。

这个过程,在Windows平台上不容易操作,但是在Linux平台上很容易看到。以gcc这款c语言编译器为例,它实际上是四个小程序。
cp: c语言预处理程序,有它负责进行预处理操作。
cc: C语言编译器,它负责将C源码编译成汇编代码。
as: 汇编器,它负责将汇编代码编译成机器码,一般使用gcc test.c这样的命令编译C语言时,会生成一个a.out的程序,它实际上指的就是as ouput,即汇编器输出文件。
link: 链接器,它负责将汇编器输入的机器码和库打包成一个操作系统可以运行的可执行文件,在Linux上的可执行文件格式是ELF格式,这个格式的实现是有链接器来完成的。
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2017-10-06
编译了以后地址确实是确定的,但操作系统会把它映射到物理地址上,所有每次运行的物理地址都不同。

“还有,我发现这三个地址之间都差4,是不是相当于汇编里面,
在数据段中这三个变量是连续定义的,所以地址也是连续的,
并且说明了C语言中int类型的变量占4个字节,int的指针类型
也占4个字节.”

是的,确实是这样编译的。int是32位的,就是4个字节了。32位系统的地址是32位的,指针就要4字节。

“还有一个问题。。
C语言中分配内存空间的一个语句是:
int *p = null;
p = (int *)malloc(sizeof(int)*100);
是在堆里面分配的空间,可是在汇编里面只有代码段,数据段,
堆栈段,还有附加段,"堆" 在那个段中?
我一直认为“堆栈”就是“栈”的意思,难道说“堆栈”是
“堆”+“栈”?? ”

操作系统管理堆内存,怎么实现的和系统有关吧。“堆栈”就是指栈内存。32位系统中ds,cs,es,都和16位系统有很大差别,具体看看cpu的保护模式,在32位系统中,堆在那个段中这种说法很难解释。

还有,在8086cpu中,寄存器是16位的,所以偏移地址是16位的,
所以一个段最大就是64KB,如果我在malloc函数里面写:
int *p = null;
p = (int *)malloc(sizeof(int)*1000000000000000000);
也就是说开辟了一个大于64KB的堆空间,会有什么后果?

那是16位计算机,现在的32位系统段大小是4g,64位就更大了(一言两语说不清楚)。
学习c语言不应考虑是怎么实现的,c是个高级语言。它把计算机系统抽象了出来,把计算机看成是图灵机,不同的系统上实现方法不同,所以学习c不应该去想它的汇编实现。实现细节就交给编译原理和操作系统这两门课吧。本回答被提问者采纳
第2个回答  2009-04-24
这么多问题!

1. 没有生成汇编,因为你没有加特定的选项,你查一下TC的帮助。默认当然生成obj和exe,让你执行它。

2. 打印出来的地址,是会改变的,因为是栈上的变量地址。你每次的结果一样不说明什么。你可以修改一下你的程序,比如把你的程序放在函数里面,在不同的地方调用。

3. C语言的int的宽度和底层硬件/操作系统有关,32-bit或者64-bit平台。

4. 地址1245052,1245048,1245044是不是对应着C语言编译
后生成汇编文件中在数据段范围中的地址?
不是,如上所述,是堆栈帧中局部变量的地址。

5. 堆栈=栈。 你要在汇编里面动态分配内存,不知道怎么弄。

6. malloc很大的空间肯定会出错。上限是多少?我觉得也许不能超过一个页面的大小(4k?)吧。我不确定。
第3个回答  2019-01-26
区别是很大的。c语言作为一种高级编程语言,是比较容易被人所理解的,但要经过编译器的编译,形成机器所能够理解的汇编语言,才能够被机器所理解。这两种语言的语法结构也很很大的差异。c语言的语言你可能已经了解一些了,那么我简单说说汇编语言。汇编语言(assembly
language)是面向机器的程序设计语言,实际上它是把机器码用助词符表示出来而形成的,它的语法结构一般为:操作码+操作数1+操作数2

以下是一个简单的汇编程序例子:
start:in
al,20h
mov
bl,al
in
al,30h
mov
cl,al
mov
ax,0
adlop:
add
al,bl
adc
ah,0
dec
cl
jnz
adlop
hlt
以上,每行是一个语句。可见,与c语言差别很大。
第4个回答  2009-04-24
用VC的话可以看到汇编码

因为这个地址是相对于程序自身进程的偏移,而不是在真实的物理内存中的地址,不受其他进程影响

变量是连续分配的

C语言没规定C是2还是4字节,只规定了int不超过long.各个编译器自己可以规定大小.比如VC就是4,TC是2

堆和栈是两个内存空间区域.栈里面是放局部变量的,堆是放malloc分配的空间.

最后一个问题不清楚,等待高人回答
相似回答