array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 Linux内核分析学习笔记(一) - 爱码网
codcompiling

从今天开始学习网易云课堂孟宁老师的《Linux内核分析》课程,链接地址:http://mooc.study.163.com/course/USTC-1000029000#/info,记录课程学习笔记。

第一周的内容主要介绍了冯诺依曼体系结构ATT格式的32位x86汇编语言以及一个简单的c程序反汇编成汇编代码的执行分析过程

 

一、冯诺依曼体系结构——存储程序式计算机

  冯诺依曼体系结构的核心是存储程序,将数据和代码都存储在存储器中,都是二进制数据,通过特定的模块来分辨数据与代码。冯诺依曼体系结构的计算机包括运算器、控制器、存储器、输入单元、输出单元五大件。

 

 

二、ATT格式的32位x86汇编

1、32位cpu的寄存器结构

通用寄存器

 

8位寄存器:ah、al、bh、bl、ch、cl、dh、dl

16位寄存器:ax、bx、cx、dx、bp、si、di、sp

32位寄存器:eax、ebx、ecx、edx、ebp、edi、esi、esp

注意:

1、8位寄存器与16位寄存器是独立的,例如低8位寄存器al的运算结构溢出并不会影响到高8位寄存器ah,同样16位寄存器ax不会影响到32位寄存器eax的高16位

2、通常情况下eax作为累加器,ebx作为基址寄存器,ecx作为计数器,edx作为数据寄存器,ebp作为堆栈基指针寄存器(栈底),esi、edi作为变址寄存器,esp作为堆栈顶指针寄存器。

段寄存器

cs代码段寄存器

ds数据段寄存器

ss栈段寄存器

es扩展段寄存器

gs、fs附加段寄存器

标志寄存器

 

 

2、几种ATT汇编指令

mov: 数据传送,可分为movb、movw、movl三种,分别传送一个字节、一个字、双字。

 

pushl入栈,pushl %eax相当于:

                      subl $4, %esp

                      movl %eax, (%esp)

popl:出栈, popl %eax相当于:

                      movl (%esp), %eax

                      add $4, %esp            

 call:call f:相当于

                      pushl %eip

                      movl f, %eip

ret: ret相当于:

                    popl %eip    

enter:相当于:

                       pushl %ebp

                       movl %esp, %ebp

leave:相当于:

                       movl %ebp, %esp

                       pop %ebp

 

注意:

Intel汇编与ATT汇编在多个操作数的时候,列出的操作数的顺序是相反的。

虽然上面对pushl和popl的解释中修改了eip,实际中程序员不能够手动直接操作eip,可以通过其他指令间接修改。

 

三、一个简单c程序反汇编分析

实验环境:https://www.shiyanlou.com/courses/running/555

1、试验阶段

 

编写c代码:

编译生成汇编代码:

gcc –S –o main.s main.c –m32

 

观察分析汇编代码

删除无关信息后的汇编代码main.s:

2、实验分析

函数调用堆栈的分析

观察上面汇编代码的每个函数main、f、g发现,每个函数的开始和结束都是一样的:

        pushl %ebp
        movl %esp, %ebp

        leave
        ret

上面两条指令相当于enter,用来构建一个函数堆栈框架,leave表示退出当前框架,分析如下:

进入函数前的初始状态:

进入函数enter:

中间进行一系列其他操作后,执行leave:

最终又恢复到进入函数之前的状态

分析c程序的汇编代码

同c程序从main函数开始执行一样,汇编代码从main标签开始执行:

        进入main函数前的内存状态

①从18行开始执行至22后:

18        pushl    %ebp
19        movl     %esp, %ebp
20        subl     $4, %esp
21        movl    $8, (%esp)
22        call       f

 

此时取出22行代码call f 后, %eip = 23

②执行22行 call f,先将当前eip(23)入栈,然后将f的地址传入eip,跳转至9行

pushl %eip
movl f, %eip

 

③进入f,构造f的堆栈框架,执行至11行:

9       pushl    %ebp
10      movl     %esp, %ebp
11      subl     $4, %esp

 

执行

12  movl 8(%ebp), %eax
13  movl %eax,  (%esp) 

此时%eax = 8

④执行

14        call g

 

将当前%eip(15)压栈,进入g,构建g的堆栈框架:

2        pushl        %ebp
3        movl         %esp, %ebp
4        movl         8(%ebp), %eax
5        addl         $3,   %eax

 

执行至6行:       %eax = 11

执行

6        popl     %ebp

 

销毁g堆栈框架:

执行

7        ret 

 

即popl %eip后, %eip = 15,回到第15行执行指令

⑤执行15行

15        leave

 

即:

pushl %ebp, %esp
popl %ebp

 销毁f的堆栈框架:

执行16行:

16        ret

 

  此时 %eip = 23,%eax = 11

  跳转至23行

23        addl        $1, %eax

 

此时%eax = 12

⑥执行24行

24        leave

 

销毁main的堆栈框架:

 

又恢复到初始状态,而函数的返回值默认存放在%eax中,即%eax = 12,

继续

25        ret

 

恢复至进入main之前的状态。

至此,上述c程序的汇编代码分析完毕。

分类:

技术点:

相关文章: