![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
深入理解计算机
文章平均质量分 63
樱满无门
这个作者很懒,什么都没留下…
展开
-
提升程序运行效率的小tips
认识到内存别名的存在消除循环的低效率减少过程调用消除不必要的内存引用消除循环的低效率为了避免不必要的扯蛋和浪费时间,只挑选有必要的和不破坏代码可读性的地方进行学习循环优化指南:如果循环中有要执行多次的值,它又是固定的,最好一次就把它算出来例如,for (int i = 0; i < strlen(s); i ++){ ...}就不是一个好的代码int length = strlen(s);for (int i = 0; i < length; i ++){.原创 2021-02-05 23:10:02 · 76 阅读 · 1 评论 -
CSAPP期末复习(更新ing)
CSAPP期末快速复习(更新ing)本人有关CSAPP的博客链接:私人博客CSDN内容基本上差不多主要内容概论信息的表示机器级的表示链接I/O概论上下文:上下文是一个状态,包含运行进程所需的所有状态信息,进程切换通过切换上下文完成编译过程(链接中会再次提到):源程序 预处理-> 文本 编译->汇编程序 汇编->可重定位目标文件 链接->可执行文件指令集架构:每条机器代码的效果。微体系结构:处理器的具体实现存储器层次结构:从上至下,访问速度越来越慢,原创 2020-12-23 17:04:34 · 2370 阅读 · 0 评论 -
CSAPP第三章之循环语句的实现
循环汇编语句使用条件测试和跳转,组合实现循环的效果GCC和其它汇编器产生的循环代码主要是基于两种基本的循环模式do-while循环重复执行:循环体->对测试条件语句求值do{ body-statements;}while(test-expr);等价于loop: body-statements; if (test-expr) goto loop;long fact_do(long n){ long result = 1; do { result *=原创 2020-12-19 17:52:10 · 235 阅读 · 1 评论 -
CSAPP第三章之条件分支的两种实现方式
有关博文请移步:为什么我不喜欢用if语句使用条件控制来实现条件分支将条件表达式和语句从C语言翻译成机器代码,最常用的就是结合有条件和无条件的跳转(有些条件可以用数据的条件转移来实现,而不是用控制的条件转移来实现)主要实验介绍请看课本主要内容:对于C语言中的if-else,汇编会使用goto的形式进行实现使用条件传送来实现条件分支实现条件操作的传统操作是使用控制的条件转移这种方法在现代编译器上很低效替代策略之一:使用数据的条件转移计算一个条件操作的两者结果,根据条件是否满足,使用条件传送原创 2020-12-19 17:51:28 · 689 阅读 · 1 评论 -
CSAPP第三章之条件码、跳转指令
控制机器代码提供测试数据值根据测试结果改变控制流条件码CPU维护着一组条件码寄存器CF:进位标志。可以检查无符号操作的溢出。ZF:0标志SF:符号标志。最近的操作结果为负数。OF:溢出标志。检查有符号操作的溢出。leaq不改变任何条件码——它是用来进行地址计算的除此之外,加法、乘法、移位、逻辑运算等指令都会设置条件码逻辑操作会将进位标志CF与溢出标志OF设为0移位操作会将进位标志CF设为最后溢出的位,溢出标志OF设为0INC与DEC只会设置溢出标志与零标志,不会改变进位标原创 2020-12-19 17:49:54 · 957 阅读 · 1 评论 -
CSAPP第三章之算术指令
算术操作一些指令类每一个指令类都有各种不同大小操作数的变种(除leaq外)指令效果描述leaq S, DD<-&S加载有效地址INC DD<-D+1加一DEC DD<-D-1减一NEG DD<- -D取负NOT DD<-~D取反ADD S, DD<-D+S相加SUB S, DD<-D-S相减IMUL S, DD<-D×S相乘XOR S, DD&原创 2020-12-19 17:49:08 · 505 阅读 · 1 评论 -
CSAPP第三章之数据传送指令与栈指令
接下来的内容不需要全部记住!只需要记住常用指令即可!数据传送指令使用最频繁的指令。将不同的指令划分位指令类,每一类中的指令执行相同的操作,唯一的区别是操作数大小不同MOV类将数据从源位置复制到目的位置movbmovwmovlmovqmovabsqMOV S,D => (S => D)源操作数限定的值为立即数,存储在寄存器或者内存中目的操作数是一个地址,在内存或寄存器中限制:传送指令的两个操作数不能都指向内存位置:将一个值从一个内存位置复制到另一个内存位置需要两条原创 2020-12-19 17:48:24 · 505 阅读 · 1 评论 -
CSAPP第三章之寄存器与寻址
访问信息通用目的寄存器:x86-64中包含的一组16个64的寄存器,用来存储整数与指针,它们都以%r开头8086中有8个16位寄存器:%ax -> %sp,每个寄存器都有特殊的用途IA32寄存器扩展为32位:%eax->%exp扩展到x86-64后,扩展为64位,并添加8个新的寄存器:%rax->%exp,%r8->%r15指令可以对这16个寄存器的低位字节中存放的不同大小的数据进行操作当指令以寄存器为目标时,对于生成小于8字节的结果的指令,有以下两条规则:生成1原创 2020-12-19 17:46:46 · 384 阅读 · 1 评论 -
北邮CSAPP第三章之数据格式与程序编码
程序的机器级表示本章学习内容:汇编代码高级语言屏蔽了程序的机器级实现。用高级语言编写的程序可以在不同的机器上运行,汇编代码则于特定机器密切相关学习汇编代码能理解编译器优化能力,并分析代码中隐含的低效率此外,高级语言提供的抽象层会隐藏我们想要了解的程序的运行时行为此外,很多攻击都涉及到程序存储运行时控制信息的方式的细节逆向工程:通过研究系统和逆向工作,试图了解系统的创建过程IA32:x86-64的32位前身(机器可以向后兼容IA32程序)C语言、汇编代码以及机器代码之间的关系x86-64原创 2020-12-17 21:56:02 · 332 阅读 · 0 评论 -
北邮CSAPP第二章之浮点数
浮点数浮点数:范围大而不精确本节内容:如何表示浮点数,浮点数的舍入,浮点数的运算二进制小数小数的二进制表示法只能表示哪些能构被写成x × 2^y的数,其它值只能近似地表示增加二进制表示的长度即可提高表示的精度IEEE浮点表示V = (-1)^s · M · 2^Es:signM:尾数E:阶码,对浮点数加权将浮点数的位表示划分为三个段s | exp | fracexp: k位的阶码字段frac: n位小数字段float:s:1位,exp:8位,fr原创 2020-12-17 21:55:11 · 385 阅读 · 0 评论 -
北邮CSAPP第二章之整数运算
整数运算无符号加法两个非负整数的加法很有可能会导致溢出两数相加后,丢弃超越范围的数字,得到的结果类似于模运算例如9 + 12 = .21 = [10101] => [0101] = 5 = 21 % 16丢弃最高位相当于从和中减去2^w(无符号)C语言不会因为溢出而发出信号检测溢出的方法:s = x + y(截取后), 若s < x或s < y,则发生了溢出(不是很理解)阿贝尔群:对于无符号数,必有y使得x + y = 0(均限定在一定字节内)原创 2020-12-17 21:54:06 · 263 阅读 · 0 评论 -
北邮CSAPP第二章之整数表示
整数表示主要内容:展示整数的两种不同表现形式,研究扩展或者收缩一个已编码整数以适应不同长度表示的效果术语详见教材B:二进制2:toU:无符号数T:补码w:位数整型数据类型为各种不同的数据类型分配的字节数与32位或64位编译法有关根据字节分配,不同大小能表示的值的范围是不同的很值得注意的特点:有符号类型的范围,负数总是比整数大一。注意,必须考虑这一点,很可能会在程序中造成错误无符号数的编码使用位向量表示整个整数数据类型。将其视作二进制表示的数,就获得了无符号表示的数据(B2原创 2020-12-17 21:53:10 · 162 阅读 · 0 评论 -
北邮CSAPP第二章之信息存储
为什么使用二进制?二值信号能更容易地被表示、存储、传输三种最重要的数字表示:无符号补码:表示有符号整数浮点数计算的表示是有限数量的,因此,答案太大时,结果会溢出浮点运算的精度有限,不可结合(指-1 + 1 != 0)整数能表示小范围的精确的数值,浮点数能表示大范围的近似的数值大量计算机的安全漏洞都是由于计算机算数运算的微妙细节引起的信息存储最小的可寻址单位:byte,8个位组成。虚拟内存:将内存视作一个非常大的char数组尽管C编译器..原创 2020-12-17 21:52:07 · 217 阅读 · 0 评论 -
北邮CSAPP第一章
从helloworld开始了解计算机helloworld的编译历程源程序:比特序列。8个byte->字节。所有的计算机信息->一串byte构成区分不同数据对象的唯一方法:读到这些数据对象时的上下文。上下文:它是一个状态,包含了能使程序运行的所有参数、变量数字的机器表示形式是对真值的有限近似值。C语言程序->一系列低级机器语言指令->可执行目标程序编译系统:预处理器,编译器,汇编器,链接器C语言源程序->预处理->编译器(汇编程序)->汇编器(可原创 2020-12-17 21:49:30 · 290 阅读 · 0 评论 -
printf函数是如何隐藏内存错误sysmalloc error
printf函数对内存的作用在写代码的时候,如果出现了动态分配的内存越界,就会报sysmalloc assertion错误(在较低的优化等级下不会出现该错误)但是,在某些时候,如果在恰当的位置添加了printf/scanf函数,那么即使写出了内存越界的代码,也不会报错这个时候,如果某些程序员比较愚笨,他就会认为是编译器错误,甚至认为是C语言的缺陷,因为他发现添加printf和不添加printf的效果差异有那么大,但是其实,主要的错误还是内存越界。使用valgrind可以轻松地进行检测。但是这里有一个原创 2020-12-15 13:36:04 · 284 阅读 · 0 评论 -
基于linux系统的简单malloc模型
在linux系统上的malloc的简单实现本片文章介绍 malloc 在linux系统上的简单实现,仅仅介绍有关原理,不涉及使用mmap等进行大块内存分配有关的部分。背景知识CSAPP第一章中对虚拟内存做了简洁的介绍。为了使进程感觉自己在独占处理器,使用虚拟内存,避免内存冲突。因此我们在下面所讨论的都是虚拟内存而非实际物理内存。linux中的内存分为两部分,一部分是内核空间,分布空间在0xFFFF800000000000 0xFFFFFFFFFFFFFFFF中,另一个部分为用户空间,分布在0x000原创 2020-12-15 13:33:28 · 152 阅读 · 1 评论 -
优化程序性能之优化编译器的能力与局限
优化程序性能本章主要探讨内容:使用几种不同的程序优化技术,让程序运行得更加高效,并且在可维护性与性能间达到平衡。将从以下的几个方面对程序进行优化选择合适的算法与数据结构尽可能使用使编译器更容易产生高效代码的方式来进行程序编写程序优化的第一步应当是消除多余的不必要的工作,包括函数调用、条件测试与内存引用等。这些优化不依赖于目标机器。基于Intel和AMD处理器,本章提出了一种高级模型。还设计了一种图形数据流来对处理器的指令执行形象化,并利用其预测程序的性能。利用处理器提供的指令级别并行能力同原创 2020-12-15 13:32:21 · 464 阅读 · 0 评论 -
程序性能优化之表示程序性能
表示程序性能CPE: Cycles Per Element,每元素的周期数,作为表示程序性能的表示方法处理器活动的顺序由时钟控制,其提供某个频率的规律信号,数量级为GHz使用时钟周期表示,度量值表示的是执行了多少条指令。许多过程含有在一组元素上迭代的循环。void psum1(float a[], float p[], long n){ long i; p[0] = a[0]; for (i = 1; i < n; i ++) p[i] = p[i - 1] + a[i];}原创 2020-12-15 13:29:20 · 543 阅读 · 0 评论 -
为什么“?:”运算比“if”运算来得快
为什么“?:”运算比“if”运算来得快曾经在做Leetcode的时候发现了一个很有趣的现象:在代码的逻辑不变的情况下,使用三目运算符?:代替if条件语句后运行速度总会提升一大截。进行试验试验代码#include <stdio.h>#include <time.h>#include <stdlib.h>int func_1(int x, int y);int func_2(int x, int y);int main(){ for (int i原创 2020-12-14 15:06:06 · 1628 阅读 · 0 评论 -
内存对齐
内存对齐是编译器的管理范畴为什么要了解内存对齐?为了可移植性的问题为了提升性能(访问未对齐的内存,处理器需要进行两次内存访问)对齐规则对齐系数(对齐模数)特定平台上的默认参数规则(from B乎)各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数各成员变量在存放的时候根据在结构中出现的顺序依次申请空间同时按照上面的对齐方式调整位置 空缺的字节自动填充为了确保结构的大小为结构的字节边界数(即该结构中占用最大的空间的类型的字节数原创 2020-12-14 15:02:04 · 59 阅读 · 0 评论