C语言编译过程+CPU内部结构与寄存器+汇编语言+集成开发环境IDE
C语言编译过程
1.7.1 C程序编译步骤
C代码编译成可执行程序经过4步:
1)预处理:宏定义展开、头文件展开、条件编译等,同时将代码中的注释删除,这里并不会检查语法
2)编译:检查语法,将预处理后文件编译生成汇编文件
3)汇编:将汇编文件生成目标文件(二进制文件)
4)链接:C语言写的程序是需要依赖各种库的,所以编译之后还需要把库链接到最终的可执行程序中去
1.7.2 gcc编译过程
1) 分步编译
预处理:gcc -E hello.c -o hello.i
编 译:gcc -S hello.i -o hello.s
汇 编:gcc -c hello.s -o hello.o
链 接:gcc hello.o -o hello_elf
选项 |
含义 |
-E |
只进行预处理 |
-S(大写) |
只进行预处理和编译 |
-c(小写) |
只进行预处理、编译和汇编 |
-o file |
指定生成的输出文件名为 file |
文件后缀 |
含义 |
.c |
C 语言文件 |
.i |
预处理后的 C 语言文件 |
.s |
编译后的汇编文件 |
.o |
编译后的目标文件 |
2) 一步编译
gcc hello.c -o demo(还是经过:预处理、编译、汇编、链接的过程):
1.7.3 查找程序所依赖的动态库
1)Linux平台下,ldd(“l”为字母) 可执行程序:
2)Windows平台下,需要相应软件(Depends.exe):
1.8 CPU内部结构与寄存器(了解)
1.8.1 64位和32位系统区别
l 寄存器是CPU内部最基本的存储单元
l CPU对外是通过总线(地址、控制、数据)来和外部设备交互的,总线的宽度是8位,同时CPU的寄存器也是8位,那么这个CPU就叫8位CPU
l 如果总线是32位,寄存器也是32位的,那么这个CPU就是32位CPU
l 有一种CPU内部的寄存器是32位的,但总线是16位,准32位CPU
l 所有的64位CPU兼容32位的指令,32位要兼容16位的指令,所以在64位的CPU上是可以识别32位的指令
l 在64位的CPU构架上运行了64位的软件操作系统,那么这个系统是64位
l 在64位的CPU构架上,运行了32位的软件操作系统,那么这个系统就是32位
l 64位的软件不能运行在32位的CPU之上
1.8.2 寄存器名字(了解)
8位 |
16位 |
32位 |
64位 |
A |
AX |
EAX |
RAX |
B |
BX |
EBX |
RBX |
C |
CX |
ECX |
RCX |
D |
DX |
EDX |
RDX |
1.8.3 寄存器、缓存、内存三者关系
按与CPU远近来分,离得最近的是寄存器,然后缓存(CPU缓存),最后内存。
CPU计算时,先预先把要用的数据从硬盘读到内存,然后再把即将要用的数据读到寄存器。于是 CPU<--->寄存器<--->内存,这就是它们之间的信息交换。
那为什么有缓存呢?因为如果老是操作内存中的同一址地的数据,就会影响速度。于是就在寄存器与内存之间设置一个缓存。
因为从缓存提取的速度远高于内存。当然缓存的价格肯定远远高于内存,不然的话,机器里就没有内存的存在。
由此可以看出,从远近来看:CPU〈---〉寄存器〈---> 缓存 <---> 内存。
1.9 汇编语言
1.9.1 VS中C语言嵌套汇编代码(了解)
#include <stdio.h>
int main()
{
//定义整型变量a, b, c
int a;
int b;
int c;
__asm
{
mov a, 3 //3的值放在a对应内存的位置
mov b, 4 //4的值放在a对应内存的位置
mov eax, a //把a内存的值放在eax寄存器
add eax, b //eax和b相加,结果放在eax
mov c, eax //eax的值放在c中
}
printf("%d\n", c);//把c的值输出
return 0;//成功完成
}
1.9.2 VS反汇编
#include <stdio.h>
int main()
{
//定义整型变量a, b, c
int a;
int b;
int c;
a = 3;
b = 4;
c = a + b;
printf("%d\n", c);//把c的值输出
return 0;//成功完成
}
1)设置断点F9
2)选择反汇编按钮
3)根据汇编代码分析程序
1.10 集成开发环境IDE
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。
1.10.1 Qt Creator
Qt Creator是跨平台的 Qt IDE, Qt Creator 是 Qt 被 Nokia 收购后推出的一款新的轻量级集成开发环境(IDE)。此 IDE 能够跨平台运行,支持的系统包括 Linux(32 位及 64 位)、Mac OS X 以及 Windows。根据官方描述,Qt Creator 的设计目标是使开发人员能够利用 Qt 这个应用程序框架更加快速及轻易的完成开发任务。
快捷键 |
含义 |
Ctrl + i |
自动格式化代码 |
Ctrl + / |
注释/取消注释 |
Alt + Enter |
自动完成类函数定义 |
F4 |
.h 文件和对应.cpp 文件切换 |
F9 |
设置断点 |
F5 |
调试运行 |
Ctrl + r |
编译,但不调试运行 |
Ctrl + b |
编译,不运行 |
F10 |
next调试 |
F11 |
step调试 |
1.10.2 Microsoft Visual Studio
Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品。VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等,所写的目标代码适用于微软支持的所有平台。Visual Studio是目前最流行的Windows平台应用程序的集成开发环境。
1) VS常用快捷键
快捷键 |
含义 |
Ctrl + k,Ctrl + f |
自动格式化代码 |
Ctrl + k,Ctrl + c |
注释代码 |
Ctrl + k,Ctrl + u |
取消注释代码 |
F9 |
设置断点 |
F5 |
调试运行 |
Ctrl + F5 |
不调试运行 |
Ctrl + Shift + b |
编译,不运行 |
F10 |
next调试 |
F11 |
step调试 |
2) VS2013的C4996错误
由于微软在VS2013中不建议再使用C的传统库函数scanf,strcpy,sprintf等,所以直接使用这些库函数会提示C4996错误:
VS建议采用带_s的函数,如scanf_s、strcpy_s,但这些并不是标准C函数。
要想继续使用此函数,需要在源文件中添加以下指令就可以避免这个错误提示:
#define _CRT_SECURE_NO_WARNINGS //这个宏定义最好要放到.c文件的第一行
#pragma warning(disable:4996) //或者使用这个
5、C语言编译过程: 1、预处理 1)、宏定义展开 2)、头文件展开 3)、删除注释 4)、条件编译 格式:gcc -E a.c -o a.i 2、编译 1)、检查语法 2)、转化成汇编语言 格式:gcc -S a.i -o a.s 3、汇编 1)、将汇编语言转化成机器语言 格式:gcc -c a.s -o a.o 4、链接 1)、将库文件链接变成可执行文件 格式:gcc a.o -o a.exe 6、汇编语言 1、新建项目创建文建 2、写c语言源代码添加断点,调试执行 3、程序会停止在断点处,在调试菜单栏中选择窗口,在列表中选择反汇编,查看汇编源代码 4、 //汇编代码 __asm { mov a, 3 mov b, 4 mov eax, a add eax, b mov c, eax } QT下的智能提示 7、处理由C语言函数的警告操作: 1、#define _CRT_SECURE_NO_WARNINGS 放在程序第一行 2、#pragma warning(disable:4996 3、在项目中右击选择属性,在打开对话框中选择C/C++处理器 在预处理器定义中编辑 _CRT_SECURE_NO_WARNINGS