-
不再疑惑,汇编之后
2009-12-15 22:19:00在我们认真学完《汇编语言》之后,就可以和计算机进行基本的沟通和交流了,也就是有了基础,但只有这些基础还不够,我们还需要更多的计算机方面知识。作为一个渴望知识和并不满足于现状的你,一定会想下一步该学习...学习计算机知识的目的是为了使用计算机解决问题。为了更好的使用计算机我们必须要学会能与计算机直接沟通和交流的汇编语言。在我们认真学完《汇编语言》之后,就可以和计算机进行基本的沟通和交流了,也就是有了基础,但只有这些基础还不够,我们还需要更多的计算机方面知识。作为一个渴望知识和并不满足于现状的你,一定会想下一步该学习什么?任何简单的答复都让你质疑。但是你已学完了《汇编语言》,你应该对机器有了了解,也具备了独立判断下一步该学什么的能力了。下面是汇编相关的几个方面的介绍和分析,你看你应该从那方面入手进行下一步的学习。
1、从汇编语言自身的角度看
《汇编语言》讲解了8086汇编机制,学完它后就具备了汇编编程的基础,并了解了8086CPU的工作机制。想进一步学习可以从以下几个方面考虑:
1)学习所有8086汇编指令和汇编结构化编程。
所有汇编指令我们可以从指令表查看,如果单独列出来学习也可以。但这样更像我们遇到一些生词和生字去查字典一样,我们一般不会抱着一本字典去学习。结构化编程方面可以去学习一下,如果以后需要大量的汇编编程需要深入学习。否则了解一下,打下理解高级语言的基础就可以了。现在绝大多数的应用是用高级语言编写。
2)386及以上的保护模式。
保护模式的编程更多的是编写操作系统人需要的。如果需要编写操作系统,我想你要深入研究一下。如果不是,可以先了解一下原理就够了。现在操作系统核心编写绝大部分用的C,只有少量要求效率很高和C没法实现的功能才用汇编实现。在windows下你无法使用受保护的指令,只能在实模式下学习。这些编程是普通应用程序用不着的,这些保护措施都是给操作系统用的。
3)win32汇编编程
主要是用汇编的方式调用windows API, 我想现在主流是用C语言方式调用windows API,用汇编纯粹是花架子,效率提高不多,程序结构和可读性比C差很多。这种逻辑上的编程,为什么不用更符合人逻辑的高级语言(C语言),而要用符合机器逻辑的汇编语言呢。我们主要是高效的解决问题,而不是炫耀。
4)其它CPU编程(如Arm、8051等嵌入式)
如果从事嵌入式开发,可以学习一下其它类型cpu的汇编,嵌入式主流的开发开始用C,当然也可能嵌入汇编。
2、从硬件设备的控制及它们直接连接看
硬件控制和使用方面,主要通过端口编程控制硬件设备,借助8086汇编基础可以看一下微机原理及接口技术方面的书。可以了解硬件之间是怎样连接和使用的,掌握更多的硬件特性。一般微机的组成: CPU、内部存储器、输入输出接口、外部设备。它们之间靠总线连接。学习这方面知识可以知道CPU是如何通过总线和设备协调工作和如何通过接口控制设备。对于硬件设备驱动的底层编程大有好处。也可以学习现有的总线和接口技术如:PCI总线、USB接口等
3、从机器语言的实现和运行原理看
如果你学完《汇编语言》后,已经知道机器是在运行机器指令。但这些机器指令是如何设 计和怎样用硬件实现的?指令的设计、寻址方式、中断控制、设备端口设计等可以去学习系统结构。它详细说明的如何设计指令的编码,寻址方式的种类及实现,为什么要使用中断机制和DMA方式。硬件和软件如何分层等问题。该方面比较综合,需要大量软件和硬件知识,建议学完组成原理和操作系统后再学系统结构。
想知道CPU如何把机器翻译成信号,控制内部电路完成工作。机器指令是用硬连线实现、还是由微指令实现。 CPU的运算器和控制器怎样用硬件实现等这方面的知识可以看组成原理。
这里和硬件更接近,相比来说嵌入式编程就不算什么硬件的工作了^_^。
4、从常用的高级语言看
汇编语言更接近的是机器的运行方式,不太符合人们通常的逻辑习惯。所以人们对机器编程模型进行了抽象,发明了高级语言。高级语言发明极大的推动了计算机编程,大量的应用都是用高级语言实现。这也导致了人们对汇编重要性认识的不足。高级语言最终都要被翻译成汇编语言,这样才能在机器上运行。汇编语言基础掌握后,可以开始高级语言的学习。高级种类繁多,应该学习哪种? 并以怎样的角度来学习能取得最好的效果呢?当然应该从一种简洁并实用的语言开始,它既具备高级语言的特性,又更接近汇编语言(就是接近些机器)。C语言是目前所有高级语言里最适合的。如果只学习C本身语法和使用,是不太合适的,关键我们应该从学习C的过程中看到高级语言的共同特征和C语言在机器上实际运行的机制。这样我们能更快的学会其它高级语言和更好的使用其它高级语言。甚至可以创造自己的编程语言。
5、从操作系统看
汇编可以通过中断方式调用操作系统功能,可以用汇编进行操作系统编程。 汇编可以理解操作系统,因为操作系统的一些功能只能用汇编实现,另一部分用用C语言实现。学习操作系统需要你掌握汇编语言和 C语言,当然还要学习一下数据结构的知识,只有汇编的基础不建议你马上开始学习操作系统。当然用纯汇编实现操作系统而跳过C,没问题,但现在没人愿意这么做,你要是不服,可以尝试一下!
6、解决现实问题
汇编语言也可以解决一些实际的通用问题,这需要用汇编去实现基本数据结构和算法,在一些对效率要求高的地方使用。如果要求不太高,用C语言实现就足够了,可移植性还好,也容易改为其它高级语言。现在大部分应用程序是用高级语言写的,汇编一般只是配合一下。
汇编是基础的基础,C语言、数据结构、组成原理、微机原理和接口是基础,操作系统和系统结构就比较系统和综合了。
组成原理和系统结构告诉怎么实现硬件。微机原理和接口更多的是告诉你怎么连接和使用硬件。C是一种高级语言。操作系统是使用汇编语言和C语言实现的一个综合的控制硬件和提供虚拟软件接口的程序。 如果你偏向软件领域,学完《汇编语言》后还是从C语言开始吧! -
mips汇编计算开方_读美国伊利诺伊理工大学计算机科学硕士能学到什么?
2020-11-23 19:08:37彼岸教育从伊利诺伊理工大学计算机科学系要来了一份近期学校的安排的部分课程大纲,包括教师背景和经验、课程目标、课程内容、考核方式,帮你提前了解修完这些课程,我能学到什么,是否掌握的是核心技术,学到之后有...最近有很多计算机专业的大学生和程序员、工程师等在职人士,向彼岸教育咨询美国伊利诺伊理工大学的计算机硕士项目,想更多地了解课程和教学内容。
彼岸教育从伊利诺伊理工大学计算机科学系要来了一份近期学校的安排的部分课程大纲,包括教师背景和经验、课程目标、课程内容、考核方式,帮你提前了解修完这些课程,我能学到什么,是否掌握的是核心技术,学到之后有什么用。
如果你的计算机科学基础比较薄弱,也不用被课程内容吓到:
伊利诺伊理工大学拥有海内外助教与大家交流学术话题;
有学习小组可以让线上学员们交流学习所得,分享解决实践问题的经验;
彼岸教育还有定期举办的线下科技菁英会,邀请行业专家分享领域前沿和从业心得。
伊利诺伊理工大学的教务团队帮助学生答疑解惑。只要你想学,肯下功夫,没有什么知识点和作业项目是攻克不了的。
另外,一般情况下计算机科学硕士项目修10门课即可毕业,可以学习以下列举的部分课程,或者结合如人工智能、数据库、网络安全、分布式与云计算等其他方向计算机科学课程。(未列举全部课程,后续实际授课老师有可能会有所调整)
授课教师:
Michael Choi博士,伊利诺伊理工大学计算机科学硕士和博士学位,自1998年起在校任教,并与2008年起任诺基亚首席工程师兼实验室高级经理。具有丰富的软件和工程研发,项目管理和项目交付经验。专业领域包括网络管理系统、下一代IP网络、语音和数据集成网络等。
课程目标:
本课程是数据结构入门课程,包括各类数据结构和面向对象的编程技术。学生将使用课堂上学习的数据结构和编程方法来构建复杂的项目。
课程内容:
数据结构概论,面向对象编程技术,软件工程概论,类,对象和应用,抽象数据类型,动态内存,单链表和双链表,堆栈,Big-O,字符串,数组,链表,继承,递归,二叉搜索树,排序,映射,图,散列,软件项目管理策略,软件项目模型,算法与实际软件技巧。
教材:
Object-Oriented Data Structures using Java, 4 th Ed., 2018, Jones and Bartlett, Nell Dale, Daniel T. Joyce, Chip Weems
面向对象数据结构(Java版)
考核方式:
包含日常作业和项目,课堂参与,随堂测验,期中考试和期末考试,综合评定
所有作业通过Github或者Bitbucket上传共享
课程使用编程语言:Java
日常练习讲解示例
授课教师:
Virgil Bistriceanu ,伊利诺伊理工大学计算机博士学位,在IIT承担教职的同时创办了一家IT咨询公司,专业领域包括信息安全,敏捷软件开发,软件测试,计算机体系结构。曾获伊利诺伊州技术协会聚光灯奖。
课程目标:
本课程介绍了计算机系统的内部体系结构,包括微型,小型和大型计算机体系结构。着重于计算机硬件,指令集以及该计算机上高级语言的实现之间的关系。在系统编程方面,该课程教授了复杂的多层软件系统的组件,包括设备驱动程序,系统软件,应用程序界面和用户界面。
课程内容:
计算机体系结构,性能表现衡量方法,指令集设计,寻址模式,存储器层次结构,缓存,流水线技术,高级C语言编程,流程抽象,流程管理,动态内存分配和垃圾收集,系统级I/O和基本IPC
教材:
Computer Organization and Design, 5th edition, Patterson and Hennessy, Elsevier
计算机组成与设计,第5版(计算机软硬件基础经典教材)
https://item.jd.com/11729917.html
Computer Systems: A Programmer's Perspective, 3rd edition, Randal Bryant & David O'Hallaron, Pearson
深入理解计算机系统,第3版(理解计算机系统必读经典书目)
https://item.jd.com/12006637.html
考核方式:
包含日常作业和项目,期中考试和期末考试,综合评定
课程使用编程语言:
MIPS汇编语言,C语言
课程使用的SPIM软件学习MIPS汇编语言
日常练习讲解示例
授课教师:
Gady Agam博士,伊利诺伊理工副教授,计算机视觉和机器学习领域专家。
课程目标:
讲解数据挖掘的基本概念、数学基础和应用算法,让学生通过实际的编程实践来掌握数据挖掘的各项应用。
课程内容:
数据处理和可视化、决策树、各种分类算法、关联关系算法、聚类算法、异常检测、互联网数据挖掘
教材:
Introduction to Data Mining. P.-N. Tan, M. Steinbach, and V. Kumar
数据挖掘导论
https://item.jd.com/12681764.html
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
授课教师:
Ola Tannous博士,麻省大学博士,研究方向包括数据库系统的可靠性研究等
课程目标:
学会如何针对实际需求建立关系数据模型,分析设计异常,建立实体联系图,分析数据之间的关系,分析和设计范式等,可以用SQL语言解决数据库事务,有能力设计并实现一个基本的具备常见用户功能的数据库项目
课程内容:
关系数据库模型、关系查询语言、SQL语言学习、实体-联系(ER)模型、数据库设计原理和范式、事务处理、并行数据库
教材:
Database System Concept, Silberschatz, Korth, Sudarshan, McGraw-Hill
数据库系统概论
https://item.jd.com/26652358074.html
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
日常练习讲解示例
授课教师:
John Korah博士,伊利诺伊理工助理教授,弗吉尼亚理工大学博士,研究领域包括大规模信息处理、并行与分布式处理、信息检索等。
课程目标:
为学生讲解信息检索涵盖的基本概念、方法、以及常见议题,核心侧重在实践以及相关理论。核心议题包括根据用户的查询寻找相关内容的算法和方法。学生可以学会如何建立一套信息检索系统,以及背后涉及的各类设计与实施相关的挑战。
课程内容:
搜索的体系架构、信息的索引、可扩展索引、索引压缩、向量空间模型、语言模型、数据挖掘技巧(分类、聚类)、Page Rank等。
教材:
Introduction to Information Retrieval, Manning, Raghavan, Schütze
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
课程使用编程语言和框架:Python
授课教师:
Michael Choi博士,伊利诺伊理工大学计算机科学硕士和博士学位,自1998年起在校任教,并与2008年起任诺基亚首席工程师兼实验室高级经理。具有丰富的软件和工程研发,项目管理和项目交付经验。专业领域包括网络管理系统、下一代IP网络、语音和数据集成网络等。
课程目标:
介绍计算机算法的设计,行为和分析。重点是搜索,排序和组合算法。评估空间和时间使用的最坏情况和平均定界。
课程内容:
算法设计导论,复杂度分析,递归关系,分治法排序(快速排序,堆和堆排序),下限排序,次序统计,二叉搜索树,平衡二叉搜索树(红黑树,AVL树),扩充数据结构,动态规划,贪心算法,平摊分析,斐波那契堆,并查集,图,深度优先搜索和宽度优先搜索,最小生成树问题,最短路径问题。
教材:
Introduction to Algorithms, 3rd edition, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein, MIT Press
算法导论,第3版(算法标准教材,国内外1000余所高校采用)
https://item.jd.com/11144230.html
考核方式:
包含日常作业,课堂参与,期中考试和期末考试,综合评定
课程使用编程语言:Java
日常练习讲解示例
授课教师:
Michael Saelee,伊利诺伊理工大学计算机系资深讲师,曾经讲授过十几门关于程序设计、计算机系体系结构、操作系统等主题的课程。
课程目标:
学习操作系统的基本原理和知识,掌握操作系统管理的资源和提供的服务,通过理解操作系统的源代码以及模拟器训练来掌握知识。
课程内容:
操作系统简介、进程和线程的基本介绍、系统服务、中断、异常的处理、内核模式和用户模式、调度、地址空间、虚拟内存和内存管理、I/O和设备管理、文件系统、并发处理。
参考教材:
Operating Systems: Three Easy Pieces
操作系统导论
https://item.jd.com/12535621.html
考核方式:
包含日常作业,期中考试和期末考试,综合评定
课程使用编程语言:C/C++和汇编语言
授课教师:
MustafaBilgic博士,伊利诺伊理工大学副教授,马里兰大学计算机科学博士,主要研究方向包括机器学习、信息获取和决策理论。Bilgic博士在伊利诺伊理工教授数门关于人工智能、机器学习以及概率图分析领域的课程。
课程目标:
学习自治体的智能控制计算方法,如何用程序来开发灵活的反馈系统,学习启发式搜索、知识表达、约束条件分析、概率逻辑推断、决策控制、传感器解释。学习的重点在于实际的应用案例。
课程内容:
人工智能发展概论、智能代理、通过搜索解决问题、对抗性搜索、知识表达(命题逻辑、一阶逻辑、不确定性表达)、通过逻辑和概率进行的推断、学习(监督学习、加强学习等)。
教材:
Artificial Intelligence: A Modern Approach, Russel, Norvig
人工智能:一种现代方法(本书为人工智能领域的最经典教材)
https://item.jd.com/11343660.html
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
课程使用编程语言:Python
授课教师:
Dennis Hood,伊利诺伊理工大学计算机系硕士专业负责人及讲师,在IIT已有20多年的教龄,是一位有着丰富教学经验的讲师,并著有多部关于计算机科学教学研究文献。
课程目标:
帮助学生建立软件工程的良好基础,教会学生如何通过经典的方法以及最新的范例来分析、开发和测试软件系统,并从技术、财务、人力资源角度研究有关问题。
课程内容:
学习软件工程的基本原理与实践方法,主题包括软件质量的概念、流程模型、软件需求的分析、设计方法论、软件测试的方法、软件维护的方法。并通过实践来建立一套软件系统。学生在小组协同作业的过程中学习软件开发全周期的各项任务。
教材:
Software Engineering (10th Edition), Sommerville
软件工程
https://item.jd.com/12311942.html
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
487日常练习示意
授课教师:
Gady Agam博士,伊利诺伊理工副教授,计算机视觉和机器学习领域专家。
课程目标:
介绍计算机视觉领域的基础性话题,帮助学生建立计算机视觉领域的技术理解、数学基础和算法基础,基于相关论文进行有关项目研究,完成有关的课程软件和技术实践。
课程内容:
计算机视觉领域的简介(包括应用领域、常用软件、OpenCV介绍)、图像的组成与表示(数字表示、几何模型、仿射变换等)、图像滤波(卷积、平滑等)、特征提取(边缘、角、曲线、材质等)、模型匹配、相机参数标定(Camera calibration)、对极几何(Epipolar geometry)、模型重建、动作捕捉、动作跟踪、对象识别和形状表达。
教材:
Computer Vision: Algorithms and Applications
计算机视觉:算法与应用
https://item.jd.com/37702398741.html
考核方式:
包含日常作业和课程实践项目,综合评定
课程使用编程语言和框架:Java/C++/Python, OpenCV/OpenGL
课程目标:
课程专注于计算机网络协议和体系架构的分析和工程实现,包括内容分发、点对点网络、路由的原理和设计,网络的移动性、多媒体网络的服务质量、网络的安全和政策研究。
课程内容:
计算机网络和互联网、应用层、传输层、网络层、局域网、无线网和移动通信网、多媒体网络、计算机网络的安全性、如果管理计算机网络。
参考教材:
Computer Networking, a Top-Down Approach, Kurose, Ross
计算机网络:自顶向下方法
https://item.jd.com/12392810.html
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
课程使用编程语言:Java
授课教师:
Ioan Raicu博士,伊利诺伊理工大学助理教授,芝加哥大学博士,并行计算和云计算领域专家,发表过多篇相关论文。
课程内容:
分布式计算模型、并行计算模型、可视化、云计算平台的体系架构(AWS、微软Azure、谷歌云等)、面向服务的体系架构、云计算编程、网格计算、点对点网络计算。
教材:
Distributed and Cloud Computing: Clusters, Grids, Clouds and Future Internet, Hwang, Dongarra, Fox
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
授课教师:
Mustafa Bilgic博士,伊利诺伊理工大学副教授,马里兰大学计算机科学博士,主要研究方向包括机器学习、信息获取和决策理论。Bilgic博士在伊利诺伊理工教授数门关于人工智能、机器学习以及概率图分析领域的课程。
课程目标:
介绍机器学习领域的基础课题,提供机器学习领域所需的数学概念、算法、以及理解技巧。为学生建立理解机器学习算法局限的理解以及对学习算法表现的分析。
课程内容:
机器学习简介、回归算法、核方法(Kernel methods)、生成学习(Generative Learning)、判别学习(Discriminative learning)、神经网络(Neural networks)、支持向量机(SVM)、图模型、非监督学习(Unsupervised Learning)、维度降低。
教材:
Machine Learning, Tom Mitchell
机器学习
https://item.jd.com/16007151390.html
考核方式:
包含日常作业和项目,以及期中考试和期末考试,综合评定
课程使用编程语言和框架:Python
Scikit-learn http://scikit-learn.org/stable/
TensorFlow https://www.tensorflow.org/
Keras https://keras.io/
点击“
-
今天考完汇编了~终于又考完了一门~
2005-12-13 12:09:00虽然考的不怎么滴,不过总算又考...不过通过这次汇编给我的打击挺大的,他们很强调汇编的重要性,我却学的这么烂,嗨,真不知道这学期都去干什么去了,真该好好的补补汇编了,不然等面试的时候就挂了之后好好看一下吧~虽然考的不怎么滴,不过总算又考完了一门,两天后考组成原理就更加恐怖了~~
所以还要加油看组成原理!
不过通过这次汇编给我的打击挺大的,他们很强调汇编的重要性,我却学的这么烂,嗨,真不知道这学期都去干什么去了,真该好好的补补汇编了,不然等面试的时候就挂了
之后好好看一下吧~
-
汇编语言典型例子详解_《汇编语言》学习笔记
2020-12-24 01:08:10前言学完 计算机组成原理 之后接下来再学什么?通过本课程一开始的图,就知道要紧接着学习汇编语言(再往下是编译原理、操作系统)。本课程内容太多我没有看完,大概看了 2/3 吧,但这并不影响我来做这个总结记录,...《汇编语言》学习笔记
另外,我觉得学习汇编语言之前最好先了解 计算机组成 的相关知识,否则遇到一些 CPU 寄存器 内存寻址 等相关概念时,可能会听着有点懵。
前言
学完 计算机组成原理 之后接下来再学什么?通过本课程一开始的图,就知道要紧接着学习汇编语言(再往下是编译原理、操作系统)。
本课程内容太多我没有看完,大概看了 2/3 吧,但这并不影响我来做这个总结记录,因为我不是专业搞汇编的,就来了解一下。
本课程主要讲解 x86 架构的汇编,最后又讲 MIPS 汇编,而 MIPS 汇编部分我没有看
课程中一些演示、讲解汇编代码的细节部分我没有详细看,即没有深入汇编语言的具体指令和参数
PS:虽然本课程十几个小时,看着不长,但是老师语速非常快,1x 速度听都感觉讲话挺快的,因此不敢 1.5x 看。
学到了什么
这个问题其实可以拆解成两个问题:第一,汇编语言是什么?第二,高级语言程序猿学习汇编有何用?分开解答。
汇编语言是什么
简答来说,汇编语言就是机器语言(二进制代码)的助记符,每条汇编语言都能直接翻译成机器语言,如下图。计算机就是一台各种电子设备组成的机器,它只能识别机器代码,即一堆二进制数字。但是二进制不易于人类阅读,而且在计算机发展初期还没有高级语言和编译器,因此出现了汇编语言。仅仅这样一个微创新,就大大提升了开发效率。
汇编语言常见的语法是 指令 参数1, 参数2 ,指令不同参数也不同。指令即 add mov jmp 等常见的算数、逻辑运算和跳转等功能,参数可以是立即数、内存地址、寄存器。因此,汇编语言编程能深入到计算机编程的最底层,通常说汇编语言是一种“面向机器的语言 / 编程”。正是因为这个特点,使得汇编语言能提供所有编程语言中最大的时间和空间的效率,因此至今依然活跃在某些计算机领域。
汇编语言都是针对特定的计算机体系结构的,例如 x86 汇编(本课重点内容)、MIPS 汇编、ARM 汇编,因此没有让所有计算机都通用的汇编语言。
高级语言的开发者,学习汇编有何用
一句话总结就是:了解程序是在计算机中是如何被执行的,即透过现象(高级语言)看本质 —— 这是所有领域的技术人员都应该追求的东西。那些能随意在 php java js C++ 等语言中随意切换的程序猿大牛,我想他肯定熟知这个本质。
无论你日常编写的语言多么高级,肯定最终经过转换(编译原理的内容)然后生成汇编语言这种最底层的语言,再被计算机执行。而“执行”的本质,就可以通过汇编语言的一行一行代码看出:使用了哪个指令、获取了哪个内存地址、操作了哪个内存片段或者寄存器……
另外一个重要的部分就是程序执行的时候的内存模型。一段程序拿过来,哪些变量将被放在栈 stack ,哪些变量将被放在堆 heap ?以及这些内存空间如何被释放?甚至是你日常遇到的爆栈、内存泄露等问题,了解了内存模型,这些都会变的非常具象,不再懵。
指令集分类
所谓“指令集”,我理解就是一套操作 CPU 的指令体系集合,以及体系规范。指令集是一种上层定义,汇编就是其具体的体现和实现。指令集分两类:
CISC 复杂指令集,以 x86 为代表(x86 在 PC 服务器领域具有统治地位)
RISC 精简指令集,以 ARM MIPS 为代表(ARM 统治了手机和平板领域,MIPS 常用语手机、电脑之外的其他电子设备)
CISC
最初的计算机编程很麻烦,例如用纸带打孔输入,因此计算机的设计者就考虑将 CPU 做的复杂一点,以简化这种本来就很麻烦的编程。因此有了 CISC 复杂指令集。x86 就是其中的典型代表,x86 的特点是:
指令向下兼容(这是其商业成功的重要因素之一!!!),缺点就是会让指令集越来越大、越来越复杂,功耗也更大(因此不适用于低功耗设备)
变长指令(MIPS 是等长的,只有 32 位),优点是节省空间、扩展性好,缺点是译码复杂
多种寻址方式
通用寄存器个数有限,x86-32 只有 8 个通用寄存器,x86-64 也只有 16 个寄存器
指令中,最多能有一个操作数在内存中,其他的操作数必须是立即数或者寄存器
RISC
历史原因,RISC 是 80 年代初发明的,那时整个计算机生态系统已经形成,编译器能力增强,就不需要 CPU 对外暴露过度复杂的指令集,因此有了 RISC 精简指令集。MIPS ARM 是 RISC 的代表,RISC 指令集特点是:
只关注一些简单常用的指令,因此简单轻量、高性能、功耗低
那些不常用的复杂指令,就依赖于编译器(即用软件来实现,而不是依赖于硬件的复杂指令),那时编译器已经比较强大
MIPS 特点:
以寄存器为中心。一出手就是 32 位(即寄存器是 32 位的),而且有 32 个通用寄存器
只有 load 和 store 指令可以访问内存,其他指令只能操作寄存器和立即数(以寄存器为中心嘛)
指令格式规范,长度一致(32 位),导致空间利用率不高,但是译码效率高
寻址方式非常简单
ARM 指令集特点:
大多数指令支持“条件执行”模式,能使得代码比较精简
具有 16 位压缩指令集,低功耗、低存储场景下很适用(ARM 在移动领域取得很大的成功,如 iphone 上的 A 系列处理器)
两者对比。
现代计算机中,像 x86 结构虽然也是 CISC ,但那时对外的,内部实现还是类似 RISC 实现的。因此,随着历史发展 CISC 和 RISC 的界限也越来越模糊。如果非要区分两者,可以看是不是只允许 load 和 store 操作主存。
数字的二进制表示
数字用二进制表示终归是一个数学问题,而常用的文本(中文、英文等)如何用二进制表示,这就是“编码”领域的问题。
普通整数
例如十进制 3 的二进制表示是 11 这没问题,但是在计算机中表示也是 11 吗?—— 不对,得分情况。例如在 C 语言中:
int 类型占 4 bytes ,即 4 * 8 = 32 bits 。那么 3 在计算机中表示就是 00000000 00000000 00000000 00000011 ,即前面要补充上若干个 0 。
short long 等长度不一样,表示方式也不一样。因此各类语言中才会有类型转换。
不同系统,或者 32 位、64 位中,表示也不一样。PS:C 语言指针类型在 32 位系统是 4 bytes ,在 64 位系统是 8 bytes ,因为需要更大的寻址空间(支持更大的内存空间)。
负数
补码
二进制负数是通过补码来表示的,补码算法是:按位取反、末尾加 1 。为何要用补码呢?建议读者看下阮一峰老师的《关于2的补码》 http://www.ruanyifeng.com/blog/2009/08/twos_complement.html ,里面讲的比我这里详细。下面简单通过一个例子来说明:
12345 是一个十进制数,其二进制是 00110000 00111001(这里暂且假设一个整数占 2 bytes ,这样简单)
如果二进制想要表示 -12345 这个负数,那就用其补码(即按位取反、末尾加一)得出 11001111 11000111
如果再想将 -12345 变为正数,那么再进行补码运算(即按位取反、末尾加一)即可,还会得到之前的 00110000 00111001 —— 这里体会到了补码运算的奥秘了,可以来回“捣腾”,完全符合数学中对正数负数的运算逻辑
如果要计算 12345 + (-12345) 的话,只需要将这两个二进制相加,得到 1 00000000 00000000 ,但是这里一个整数只有 2 bytes ,因此第一位的 1 会被移除,得到的正好是 00000000 00000000 ,和数学运算一样 —— 又一次感受到补码运算的奥秘!!!
而且,计算机只有加法器没有减法器,如果计算 a - b,就会转换为 a + (-b) ,其中采用补码计算 -b ,然后直接做加法运算。这样也从硬件上节省了资源
有符号数和无符号数
计算机肯定是看不懂正数、负数的,它只能识别二进制数字。那么计算机如何知道一个数是正数还是负数呢?要看两点:
这个变量的类型是有符号还是无符号,C 语言中有相关的语法
如果是无符号数,则正常解析。如果是有符号数,则判断第一位:第一位是 0 则是正数,第一位是 1 则是负数 —— 这仅仅是软件逻辑上的一个约定。
因此,有符号数的可用存储空间,比无符号数要少一个 bit ,因为第一个 bit 要表示符号
因此 C 语言中的数字类型就有很多种,适用于不同长度。而每种数字类型,又分有符号性和无符号型。即便是是0也可以有符号或者无符号两种表示,因为两者对二进制代码的解析方法不一样。
PS:日常开发中,尽量别用无符号数,会带来运算问题。C 语言中,有符号数和无符号数一起进行算数运算是,会将有符号数转换为无符号数(负数第一 bit 的 1 就不再代表负数了)再进行运算,很危险!!!除非特殊场景,例如摸运算或者按位运算。
其他
除法计算比较复杂,如果遇到以 2 为底数的除法,尽量使用位运算。例如 js 中的 >> 。64 >> 2 === 16 ,即将 64 转换为 2 进制,然后整体右移 2 位。这种运算效率会非常快 —— 但是估计现代编译器会捕捉到这一特点,将除法自动编译为位运算。
浮点数
浮点数的二进制表示比较复杂,细节部分可以忽略
十进制小数如何转换为二进制小数
规则是:整体规则是“乘 2 取整,顺序排列”,例如:
十进制 0.5 二进制就是 0.1
0.5 * 2 = 1,取整数 1
十进制 0.25 二进制就是 0.01
0.25 * 2 = 0.5 ,取整数 0
0.5 * 2 = 1 ,取整数 1
十进制的 0.2 二进制就是 0.00110011001100110011…… 无限循环
0.2 * 2 = 0.4 ,取整数 0
0.4 * 2 = 0.8 ,取整数 0
0.8 * 2 = 1.6 ,取整数 1
0.6 * 2 = 1.2 ,取整数 1
0.2 * 2 = 0.4 ,取整数 0
…… 无限循环了(只能到某个精度为止)
因此,二进制能精确表示的小数,只能是若干次 *2 能得到整数的值。其他情况如 0.2 就无法精确表示,只能精确到某个度,因此 C 语言才有单精度 float 和双精度 double 浮点数。
浮点数的二进制存储
符号位 S ,都占 1 bit ,0 表示非负数,1 表述负数
指数 E
有效数字 M
通过以上几个区域能计算出它存储的浮点数的数值,按公式 V = (-1)^S * M * 2^E 。不同精度的浮点数,这几个区间的大小不一致:
32 位浮点数 float 中:S 占 1 bit , E 占 8 bit ,M 占 23 bit ,总共 32 bit
64 位浮点数 double 中:S 占 1 bit , E 占 11 bit ,M 占 52 bit ,总共 32 bit
整数和浮点数的转换
浮点数转换为 int ,直接舍弃小数部分
int 转换为 double ,能精确转换。因为 double 的存储部分 M 比 int 的 32 位要大
int 转换为 float ,不会溢出但可能会被舍入 。因为 float 存储部分 M 只有 23 位,没有 int 的 32 位大
x86 计算机系统结构
我感觉这部分算是对计算机组成原理的一个简单介绍,但我更加推荐大家去专门的计算机组成原理的课程去详细学习。
计算机系统结构模型
主要结构分为:
CPU ,内存,输入输出设备
它们之间通过系统总线连接
x86 的保护模式
8086 是 intel 在 1978 年发布的 16 位处理器,80386 是 1985 年 intel 发布的 32 位处理器(寄存器 32 位)。80386 有三种工作模式:
实模式:相当于一个可进行 32 未运算的 8086
保护模式:(最重要!!!)通过对程序使用的存储区进行分段、分页的存储管理机制,达到分级使用、互不干扰的目的。通俗来说,即多个程序同时运行时互不干扰,为每个任务提供一台虚拟处理器,使每个任务单独运行、互不干扰。
虚拟 8086 模式:保护模式下同时模拟多个 8086 处理器
有了保护模式,编程人员才可以在一个私有的空间内为所欲为。
和汇编程序相关的结构
就好像程序猿占有了一个(虚拟的) CPU 和一段内存地址
CPU 中包括 PC 寄存器,表示小一条指令的地址
CPU 中包括寄存器和寄存器堆,以名字来访问的快速存储单元
CPU 中有条件码,用于存储最近执行指令的结果状体信息,用于条件指令的判断执行
内存即以字节编码的连续存储空间,存放代码、数据、运行栈、以及操作系统数据
这部分内容中,寄存器的知识对于汇编语言是很重要的,阮一峰老师的博客中也介绍了寄存器,大家可以去参考。
程序执行时的内存模型
汇编语言是面向机器的最基础编程,既然是编程就涉及到内存的使用和分配,于是就有了内存模型。这部分的知识,我感觉阮一峰老师的博客中已经写的很详细了,我也会参考他的文章来进行下文的总结。
分配内存空间
某个程序开始运行之前,操作系统会给它分配一段内存空间,用于存储改程序时使用的、产出的数据。具体这块内存区域的大小和起止指针先不用关心。
栈 Stack
栈这个数据结构的特点是“先进后出”。像 C 语言这种“过程调用过程”后者“函数调用函数”的执行方式,最先调用的过程或者函数,会是最后一个结束。这一特点和栈的特点基本一致。
需要强调一点,在整个这段内存空间中,栈是自上(高地址)而下(低地址)进行累积的,即栈顶的内存地址比栈底的内存地址要小。这一点和堆正好相反,如下图:
压栈 push
当一个过程或者函数被执行时,会有一些数据(参数、局部变量、返回地址)需要临时存储起来。而且在“函数调用函数”的整个过程中,会有很多这样的操作。那么就在每个函数执行时,将这些数据压栈。如下图,注意调用链和压栈的关系(其中两个 amI 是发生了递归调用)。
当前正在执行的函数对应的栈,叫做“栈帧”,%ebp 和 %esp 两个寄存器分别存储了该栈帧两端的地址。
PS:递归和循环虽然都可以满足某些计算场景,但是在构建内存模型上是完全不一样的,递归复杂度更高。
出栈 pop
栈中的数据是有声明周期的,每个函数执行完 return 之后,其对应的数据就要被 pop ,并释放这段内存空间。因此栈的内存空间是由系统分配、系统自动释放,不需要人为干预。人只管好好写自己的程序就 OK 了。
可以拿上图中的调用链和栈写一个详细的调用过程:
尚未开始调用,栈可以视作是空的
yoo 函数被调用,yoo 的数据被压栈
yoo 函数中又调用了 who 函数,who 的数据被压栈
who 函数中又调用了 amI 函数,amI 的数据被压栈
amI 函数中又递归调用了 amI 函数,amI 的数据被压栈
这里注意:压栈其实是自上而下的累计
amI 函数 return ,出栈
amI 函数 return ,出栈
who 函数 return ,出栈
yoo 函数 return ,出栈
最终,栈又回到之前的空状态
无论是压栈还是出栈,%ebp 和 %esp 寄存器一直随着栈帧的变化而变化
其他
有一个程序猿知名网站叫 stackoverflow ,意思就是“栈溢出”。按照上述模型的理解,就是程序执行时栈内存累计过多,导致溢出了整个分配的内存空间了。常见的导致这种问题的方式是大量的递归调用,可以用“尾递归”来解决这一问题,感兴趣的可以去具体查一查。
堆 heap
在整个程序被分配的内存空间里,栈是系统自己使用和分配,自上而下的累积。其中还有一部分内存空间是给程序猿使用的,即你可以通过程序动态占有一部分内存(如 C 语言的 malloc ,C++ 的 new ,其他高级语言的引用类型),这部分内存叫“堆”。它和栈不一样:
堆是 自下(内存低地址)而上(内存高地址) 的累积的
堆没有“先进后出”这种规则,它就是简单粗暴的占有和释放
堆中被占用的内存不会自动释放,需要手动释放,或者通过虚拟机定期 GC (如常见的引用计数方法、标记清除方法等)
常说的内存泄露就是在堆中占有的内存没有被及时的清理或者 GC ,导致长时间积累之后内存崩溃。对于 JS 开发者,应该知道 Chrome devtools 中有一个 heap Snapshot ,用来记录当前时刻 JS 堆内存,如下图:
常见数据结构的存储方式
以 C 语言中的数组和结构体为例。
C 语言中,数组需要一个连续的存储空间,每个数组需要一个 L * sizeOf(T) 字节的空间。例如 10 个 int 元素的数组,其空间就需要 10 * 4 = 40 bytes 的空间。通过这个存储格式,就可以很容易的遍历、访问到数据的每个元素。用 %edx 寄存器存储起始地址,用 %eax 表示 index ,那么 (%edx, %eax, 4) 就是这个当前元素的内存地址(4 即取出 4 bytes 长度的内容,int 类型占 4 bytes)。二维数组也是同样的道理。
PS:数组和链表有时候看着用途一样,但是数据结构上是有明显区别的,链表不需要一个连续的存储空间。
C 语言结构体也需要一个连续的存储空间,结构提内部通过名字访问,每个元素都可以有不同的类型。
struct rec {
int i;
init a[3];
int *p; // *p 表示一个内存地址,&p 可以获取该地址的值
}
以上代码将会被分配这样一个连续的内存地址:0 - 4 存放 i(4 bytes),接着 5 - 16 存放数组(3 个 int),接着 16 - 20 存放指针(32 位指针)。
简单的汇编指令
虽然本课是主讲汇编语言,课程中也花了大量的时间讲解了常用的指令、示例以及 C 语言和汇编语言的如何对应。不过对于我这种以了解汇编、学习基础知识为目的的高级语言的开发者,并没有去认真听每个指令的具体意义。不知道这是不是常说的“不求甚解”。
简单指令
课程中几个比较简单的汇编指令如下:(阮一峰老师的博客中也讲了一些常用指令,讲的更加详细,可以去学习)
addl 参数1, 参数2 加法
movl Source, Dest 赋值
leal Source, Dest 计算出地址赋值给 Dest
cmpl Src2, Src1 比较,类似于计算 Src2 - Src1
上述两个指令,add 和 mov 等表示指令类型,后面的 l 是一个后缀,表示一次性操作 2 bytes 。这样的后缀还有很多,例如 b w ,都有不同的含义,不过不用去管它。
参数中,%edx 表示某个寄存器,(%edx) 表示将这个寄存器的值作为内存地址,$ 开头的是一个立即数。8(%edx) 找到某个内存地址并连续读取 8 bits 内容(如 int 类型就占 8 bits)。
条件码和分支
上文中【和汇编程序相关的结构】图中可以看到,CPU 中有“条件码”。例如,x86 中常用的四个条件码(其实我也不知道怎么用……)
CF,Carry(进位) Flag
SF,Sing Flag
ZF,Zero Flag
OF,OverFlow Flag
(每个条件码只占 1 bit 空间,可见它是一个 boolean 型的存在)
在指令运行过程中,硬件会根据指令运行的状态实时的修改这些条件码的值,然后用 set 指令,从条件码中读出来,放入通用寄存器中,然后就可以用于分支跳转了。细节没具体看。
跳转
以 j 开头的一系列指令,满足不同的条件即可跳转到某个程序块。例如 jmp 是无条件跳转,je 是 ZF 条件码为 0 时才跳转,jne 是 ZF 条件码不是 0 时才跳转。跳转的语法类似于 C 语言的 goto 语句,但在 C 语言中不推荐使用 goto 语句。
执行逻辑验证
高级编程语言中有三种基本的执行逻辑:第一,顺序执行,这个对应汇编语言没啥问题;第二,分支执行(即 if else);第三,循环执行。后两种,通过判断条件码和跳转也都可以实现。
关于递归,课程中也讲了很多内容,不过我没看懂(没有那么那么认真的看,看不懂就算了……)。
程序示例
如果想简单看一下汇编语言是什么样子的,可以通过 gcc 编译一段简单的 C 语言来看下。首先,新建一个 hello.c 的文件然后写上如下内容并保存。
#include
#include
int main() {
printf("hello word
");
exit(0);
return 0;
}
在该文件目录中运行 gcc -S -O2 -m32 hello.c ,然后即可看到生成了一个 hello.s 的文件,内容如下:
.section__TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl_main
.p2align4, 0x90
_main: ## @main
## BB#0:
pushl%ebp
movl%esp, %ebp
subl$8, %esp
calllL0$pb
L0$pb:
popl%eax
lealL_str-L0$pb(%eax), %eax
movl%eax, (%esp)
calll_puts
movl$0, (%esp)
calll_exit
subl$4, %esp
.section__TEXT,__cstring,cstring_literals
L_str: ## @str
.asciz"hello word"
.subsections_via_symbols
这就是 C 语言编译出来的汇编语言。具体的示例,可以去看阮一峰老师那篇博客最后的内容,他在博客中对一段汇编语言做了详细的解释。我这里就省略了。
最后
仅仅是一个学习笔记,发现错误欢迎指正。
大家可以关注一下课程
-
golang 没有名字参数_Golang入门(2):一天学完GO的基本语法
2021-01-06 23:16:49因为这篇文章只是入门Golang的第二篇文章,所以本文并不会对一些指令进行深挖,仅仅只是停留在“怎么用”的程度,至于“为什么是这样”,则涉及到了具体的应用场景和汇编指令,作者将会在以后的文章中进行介绍。... -
编程究竟如何去学
2011-06-22 08:15:00从最开始的c语言,汇编,c++,python,Java,c#,怎么说也看了这么多学编程的书,但是突然叫我来一个程序,我却显得力不从心,记得每一门编程语言都是从最经典的“hello world!”开始,然后是基本知识最后到界面,... -
韦东山老师的视频适合什么基础的人?
2018-10-12 10:34:04大家好,我是零基础的,之前是化学专业的...目前刚刚学完郝斌老师的C自学教程,在看《C primer plus》巩固一下C,接下来打算学王爽老师《汇编语言》。现在有以下疑问: 1、在学完这两门课之后,能不能直接看韦东山... -
0、什么是变量,什么是shell编程
2018-03-30 15:23:05shell编程: 编译器:也叫解释器shell给我们提供另外一个功能...静态语言:编译型语言(有程序开发环境,不需要借助额外的二进制程序,直接写代码,写完之后需要一个编译器,将代码放到编译器就可以交给硬件形成一个... -
c语言中变量问题
2015-03-21 09:43:52这些问题一直困扰着我,终于在学习完汇编之后,我明白了变量在内存中的位置。了解了这些才能写出更优秀的代码。首先全局变量与局部变量是有本质区别的,初始化的全局变量保存在data段,这一般是在代码段的最后;未... -
OO2019第一次作业总结
2019-03-27 09:01:00这个问题应该是始终贯穿整个OO课程的核心问题之一,在上完每一堂课,写完每一次作业或是写下每一个类和对象之后我们都应该考虑一下这个问题,OOP带给了我们什么好处?其实在每学习一个新的概念的时候,我们都应该去... -
心情记录
2018-04-20 22:21:4830天自制操作系统系列还没有总结完其实我感觉这个玩具系统写了一遍之后就没什么激情再来复习一遍了....这个排到最后吧2.BIOS编程总结复习由于BIOS编程是基于16位的8086汇编,而且想要深入理解操作系统这部分是必不... -
开发人员应该具备的双重思维
2011-10-20 17:15:00作为一个程序员,我大概经历下面几个阶段: 第一个阶段,是刚上大学时候的编程课。...第二个阶段,是学完《数据结构》和《数据库》之类的课程之后,教科书教我时间复杂度和空间复杂度,主要在这些事... -
1804_4 随笔
2015-01-26 10:23:22电脑配好之后,开始想着要做点什么,编程,渗透下定决心都想要再努力的学点。 第二天,在大牛的引导下,确定了三个点。 1.win32汇编 2.windows核心编程 3.之前写的驱动继续实现它。 和大牛谈完话之后... -
经验分享:六大IT公司面试亲历精采回放
2008-05-30 14:39:43爱立信: 爱立信的特色是楼里有超多老外。笔试题出得不错,给一张考卷一本技术手册。 技术手册提供了一套汇编指令集,有每...其实汇编和单片机学得稍微好点就不会有什么技术上得障碍了,感觉很大程度上是在考快速阅... -
1-系统移植_u-boot移植
2017-02-03 15:14:25c语言、汇编、脚本、Makefile、Kconfig、设备树装windows:BIOS界面、运行系统内核、安装驱动、装软件移植就是给一个开发板装一个系统:学完这门课之后我们都是嵌入式的网管嵌入式平台:引导程序(u-boot)、uImage、写... -
记ICS的lab2--bomb实验
2019-03-18 13:50:00如果不是等到全部解完已经过去一周之后才写报告,我想我是不能心平气和的回顾这个过程,真是太痛苦了,我明明什么都不会,就要开始做实验。不过真的学到很多,可以说我的汇编都是因为这个实验才学会的吧。虽然很难,... -
Chapter 5 Hiding the Implementation
2010-05-17 16:34:00现在想好好学学java了,学校里的c和汇编帮我打下了学语言的基础。要把Thinking in java看完,并写些程序。PackagePackage感觉类似于c中的include语句,主要是让我们可以使用编译好的class文件(一个compile unit如果... -
关于堆和栈
2011-04-07 11:52:00堆是程序可以自由操作的内存,使用时先申请,用完之后释放,如何使用完全由程序代码控制。 2.栈在汇编代码中表示成PUSH POP,用的是ESS段,SP寄存器 而堆不是,是在内存中读写,EDS段, 3. C++包括两种被应用... -
自己动手写操作系统(含源代码).part2
2010-10-18 19:47:45所谓填补空白,具体说就是让像我一样的操作系统爱好者在读完本书之后,能够有信心去读其他比较流行的开源的操作系统代码,有能力从零开始自己动手写操作系统,而这个任务第一版已经完成了。 那么为什么我又写作了第... -
自己动手写操作系统(含源代码).part1
2010-10-18 19:41:25所谓填补空白,具体说就是让像我一样的操作系统爱好者在读完本书之后,能够有信心去读其他比较流行的开源的操作系统代码,有能力从零开始自己动手写操作系统,而这个任务第一版已经完成了。 那么为什么我又写作了第... -
疯狂的程序员
2012-07-18 18:05:32就算有3000人买,每人每月买1根,都要3个月才卖完。你们都不是做生意的材料。看我去弄个大CASE过来。” 绝影这么说,就这么去做了。正好到学校开运动会,校园里凡是能挂的地方都挂了赞助商的广告。他觉得做广告这个... -
C语言FAQ 常见问题列表
2010-10-28 16:41:29o 2.2 64 位机上的 64 位类型是什么样的? o 2.3 怎样定义和声明全局变量和函数最好? o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 ... -
C语言入门经典(第4版)--源代码及课后练习答案
2013-02-02 17:18:55他曾在IBM工作多年,能使用多种语言进行编程(在多种机器上使用汇编语言和高级语言),设计和实现了实时闭环工业控制系统。Horton拥有丰富的教学经验(教学内容包括C、C++、Fortran、PL/1、APL等),同时还是机械、加工... -
C语言入门经典(第4版)--详细书签版
2013-02-02 17:16:50他曾在IBM工作多年,能使用多种语言进行编程(在多种机器上使用汇编语言和高级语言),设计和实现了实时闭环工业控制系统。Horton拥有丰富的教学经验(教学内容包括C、C++、Fortran、PL/1、APL等),同时还是机械、加工... -
你必须知道的495个C语言问题
2015-10-16 14:14:281.2 为什么不精确定义标准类型的大小? 1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都解决... -
你必须知道的495个C语言问题(高清版)
2010-03-31 16:24:091.2 为什么不精确定义标准类型的大小? 2 1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都... -
《你必须知道的495个C语言问题》
2010-03-20 16:41:181.24 我在一个文件中定义了一个extern数组,然后在另一个文件中使用,为什么sizeof取不到数组的大小? 13 声明问题 14 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 14 *1.26 main的正确...
-
IpTools.exe
-
实现 MySQL 读写分离的利器 mysql-proxy
-
java流程控制
-
perl-DBI-1.40-5.i386.rpm
-
毛概课件 第七章改革和对外开放.ppt
-
分享一个查看外网IP的工具
-
VMware vSphere ESXi 7 精讲/VCSA/VSAN
-
NFS 实现高可用(DRBD + heartbeat)
-
MySQL 数据类型和运算符
-
Performance Index 64 Pro for Mac(系统性能监测软件)
-
airxzip.zip
-
galaxy-vae-源码
-
Java程序运行机制
-
QT编程思想【C++,基于QT 6】
-
微信质量群采集助手
-
毛概课件 第六章社会主义初级阶段理论.ppt
-
基于Flink+Hudi构建企业亿级云上实时数据湖教程(PC、移动、小
-
SSL证书与CA数字证书有什么区别?
-
ImageWatch2017.vsix
-
【布道者】Linux极速入门