C语言基础(一)
2015-12-06 22:31
309 查看
精通细节是理解更深和更基本概念的先决条件。有人说:“我理解了一般规则,不愿劳神去学习细节!”他们实际上是在自欺欺人。
对于严谨的程序员来说,能够阅读和理解汇编代码仍是一项很重要的技能。通过阅读这些汇编代码,我们能够理解编译器的优化能力,并分析代码中隐含的低效率。
在C语言程序中嵌入汇编代码的方法:1)整个函数都用汇编代码来写,然后在链接阶段与C语言函数结合起来;2)在C语言程序中直接利用GCC对嵌入汇编代码的支持。
一、程序编码
指令:gcc -O1 code.c -S
-O1告诉编译器使用第一级优化;-S产生汇编代码code.s
指令:gcc -O1 code.c -c
-c编译并汇编代码,产生目标代码文件code.o
指令:objdump -d code.o
-d使用反汇编器(disassembler)产生反汇编代码, OBJDUMP(表示object dump)。
指令:gcc -O1 code.o main.c -o prog
产生可执行文件prog
汇编文件中有用以‘.’开头都是指导汇编器和链接器的命令。
命令:gcc -O1 -S -masm=intel code.c
gcc默认为ATT格式,上命令得到Intel格式代码。
ATT与Intel汇编代码格式有较大的差别。需要注意的是它们在带有多个操作数的指令情况下,列出操作数的顺序相反(ATT自左向右,Intel[b]自右向左)。[/b]
二、机器级代码
机器级编程的两种抽象:1)机器级程序的格式和行为,定义了指令集体系结构(Instruction set architecture, ISA),它定义了处理器状态、指令的格式,以及每条指令对状态的影响。2)机器级程序使用的存储器地址是虚拟地址,提供的存储器模型看上去是一个非常大的字节数组。
IA32机器代码
1)程序计数器(program counter):(通常称为PC,用%eip表示)指示将要执行的下一条指令在存储器中的地址。
2)整数寄存器文件(integer register file):用于记录某些程序状态或保存一些临时数据。
3)一组浮点寄存器(float register)。
4)条件码寄存器(condition code registers):保存着最近执行的算术或逻辑指令的状态信息。
大多数指令有个一或多个操作数(operand),指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。操作数类型:1)立即数(immediate),也就是常量值;2)寄存器(register);3)储存器引用(memory reference),它会根据计算出来的地址(通常称为有效地址(effective address))访问某个存储器位置。
(一)有多种不同的寻址模式,允许不同形式的存储器引用。最常用的形式为Imm(Eb, Ei, s):一个立即数偏移Imm,一个基址寄存器Eb,一个变址寄存器Ei和一个比例因子S,这里S必须是1、2、4或8。然后,有效地址被计算为Imm + R[Eb] + R[Ei] . S。(here are many different addressing modes
allowing different forms of memory references. The most general form is shown at the bottom of the table with syntax Imm(Eb,Ei,s). Such a reference has four components:an immediate offset Imm, a base register Eb, an index register Ei, and a scale factor
s, where s must be 1, 2, 4, or 8. The effective address is then computed As Imm+R[Eb]+R[Ei].s.)
参考:《深入理解计算机系统》
对于严谨的程序员来说,能够阅读和理解汇编代码仍是一项很重要的技能。通过阅读这些汇编代码,我们能够理解编译器的优化能力,并分析代码中隐含的低效率。
在C语言程序中嵌入汇编代码的方法:1)整个函数都用汇编代码来写,然后在链接阶段与C语言函数结合起来;2)在C语言程序中直接利用GCC对嵌入汇编代码的支持。
一、程序编码
指令:gcc -O1 code.c -S
-O1告诉编译器使用第一级优化;-S产生汇编代码code.s
指令:gcc -O1 code.c -c
-c编译并汇编代码,产生目标代码文件code.o
指令:objdump -d code.o
-d使用反汇编器(disassembler)产生反汇编代码, OBJDUMP(表示object dump)。
指令:gcc -O1 code.o main.c -o prog
产生可执行文件prog
汇编文件中有用以‘.’开头都是指导汇编器和链接器的命令。
命令:gcc -O1 -S -masm=intel code.c
gcc默认为ATT格式,上命令得到Intel格式代码。
ATT与Intel汇编代码格式有较大的差别。需要注意的是它们在带有多个操作数的指令情况下,列出操作数的顺序相反(ATT自左向右,Intel[b]自右向左)。[/b]
int simple(int *xp, int y) { int t = *xp + y; *xp = t; return t; } Assembly code for simple in ATT format simple: pushl %ebp Save frame pointer movl %esp, %ebp Create new frame pointer movl 8(%ebp), %edx Retrieve xp movl 12(%ebp), %eax Retrieve y addl (%edx), %eax Add *xp to get t movl %eax, (%edx) Store t at xp popl %ebp Restore frame pointer ret Return Assembly code for simple in Intel format simple: push ebp mov ebp, esp mov edx, DWORD PTR [ebp+8] mov eax, DWORD PTR [ebp+12] add eax, DWORD PTR [edx] mov DWORD PTR [edx], eax pop ebp ret
二、机器级代码
机器级编程的两种抽象:1)机器级程序的格式和行为,定义了指令集体系结构(Instruction set architecture, ISA),它定义了处理器状态、指令的格式,以及每条指令对状态的影响。2)机器级程序使用的存储器地址是虚拟地址,提供的存储器模型看上去是一个非常大的字节数组。
IA32机器代码
1)程序计数器(program counter):(通常称为PC,用%eip表示)指示将要执行的下一条指令在存储器中的地址。
2)整数寄存器文件(integer register file):用于记录某些程序状态或保存一些临时数据。
3)一组浮点寄存器(float register)。
4)条件码寄存器(condition code registers):保存着最近执行的算术或逻辑指令的状态信息。
大多数指令有个一或多个操作数(operand),指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。操作数类型:1)立即数(immediate),也就是常量值;2)寄存器(register);3)储存器引用(memory reference),它会根据计算出来的地址(通常称为有效地址(effective address))访问某个存储器位置。
(一)有多种不同的寻址模式,允许不同形式的存储器引用。最常用的形式为Imm(Eb, Ei, s):一个立即数偏移Imm,一个基址寄存器Eb,一个变址寄存器Ei和一个比例因子S,这里S必须是1、2、4或8。然后,有效地址被计算为Imm + R[Eb] + R[Ei] . S。(here are many different addressing modes
allowing different forms of memory references. The most general form is shown at the bottom of the table with syntax Imm(Eb,Ei,s). Such a reference has four components:an immediate offset Imm, a base register Eb, an index register Ei, and a scale factor
s, where s must be 1, 2, 4, or 8. The effective address is then computed As Imm+R[Eb]+R[Ei].s.)
参考:《深入理解计算机系统》
相关文章推荐
- mysql Connector C/C++ 多线程封装
- 20151202 c语言小代码
- C语言基础,排序算法之冒泡排序算法
- Arduino 平台与C语言程序设计-week3-Arduino Programs-Lesson1
- MySQL Connector/C++入门教程(上)
- 求字符串的最长无重复字符子串(C++)
- C++容器类是什么意思? 简单易懂
- C++中容器跟模板有什么异同么?用简单易懂的话
- 读取Windows桌面图标的名字和位置,32bit程序读取64bit进程
- Arduino 平台与C语言程序设计-week2-C Programming-Lesson3
- Effictive c++条款38-40
- 给C++初学者的50个忠告
- Template(模板)设计模式
- Arduino 平台与C语言程序设计-week2-C Programming-Lesson2
- Arduino 平台与C语言程序设计-week2-C Programming-Lesson1
- C&C++ 结构体,类 区别
- C++类与对象基础
- LeetCode Reverse Bits 的C++解决4ms
- hdu 1350 Taxi Cab Scheme(二分匹配)
- C-054.学习OC之前,需要掌握和理解的C语言的基础部分基本写完了