从assemblyer Instructure deepth understander C principle
要彻底搞清楚C语言的原理,就必须深入到指令一层去理解。你写一行C代码,编译器会生成什么样的指令,要做到心中有数;
涉及到的as assembly
链接器 ld;
用汇编器翻译成机器指令了还不行,还要有一个链接的步骤呢?链接主要有两个作用,一是修改目标文件中的信息,对地址做重定位
二是把多个目标文件合并成一个可执行文件;
#
号表示单行注释,类似于C语言的//
注释,和shell注释一样;
汇编程序中以.
开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。.section
指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。.data
段保存程序的数据,是可读可写的,相当于C程序的全局变量。本程序中没有定义数据,所以.data
段是空的。
.text
段保存代码,是只读和可执行的,后面那些指令都属于.text
段;
_start
是一个符号(Symbol), 符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值。在C语言中我们通过变量名访问一 个变量,其实就是读写某个地址的内存单元,我们通过函数名调用一个函数,其实就是跳转到该函数第一条指令所在的地址,所以变量名和函数名都是符号,本质上 是代表内存地址的。
.globl
指示告诉汇编器,_start
这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号
_start
就像C程序的main
函数一样特殊,是整个程序的入口,链接器在链接时会查找目标文件中的_start
符号代表的地址,把它设置为整个程序的入口地址,所以每个汇编程序都要提供一个_start
符号并且用.globl
声明。如果一个符号没有用.globl
声明,就表示这个符号不会被链接器用到。
汇编程序中,立即数前面要加$,寄存器名前面要加%,以便跟符号名区分开。以后我们会看到mov
指令还有另外几种形式,但数据传送方向都是一样的,第一个操作数总是源操作数,第二个操作数总是目标操作数。(注意这里是AT&T汇编语法,intel语法源和目标是相反的哦);
前两条指令都是为这条指令做准备的,执行这条指令时发生以下动作:
int
指令称为软中断指令,可以用这条指令故意产生一个异常,上一章讲过,异常的处理和中断类似,CPU从用户模式切换到特权模式,然后跳转到内核代码中执行异常处理程序。int
指令中的立即数0x80是一个参数,在异常处理程序中要根据这个参数决定如何处理,在Linux内核中int $0x80
这种异常称为系统调用(System Call)。内核提供了很多系统服务供用户程序使用,但这些系统服务不能像库函数(比如printf
) 那样调用,因为在执行用户程序时CPU处于用户模式,不能直接调用内核函数,所以需要通过系统调用切换CPU模式,经由异常处理程序进入内核,用户程序只 能通过寄存器传几个参数,之后就要按内核设计好的代码路线走,而不能由用户程序随心所欲,想调哪个内核函数就调哪个内核函数,这样可以保证系统服务被安全 地调用。在调用结束之后,CPU再切换回用户模式,继续执行int $0x80
的下一条指令,在用户程序看来就像函数调用和返回一样。eax
和ebx
的值是传递给系统调用的两个参数。eax
的值是系统调用号,Linux的各种系统调用都是由int $0x80
指令引发的,内核需要通过eax
判断用户要调哪个系统调用,_exit
的系统调用号是1。ebx
的值是传给_exit
的参数,表示退出状态。大多数系统调用完成之后会返回用户空间继续执行后面的指令,而_exit
系统调用比较特殊,它会终止掉当前进程,而不是返回用户空间继续执行- “jump if equal”;
jmp
是一个无条件跳转指令,什么条件也不判断,直接跳转;jle
表示“jump if less than or equal”汇编寻址;
- 访问内存时在指令中可以用多种方式表示内存地址,比如可以用数组基地址、元素长度和下标三个量来表示,增加了寻址的灵活性
- parcel存储库url
- http://www.cloudera.com/content/cloudera-content/cloudera-docs/CM4Ent/latest/Cloudera-Manager-Administration-Guide/cmag_db_for_cm_upgrades.html
从assemblyer Instructure deepth understander C principle的更多相关文章
- Atitit.软件开发的几大规则,法则,与原则Principle v3
Atitit.软件开发的几大规则,法则,与原则Principle v31.1. 修改历史22. 设计模式六大原则22.1. 设计模式六大原则(1):单一职责原则22.2. 设计模式六大原则(2):里 ...
- C#设计模式系列:开闭原则(Open Close Principle)
1.开闭原则简介 开闭原则对扩展开放,对修改关闭,开闭原则是面向对象设计中可复用设计的基石. 2.开闭原则的实现 实现开闭原则的关键就在于抽象,把系统的所有可能的行为抽象成一个抽象底层,这个抽象底层规 ...
- 开放封闭原则(Open Closed Principle)
在面向对象的设计中有很多流行的思想,比如说 "所有的成员变量都应该设置为私有(Private)","要避免使用全局变量(Global Variables)",& ...
- 最少知识原则(Least Knowledge Principle)
最少知识原则(Least Knowledge Principle),或者称迪米特法则(Law of Demeter),是一种面向对象程序设计的指导原则,它描述了一种保持代码松耦合的策略.其可简单的归纳 ...
- 接口分离原则(Interface Segregation Principle)
接口分离原则(Interface Segregation Principle)用于处理胖接口(fat interface)所带来的问题.如果类的接口定义暴露了过多的行为,则说明这个类的接口定义内聚程度 ...
- 依赖倒置原则(Dependency Inversion Principle)
很多软件工程师都多少在处理 "Bad Design"时有一些痛苦的经历.如果发现这些 "Bad Design" 的始作俑者就是我们自己时,那感觉就更糟糕了.那么 ...
- 里氏替换原则(Liskov Substitution Principle)
开放封闭原则(Open Closed Principle)是构建可维护性和可重用性代码的基础.它强调设计良好的代码可以不通过修改而扩展,新的功能通过添加新的代码来实现,而不需要更改已有的可工作的代码. ...
- 单一职责原则(Single Responsibility Principle)
单一职责原则(SRP:The Single Responsibility Principle) 一个类应该有且只有一个变化的原因. There should never be more than on ...
- [Design Patterns] 2. Design principle
Single Responsibility Principle 类的设计趋向于:Use Case Diagram --> (derived) --> Detail Open-Closed ...
随机推荐
- Angular.js入门的样例
感觉这下子,前端的路也宽多了,从容不迫了. 因为可控制的节点又推前了, 有空了好好学一下. 然后结合EXPRESS或METEOR,是不是有点爽? 参考URL: https://toddmotto.co ...
- hdu 4664 Triangulation 博弈论
看到这题时,当时还不会做,也没搞懂sg函数,于是狠狠的钻研了下博弈论,渐渐的知道了sg函数…… 现在在来做这题就很容易了,1A 打表容易发现在80左右的时候就出现循环节了 代码如下: #include ...
- 李洪强iOS开发之【零基础学习iOS开发】【02-C语言】07-基本数据类型
C语言有丰富的数据类型,因此它很适合用来编写数据库,如DB2.Oracle等大型数据库都是C语言写的.其中,提供了4种最常用的基本数据类型:char.int.float.double,使用这些数据类型 ...
- [itint5]二叉树转换线索二叉树
http://www.itint5.com/oj/#27 用了基于stack的中序遍历,记录一下last,就很简单了. #include <stack> /*树结点的定义(请不要在代码中定 ...
- P51、面试题5:从尾到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 链表结点定义如下: Struct ListNode{ int m_nKey; ListNode* m_pNext; }; 我们可 ...
- ubuntu 解决依赖问题
安装aptitude包管理器 然后用aptitude安装 sudo aptitude install ***
- Shell中判断字符串是否为数字的6种方法分享
#!/bin/bash ## 方法1 a=1234;echo "$a"|[ -n "`sed -n '/^[0-9][0-9]*$/p'`" ] &&a ...
- POJ2528 线段树的区间操作
首先应该对该[0,10000000]进行离散化 即先将点集进行排序,然后从小到大缩小其中的间距,使得最后点数不会超过2*n 然后就是线段树操作 只需进行染色,然后最后用nlgn进行一个个查询颜色记录即 ...
- 设计模式 - chain of Responsibility
Chain of Responsibility也就是职责链模式,通过使用链式结构,使对象都有机会处理请求,从而避免请求的发送者与接受者间的耦合关系.将这些对象连成链,并沿着该链传递请求,直到有对象处理 ...
- IE中Ajax数据缓存的问题
在IE中,Ajax回来的数据会有缓存的现象发生,解决方式: 1,改变URL,每次请求加一个随机数参数Math.random()或者new Date().getTime(),这样IE会认为URL不一样, ...