要彻底搞清楚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语法源和目标是相反的哦);

前两条指令都是为这条指令做准备的,执行这条指令时发生以下动作:

  1. int指令称为软中断指令,可以用这条指令故意产生一个异常,上一章讲过,异常的处理和中断类似,CPU从用户模式切换到特权模式,然后跳转到内核代码中执行异常处理程序。

  2. int指令中的立即数0x80是一个参数,在异常处理程序中要根据这个参数决定如何处理,在Linux内核中int $0x80这种异常称为系统调用(System Call)。内核提供了很多系统服务供用户程序使用,但这些系统服务不能像库函数(比如printf) 那样调用,因为在执行用户程序时CPU处于用户模式,不能直接调用内核函数,所以需要通过系统调用切换CPU模式,经由异常处理程序进入内核,用户程序只 能通过寄存器传几个参数,之后就要按内核设计好的代码路线走,而不能由用户程序随心所欲,想调哪个内核函数就调哪个内核函数,这样可以保证系统服务被安全 地调用。在调用结束之后,CPU再切换回用户模式,继续执行int $0x80的下一条指令,在用户程序看来就像函数调用和返回一样。

  3. eaxebx的值是传递给系统调用的两个参数。eax的值是系统调用号,Linux的各种系统调用都是由int $0x80指令引发的,内核需要通过eax判断用户要调哪个系统调用,_exit的系统调用号是1。ebx的值是传给_exit的参数,表示退出状态。大多数系统调用完成之后会返回用户空间继续执行后面的指令,而_exit系统调用比较特殊,它会终止掉当前进程,而不是返回用户空间继续执行

  4. “jump if equal”;jmp是一个无条件跳转指令,什么条件也不判断,直接跳转;jle表示“jump if less than or equal”

    汇编寻址;

  5. 访问内存时在指令中可以用多种方式表示内存地址,比如可以用数组基地址、元素长度和下标三个量来表示,增加了寻址的灵活性
  6. parcel存储库url
  7. 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的更多相关文章

  1. Atitit.软件开发的几大规则,法则,与原则Principle v3

    Atitit.软件开发的几大规则,法则,与原则Principle  v31.1. 修改历史22. 设计模式六大原则22.1. 设计模式六大原则(1):单一职责原则22.2. 设计模式六大原则(2):里 ...

  2. C#设计模式系列:开闭原则(Open Close Principle)

    1.开闭原则简介 开闭原则对扩展开放,对修改关闭,开闭原则是面向对象设计中可复用设计的基石. 2.开闭原则的实现 实现开闭原则的关键就在于抽象,把系统的所有可能的行为抽象成一个抽象底层,这个抽象底层规 ...

  3. 开放封闭原则(Open Closed Principle)

    在面向对象的设计中有很多流行的思想,比如说 "所有的成员变量都应该设置为私有(Private)","要避免使用全局变量(Global Variables)",& ...

  4. 最少知识原则(Least Knowledge Principle)

    最少知识原则(Least Knowledge Principle),或者称迪米特法则(Law of Demeter),是一种面向对象程序设计的指导原则,它描述了一种保持代码松耦合的策略.其可简单的归纳 ...

  5. 接口分离原则(Interface Segregation Principle)

    接口分离原则(Interface Segregation Principle)用于处理胖接口(fat interface)所带来的问题.如果类的接口定义暴露了过多的行为,则说明这个类的接口定义内聚程度 ...

  6. 依赖倒置原则(Dependency Inversion Principle)

    很多软件工程师都多少在处理 "Bad Design"时有一些痛苦的经历.如果发现这些 "Bad Design" 的始作俑者就是我们自己时,那感觉就更糟糕了.那么 ...

  7. 里氏替换原则(Liskov Substitution Principle)

    开放封闭原则(Open Closed Principle)是构建可维护性和可重用性代码的基础.它强调设计良好的代码可以不通过修改而扩展,新的功能通过添加新的代码来实现,而不需要更改已有的可工作的代码. ...

  8. 单一职责原则(Single Responsibility Principle)

    单一职责原则(SRP:The Single Responsibility Principle) 一个类应该有且只有一个变化的原因. There should never be more than on ...

  9. [Design Patterns] 2. Design principle

    Single Responsibility Principle 类的设计趋向于:Use Case Diagram --> (derived) --> Detail Open-Closed ...

随机推荐

  1. 【leetcode】Longest Common Prefix (easy)

    Write a function to find the longest common prefix string amongst an array of strings. 思路:找最长公共前缀 常规 ...

  2. 吐槽C++

    个人感觉,在c++ 道路的学习路上,遇到很多的坎坷,现在回想起来,最关键一点就是 c++知识点繁杂很多,教科书很多知识点都没有提到. 但是在实际工作中,这些没有提到的知识点,却又经常会用到(或者看开源 ...

  3. ANDROID_MARS学习笔记_S01_006ImageView

    一.ImageView介绍 设置scalType Must be one of the following constant values. Constant Value Description ma ...

  4. R语言学习笔记:生成序列(Genenrating Sequences)

    R提供了多种生成不同类型序列的方法.如: > x<-1:20 > x [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 1 ...

  5. ActiveMQ可靠性机制

    消息的签收(Acknowledgment): 客户端成功接收一条消息的标志是这条消息被签收. 成功接收一条消息一般包括如下三个阶段: (1) 客户端接收消息  (2) 客户端处理消息   (3) 消息 ...

  6. 查看32bit的ARM(比如ARMv7)反汇编

    1.使用./arm-eabi-as test.S -o test.o编译 2.使用./arm-eabi-objdump -d test.o反汇编

  7. 【TopCoder】SRM 680 DIV 2

    1. BearPair之bigDistance1.1 题目概述在 <= 50的字符串中找位置i,j 满足(1) s[i] != s[j];(2) abs(i-j)尽可能大.若不存在返回-1, 否 ...

  8. Scrapy在win7 32位的安装及依赖包

    Scrapy,一个网络爬虫的框架,首先第一步肯定是安装. 参考网上的文章. 安装过程中需要用到pip工具,请自行安装. 1.安装python 这个是必须的,既然都用到scrapy了,肯定已经安装了py ...

  9. poj2752 水题

    又2b了一次…… var s:ansistring; ans,pre:..] of longint; i,k,tot:longint; procedure main; begin pre[]:=;k: ...

  10. I.MX6 Android i2c-tools porting

    /************************************************************************** * I.MX6 Android i2c-tool ...