现在的位置: 首页 > 综合 > 正文

深入理解计算笔记2

2014年11月19日 ⁄ 综合 ⁄ 共 1646字 ⁄ 字号 评论关闭

第3章

现代的编译器产生的代码至少与一个熟练地汇编语言程序员手工编写的代码一样高效,即编译器可以承担产生汇编代码的大部分工作,所以我们学习汇编的目标是能够阅读和理解编译器产生的代码。

 

1得到汇编代码的命令  gcc –O1 -S code.c

反汇编语句         objdump –d code.o  汇编以后的

                                   objdump–d code   链接以后的

链接以后的会分配出虚拟地址。

反汇编器只是基于机器代码文件中的字节序列来确定的汇编代码,它不需要访问程序的源代码或汇编代码。

2 操作数格式

3传送指令的两个操作数不能都指向内存的位置。

movs和 movz 都是将一个较小的源数据复制到一个较大的数据位置,高位用符号位(s)或者0(z)扩展。

4 c语言中的指针被编译为将该指针放入一个寄存器,然后在存储器引用中使用这个寄存器。  局部变量通常保存在寄存器而不是内存中。

5 leal 是加载有效地址指令,但编译器经常发现一些leal的灵活用法,它跟有效地址的计算无关。如 leal 7(%edx,%edx,4),%eax 是将 eax 设置为 5edx +7.

6清零操作

xor %edx,%edx  2个字节

sub %edx, %edx   2个字节

movl $0, %edx    7个字节

7 cmp 和sub

Cmp只设置条件码而不改变目的寄存器的值。其他行为与sub完全一样。

所以cmp在计算时也可能溢出了,但它并不保存计算结果。通过一些机制,cmp可以保证比较大小的正确性。

#include<stdio.h>
int main(){
int i =2147483647;
int j =-10;
printf("start\n");
if(i>j){
printf("i>j \n");
}else{
printf("i<=j \n");
}
if(i-j >0){
printf("i-j >0\n");
}else{
printf("i-j<=0\n");
}

int a = 10;
int b = -2147483648;
if(b<a){
printf("b<a\n");
}

}

 

out put:

start
i>j
i-j<=0

b<a

注意结果中的 i>j i-j < 0。这个结论说明我们有时候并不能用
if
x-y>0 a代替ifx>y b

顺便提一下  a语句用8条指令 而 b语句 只用4条。

 

8 条件语句的编译

9 循环语句的编译

Do-while形式是基础,其他循环会首先转换为do-while形式。

确定哪些寄存器存放哪些程序的值可能会比较困难。

10 因为有指令流水线的存在,所以then-expelse-exp都比较简单时基于条件数据传送的代码要比基于条件控制转移的代码性能好。

11 switch语句在编译时,当分支比较多并且跨度比较小时就使用跳转表这种数据结构,它执行开关语句的时间与开关的数量无关,所以比多个if-else更高效。

12帧栈结构

为单个过程分配的那部分 栈 被称为 帧。 其实就是该过程的局部变量所在的位置。

在此处的栈,特指那些在过程调用中会受影响的变量和 需要传递的参数所在的区域。

第4章

现在微处理器可以称得上是人类创造的最复杂的系统之一,你可能永远都不会自己设计处理器,那为什么还应该了解处理器的设计呢?

这一章的内容和唐朔飞的计算机组成原理的中央处理器讲的差不多。并且个人感觉唐的明显好于这章。本人本科机组有相当不错的基础,就跳过了此章,一些概念放这里仅供参考。

1指令是指示计算机执行某些操作的命令。它由一组微命令实现。

微命令如pc-> MAR(其实只要打开寄存器的开关门就行),可以在一个时钟周期内完成。一个时钟周期就是一个节拍。

在每个节拍内,机器可以完成一个或者几个可以同时执行的操作,节拍是控制计算机操作的最小时间单位。

2从程序运行的角度看,cpu的基本功能就是对指令流和数据流在时间与空间上实施正确的控制。

3指令执行过程

取指阶段,分析取数阶段(又称间址周期),执行阶段,中断阶段

4硬布线控制器和微程序控制器

5指令流水线

6指令乱序技术

 

抱歉!评论已关闭.