精华内容
下载资源
问答
  • -ng-repeat 用于循环创建元素 ...用来元素绑定雷鸣,其指令表达式的返回值可以为 使用控制器中的变量 通过键值对方式绑定 -ng-style 用于设定元素的css样式 -ng-show 元素是否显示,取值为布尔值,通过修改d...

    一、设计模式
    所谓的设计模式就是一套被反复使用的,多数人知道的,经过分类编写的,代码设计经验的总结,使用设计模式可以提高代码的重用性和可读性。
    1、设计模式分类
    单例模式、代理模式、观察者模式、MVC模式

    2、mvc
    m-模型,model,可以看出js中变量、对象
    v-视图,view,用于展示数据的视图,dom元素
    c-控制器,controller,用于处理m和v之间的交互,类似于js中的函数
    
    mvc的核心理念:把管理数据的代码(model)、应用逻辑代码(c)、向用户展示的数据代码(v)分离出来
    

    二、单页面应用
    1、概念
    将所有功能都局限于一个web页面,在该页面初始化时加载相应的html文件、js和css,一旦页面加载完成,页面将不会随着用户的操作而去加载页面;而是使用js动态的改变html内容;单页面应用可以提高用户体验

    2、优缺点
        1)优点
        -用户体验好
        -前后端工作分离
        -减轻服务端压力
        -可以多端共用一套代码
    
        2)缺点
        -搜索引擎难度较高
        -无法使用前进后退
        -初次加载耗时较长
    

    三、AngularJS
    1、概念
    AngularJS是一个js框架,遵循MVC设计模式,实现了视图、数据、逻辑组件间的松耦合

    -高内聚低耦合:内聚就是一个模块独立性比较强,对外界的依赖比较少;耦合指的是容易受外界影响
    
    2、Angularjs版本
    -1.x
    -2.x 16年9月
    -4.x 17年3月
    
    3、使用Angular
        首先引入Angularjs的文件,然后在指定元素添加指令ng-app="xx";
    
    3、指令
     指令是扩展的html属性,带有前缀ng-,在h5中,允许扩展自己的属性,需要以data-开头;所在html5中可以使用data-ng-开头
    1)内置指令
    -ng-app
     初始化一个AngularJS应用程序,告诉系统,该元素是Angular应用的拥有者,可以理解为js中的作用域
    
    -ng-init
     初始化应用程序数据,通常不建议使用,一般会选择使用控制器或模块
    -ng-model
    双向数据绑定,帮元素绑定到应用程序,当元素中的值发生改变或使用js改变变量值,都会相互通知;
    一般用在表单元素上
    -ng-bind
    单向数据绑定
    把参数绑定到html元素上
    

    -ng-repeat
    用于循环创建元素
    语法:
    在需要循环创建的元素上添加属性:ng-repeat=“变量 in 数组” 变量是数组中的元素,可以使用ng-bind或表达式进行值得显示

    -ng-class
    用来给元素绑定雷鸣,其指令表达式的返回值可以为
    使用控制器中的变量
    通过键值对方式绑定
    
    -ng-style
    用于设定元素的css样式
    
    -ng-show
    元素是否显示,取值为布尔值,通过修改display的值,来控制显示或不显示
    -ng-if
    元素是否显示,取值为布尔值,根据值,决定元素是否添加到页面中
    -ng-hide
    作用于ng-show类似
    
    -ng-switch
    根据一个值来决定哪个节点显示,其他节点会被移除,对应的子元素使用ng-switch-when,还可以通过ng-switch-default指令设置默认选项,如果没有匹配的,则会使用default
    
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <script src="angular.min.js"></script>
        <style>
            table,td{
                border: 1px solid black;
            }
            td{
                width: 100px;
            }
            .class1{
                border: 1px solid red;
                height: 100px;
                background-color: blue;
            }
            .class2{
                color: red;
            }
            .class3{
                font-size: 30px;
            }
        </style>
    </head>
    <body ng-app="myApp" ng-init="arr=['abc','bcs','wed','dew']" ng-controller="myVC">
    
        <ul>
            <li ng-repeat = "value in arr" ng-bind="value"></li>
        </ul>
        <div ng-init="persons = [{name:'张三',age:10,sex:'男'},
                                 {name:'李四',age:14,sex:'女'},
                                 {name:'王五',age:20,sex:'未知'}]">
    
            <table>
                <tr ng-repeat="obj in persons">
                    <td ng-bind="obj.name"></td>
                    <td ng-bind = "obj.age"></td>
                    <td ng-bind="obj.sex"></td>
                </tr>
            </table>
        </div>
        <div class = "{{className}}"></div>
        <div ng-class="{true:'class2',false:'class3'}[isHave]">123123</div>
        <div ng-style="{color:'blue'}">这是一个div</div>
        <div ng-style="styleObj">qwwqqw</div>
        <div ng-show="false">123123</div>
        <div ng-if="false">www</div>
    
        <div>
            <input type="text" ng-model="index">
            <ul ng-switch on ="index">
                <li ng-switch-when="1">123</li>
                <li ng-switch-when="2">abc</li>
                <li ng-switch-when="3">kkk</li>
                <li ng-switch-default>默认</li>
            </ul>
        </div>
        <script>
            var app = angular.module('myApp',[]);
            app.controller("myVC",function($scope){
                $scope.className = "class1";
                $scope.isHave = false;
    
                $scope.styleObj = {
                    "font-size":"30px"
                }
            })
        </script>
    </body>
    </html>
    
    展开全文
  • 或者说节省空间,现在大部分的编译器做得比一般的汇编语言初学者,甚至是有一定编程经验的人都好,对一些汇编指令有所了解后,可能利用这些指令写出符合特定条件的好的代码,不管是在shellcode还是在关键代码的...
  • IDA学习经验和实战记录--手过花指令(1)

    千次阅读 多人点赞 2019-01-01 23:39:19
    IDA学习经验和实战记录--手过花指令(1)侦壳脱壳发现问题OD辅助分析IDA实现引入分析花指令情形一情形二情形三情形四脚本去除 实验软件下载地址 侦壳 什么都没有查到 应该是自己编写的加密方式 (本身这...

    实验软件下载地址

    侦壳

    图1
    什么都没有查到
    应该是自己编写的加密方式
    (本身这就是一个加壳软件)

    脱壳

    发现问题

    图2-1
    用IDA打开后,发现最底下是红色的,且有很多黑色部分(未知)
    还有大部分的data数据,而且没有发现已解锁的函数(蓝色部分)
    需要进行脱壳

    OD辅助分析

    图2-1-1
    OD打开,发现一开始有pushad
    说明肯定是加壳了的
    向下单步跟踪一下,发现有很多 花指令

    图2-1-2
    (跳转来条转去的)
    现在主要是学习IDA,OD脱壳等有时候再发

    注: 可以用ESP定律实现(有空会发

    IDA实现

    引入

    图解部分(不知道应该怎么叫)最上面可以看到上面有个pushad
    图2-2-1

    先调整IDA,把地址显示出来
    图2-2-2

    鼠标放到有效分析的最后一行
    按下space,切换视图模式
    图2-2-3
    敲黑板!补充一下

    图中的代码

    start	endp	;sp-analysis failed
    

    //分号后面的是注释,此处意为【分析失败】

    				;sub_456189↓p
    

    //此处注释意为【分析交叉引用有冲突】
    //一般是导航带上深红色区域(详见上图2-1)

    注:交叉引用简介

    定位到红色出错的CALLD,转变为数据(应该类似OD的删除分析。我猜的
    图2-2-4
    图2-2-5

    分析

    全部分析错误都没有了,
    开始人工分析
    图2-2-6
    (为了方便分析,请先按上面图2-2-2把地址显示出来这里就不上图了)

    以下机器码查询自 CSDN博客

    机器码汇编语言
    9ACALL immed32
    E8CALL immed16
    E9JMP immed16
    EBJMP immed8

    因为E8机器码在汇编中会被翻译为call,但是后面的EB OC 00 00会被翻译成call的地址,但是这个地址并不存在,因此会报错。
    那么就很清楚了,这里不是call而是jmp到一个地址
    光标定位到下一行EB,按C,将数据转换为代码
    图2-2-7
    图2-2-8

    至此,一处花搞定
    那什么叫做花指令呢
    就是在本来正常的顺序下,让其不停跳转,中间一些永远不会执行到的地方,加上一些其他字符,使反编译器无法正常分析,就达到了在一定程度上保护程序的功效

    这个截图上,除了这一处,还有一处,如下图
    图2-2-9

    E8 F6 FF FF FF   call   near ptr byte_4560FF
    

    这个near ptr byte_4560FF也是不知其为何物
    分析一下,发现这个一整段都是花,没有意义
    图2-2-10

    花指令

    一堆花加在一起,是为花指令
    这个例子中,有以下几种情形(分析出来类型,方便接下来用脚本去除所有的花指令)
    本来想用Md的Flowchart流程图写一下大概流程的。。
    试了几次,放弃了
    反正asm汇编的代码也算是很好懂的。

    情形一

    	call label1
    	db 0E8h
    label2:
    	jmp label3
    	db 0
    	db 0
    	db 0E8h
    	db 0F6h
    	db 0FFh
    	db OFFh
    	db OFFh
    label1: 
    	:call label2
    label3:
    	add esp,8
    

    情形二

    	jz label1
    	jnz label1
    	db 0EBh
    	db2
    label1:
    	jmp label2
    	db 81h
    label2:
    

    情形三

    	push eax
    	call label1
    	db 29h
    	db 5Ah
    label1:
    	POP eax
    	imul eax,3
    	call label2
    	db 29h
    	db5Ah
    label2:
    	add esp,4
    	pop eax
    

    情形四

    	jmp label1
    	db 68h
    label1: 
    	jmp label2
    	db 0CDh,20h
    label2:
    	jmp label3
    	db 0E8h
    label3:
    

    脚本去除

    下次再说。先编辑到这里。

    • 回头会补链的。

    吾爱破解论坛: IDA学习经验和实战记录–手过花指令(2)(已重排版)
    CSDN: IDA学习经验和实战记录–手过花指令(2)(推荐。)。

    展开全文
  • Vue自定义指令写法

    千次阅读 2018-06-01 11:05:58
    原文作者: Sarah Drasner原文链接: The Power of Custom Directives in Vue当你最初... 尽管如此, 我们都有一个经验: 框架不是万能的, 不可能全面覆盖各种各样的情况.令人兴奋的是, Vue的功能令人难以置信的丰富. ...
    原文作者: 
    Sarah Drasner
    
    原文链接:  The Power of Custom Directives in Vue

    当你最初学习JavaScript框架的时候, 有点像一个小孩在一个糖果商店里面. 你接受一切对于你来说可用的东西, 它会让我们的开发变得更简单. 尽管如此, 我们都有一个经验: 框架不是万能的, 不可能全面覆盖各种各样的情况.

    令人兴奋的是, Vue的功能令人难以置信的丰富. 尽管有可能有些特殊情况没有被Vue框架本身所覆盖, 但是你可以非常快速轻松的创建自定义指令.

    什么是指令?

    我曾经在我的Vue.js入门里面写过一篇关于指令的文章, 现在不妨让我们回顾一下:

    指令只一种可以附加到DOM元素的微命令(tiny commands). 它们通常以"v-"作为前缀, 以方便Vue知道你在使用一种特殊的标记, 从而确保语法的一致性. 如果你需要对HTML元素的低级别(low-level)访问来控制一些行为, 它们通常很有用.

    如果你正在使用Vue(或者Angular), 你可能已经很熟悉其中的一些指令, 如: v-if, v-else等等. 我们将从了解一些基础开始, 但是如果你更愿意直接看例子, 请直接往下滚动. 这些例子也能很好的让你理解这些概念.

    以下是一些指令的使用方法, 以及对应的例子片段. 这些例子不是规定性的, 它们只是一些用例. 这里的"例子"实际上是"指令".

    v-example: 这将实例化一个指令, 但不接受任何参数. 虽然不带参数的指令, 在使用的过程中并不是很灵活, 但是你仍然可以通过这种类型的指令对DOM元素做一些操作.

    v-example="value": 这将传递一个值给指令, 并且该指令根据该值计算出要做的操作.

    <div v-if="stateExample">I will show up if stateExample is true</div>
    

    v-example="'string'": 这将让你把'string'作为一个表达式.

    <p v-html="'<strong>this is an example of a string in some text</strong>'"></p>
    

    v-example:arg="value": 这允许我们传入一个参数给指令. 下面的例子中, 我们绑定到一个类, 将其样式化为一个对象, 单独存储.

    <div v-bind:class="someClassObject"></div>
    

    v-example:arg.modifier="value": 这允许我们使用修饰语. 下面的例子中, 允许我们在点击事件时, 调用preventDefault().

    <button v-on:submit.prevent="onSubmit"></button>
    

    领悟自定义指令

    既然我们已经大致过了一遍所有的我们所用过的指令类型方法, 让我们想一想我们如何通过自己编写的自定义指令来实现它们? 使用自定义指令的一个很好的例子是滚动事件, 让我们看看如何实现它.

    首先, 最基本的是如何创建一个全局的指令. (是的, 它什么也不做.) 仅仅是创建了一个指令.

    Vue.directive('tack');
    

    HTML:

    <p v-tack>This element has a directive on it</p>
    

    我们有几个可用的钩子, 每个钩子可以选择一些参数. 钩子如下:

    • bind: 一旦指令附加到元素时触发
    • inserted: 一旦元素被添加到父元素时触发
    • update: 每当元素本身更新(但是子元素还未更新)时触发
    • componentUpdate: 每单组件和子组件被更新时触发
    • unbind: 一旦指令被移除时触发

    就个人而言,  bind update 也许是这五个里面最有用的两个钩子了.

    每个钩子都有elbinding, 和vnode参数可用. updatecomponentUpdated钩子还暴露了oldVnode, 以区分传递的旧值和较新的值.

    el, 跟你所期待的一样, 就是所绑定的元素. binding是一个保护传入钩子的参数的对象. 有很多可用的参数, 包括namevalueoldValueexpressionargumentsarg及修饰语. vnode有一个更不寻常的用例, 它可用于你需要直接引用到虚拟DOM中的节点. binding和vnode都应该被视为只读.


    绑定一个自定义指令

    既然我们已经知道了这一点, 就可以开始研究如何在实际中使用一个自定义指令. 让我们完善刚才所创建的第一个指令, 让它变得有用:

    Vue.directive('tack', {
        bind(el, binding, vnode) {
            el.style.position = 'fixed'
        }
    });
    

    在HTML元素中:

    <p v-tack>I will now be tacked onto the page</p>
    

    毫无疑问, 它完全可以按照我们所希望的工作. 但是它还不够灵活, 如果我们可以传入一个值, 然后直接更新或者重用这个指令就好了. 例如, 我们想为这个元素指定一个值, 表示这个元素离顶部多远(多少个像素), 我们可以这样写(在CODEPEN上查看):


    // JS
    Vue.directive('tack', {
        bind(el, binding, vnode){
            el.style.position = 'fixed';
            el.style.top = binding.value + 'px';
        }
    });
    
    // HTML
    <div id="app">
        <p>Scroll down the page</p>
        <p v-tack="70">Stick me 70px from the top of the page</p>
    </div>
    

    假设我们想要区分从顶部或者左侧偏移70px, 我们可以通过传递一个参数来做到这一点(在CODEPEN上查看):


    // JS
    Vue.directive('tack', {
        bind(el, binding, vnode) {
            el.style.position = 'fixed';
            const s = (binding.arg === 'left' ? 'left' : 'top');
            el.style[s] = binding.value + 'px';
        }
    });
    
    // HTML
    <p v-tack:left="70">I'll now be offset from the left instead of the top</p>
    

    当然, 你可以同时传入不止一个值. 你可以像使用标准指令一样简单的使用自定义指令(在CODEPEN上查看):


    // JS
    Vue.directive('tack', {
        bind(el, binding, vnode) {
            el.style.position = 'fixed';
            el.style.top = binding.value.top + 'px';
            el.style.left = binding.value.left + 'px';
        }
    });
    
    // HTML
    <p v-tack="{top: '40', left: '100'}">Stick me 40px from the top of the page and 100px from the left of the page</p>
    

    基于我们的自定义指令, 我们可以创建和修改方法, 从而创建更为复杂的自定义指令. 这里, 我们将做一个waypoints-like例子, 用少量的代码实现特定滚动事件触发的动画效果(在CODEPEN上查看):

    // JS
    Vue.directive('scroll', {
        inserted: function(el, binding) {
            let f = function(evt) {
                if(binding.value(evt, el)) {
                    window.removeEventListener('scroll', f);
                }
            };
            window.addEventListener('scroll', f);
        }
    });
    
    // main app
    new Vue({
        el: "#app",
        methods: {
            handleScroll: function(evt, el) {
                if(window.scrollY > 50) {
                    TweenMax.to(el, 1.5, {
                        y: -10,
                        opacity: 1,
                        ease: Sine.easeOut
                    });
                }
                
                return window.scrollY > 100;
            }
        }
    });
    
    // HTML
    <div class="box" v-scroll="handleScroll">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A atque amet harum aut ab veritatis earum porro praesentium ut corporis. Quasi provident dolorem officia iure fugiat, eius mollitia sequi quisquam.</p>
    </div>
    

    为了让大家看得更清楚, 在这个代码片段中, 我们尽可能的保证它的简单易读. 在实际的APP中, 你可以构建非常友好的, 并且非常灵活的, 适合整个团队使用的自定义指令.

    在实际的构建中, 我会将指令代码放在"main.js"文件中, 该文件位于"src"目录的根目录下(如果你使用的是Vue-cli构建工具), 那么"App.vue"以及组件目录中的所有的.vue文件都可以访问它. 当然, 还要其他方法可以使用它, 但是我发现对于整个应用程序来说, 这是最灵活的实现方式.

    展开全文
  • 计算机体系结构.指令集架构

    千次阅读 多人点赞 2019-06-08 22:28:19
    计算机体系结构.指令集架构 微结构与ISA 微结构(Microarchitecture)对应的是底层硬件如何实现...而到底有哪些指令可供使用指令是什么格式、哪些通用寄存器可以,以及这些指令在程序员看来是要如何执行的,...

    计算机体系结构.指令集架构

    微结构与ISA

    微结构(Microarchitecture)对应的是底层硬件如何实现指令执行的,那么指令集架构(Instruction Set Architecture)对应的是程序员所看到的程序的模样。

    具体指令是如何被处理器一步一步完成执行任务的,这交给了微结构。而到底有哪些指令可供使用、指令是什么格式、哪些通用寄存器可以用,以及这些指令在程序员看来是要如何执行的,就是ISA的范畴了。

    因此程序员在某个ISA上写的程序,这个程序的每一步执行了什么操作,最终结果如何,程序员是知道的。而程序员不知道的是,每一步到底是如何被处理器完成的。

    比如一个加法操作“add A,B,C”,在程序员的视角看来,就是将寄存器A和B里的数相加的结果存放在寄存器C中,之后程序员就可以把寄存器C作为A和B相加的结果来继续使用。

    而在微结构的视角(假设为乱序执行),则是处理器读取到了一条指令,通过译码逻辑得知这是一条加法指令,这条指令需要寄存器A和B里的数据作为输入,因此要检查有没有正在执行的指令要写入寄存器A和B(即寻找寄存器A和B的重命名寄存器),并为其结果寄存器C进行寄存器重命名,同时在重排序缓存(ROB)中为该指令申请一个位置,然后送入指令队列(即保留站),并不断检查寄存器A和B里的数据是否可用,该指令会等待直到源数据可用,且加法运算单元空闲时,则该指令的操作码以及寄存器A和B的数据(或来自寄存器堆,或来自旁路,或来自尚未退休指令的ROB项)会送入加法运算单元,当加法运算单元完成后将结果通过总线写回到该指令对应的ROB项中,并修改该项的状态为已完成,退休(retire)逻辑每拍检查若干ROB的项,按照程序顺序完成指令的执行,即将其结果写回寄存器堆,并回收ROB项和重命名寄存器。

    • 若有指令在退休时被发现有例外,则要冲刷流水线,进入例外处理。
    • 若运行期间来了中断,则需要保存现场去处理中断。
    • 若在此之前有一个读操作读取数据到A(或B)且未命中缓存,则该指令需要一直等待,而该指令之后的指令由于乱序可能先于这个加法操作完成执行。
    • 若该指令运行在错误的分支预测路径上,则分支结果出来后该指令会被取消掉。

    不同的微结构下,如何完成这条指令的执行,通常是不一样的。但程序员并不需要知道内部是如何完成的,只需要知道这条指令可以将寄存器A和B的数据相加并存入寄存器C就可以了。这就是ISA了。

    ISA到底是什么

    微结构负责实现每条指令是如何完成执行任务的,而ISA则可以描述指令序模型(instruction sequencing model),有两种指令序模型:

    • 基于顺序的控制流(sequential control-flow)的指令序,对应经典的冯诺伊曼架构。控制流架构下有单一的程序计数器(PC),其决定了指令的获取、执行和提交的顺序。此时的指令是在PC的指挥下一条一条顺序执行的。目前大多数ISA都是基于控制流的。
    • 基于数据流(data-flow execution)的指令序,对应数据流架构(Dataflow Architecture)。其在逻辑上没有PC的存在,指令的执行并不是按照程序所写明的顺序,而是按照数据依赖关系。
      • 虽然学术上有不少对数据流架构的讨论,但是商业上并没有纯粹数据流架构的通用处理器,不过在数字信号处理、网络路由、数据仓库等领域则有【1】。
      • 从某种意义上来说,处理器核内部的乱序执行结构也是一种数据流架构,此时指令只要满足了数据依赖,就可以送去执行了,这恰恰打乱了顺序的指令流【2】。

    ISA涵盖的内容,包括但不限于以下几点:

    • 指令格式:定长或变长;每个位的含义(操作码,寄存器编号,立即数等);操作数的个数;
    • 寻址访存:寻址范围(地址空间);寻址模式;寻址粒度(单比特/字节/64比特等);访存方式(如load/store结构,专门的IO指令);地址对齐;
    • 数据类型:8/16/32/64位整数,浮点;有/无符号;复杂数据类型(BCD码、字符串、链表);
    • 寄存器:通用寄存器数量以及每个寄存器含义、宽度;整数、浮点、向量寄存器;大小端;特殊用途寄存器(如标志寄存器、架构相关的寄存器如MIPS的协处理器寄存器);

    通常ISA都会包含以下三类指令:

    • 运算指令:算术运算(加减乘除),逻辑运算(与或非),移位运算,向量运算等;
    • 分支指令:条件分支指令,非条件分支指令(如函数调用、无条件跳转)等;
    • 访存指令:load/store结构;寻址模式(寄存器寻址、基址寻址等);IO指令等;

    此外还有:

    • 架构相关指令:原子操作(如ll/sc);内存栅栏;缓存相关的指令;TLB相关的指令;等
    • 复杂操作指令:FFT、三角函数、平方根;等
    • 其他特殊用途:虚拟化指令;例外和中断(有哪些例外,是否是精确例外);核心态/用户态;访存权限检查、禁止运行位等安全方面;非对齐访存;功耗管理;延迟槽;特殊寄存器的访问;等

    最后说一句,在汇编层面还有一些“伪指令”,其只对汇编器有用,不会被翻译成机器码。MIPS中的“.set“指令会影响汇编器如何将汇编翻译成机器码:“.set mips16”使汇编器进入MIPS 16模式;“.set mips3”则告诉汇编器下面的指令是MIPS IV(64位指令集,兼容32位指令)中的指令【3】。还有一些“伪指令”,只有汇编器认识,CPU不认识,在编译的时候会被汇编器翻译成 CPU 认识的汇编指令,完成相应的功能,如“li”指令通常会被翻译成“lui”和“ori”。

    CISC 和 RISC

    Complex Instruction Set Computer,即CISC,复杂指令集计算机。
    Reduced Instruction Set Computer,即RISC,精简指令集计算机。

    笼统的对比一下CISC和RISC,不完全正确,但能反应其本质上的差别:

    对比CISC(x86)RISC(ARM,MIPS,etc)
    访存模式多种寻址模式load/store
    指令宽度变长定长
    操作数来源内存或寄存器寄存器
    IO通信专用的IO指令和IO地址空间内存映射
    访存对齐不需要需要
    数据类型多而复杂少而简洁
    寄存器堆相对更小相对更大
    设计原则功能多样的复杂指令集功能完备的精简指令集

    可见RISC更加简洁,因此单从架构优势上来说,普遍认为RISC更优于CISC:

    • RISC的定长指令宽度以及相对规整的指令格式,简化了译码逻辑,也使得指令之间相关性的判断也更容易,比较容易实现多发射结构,此外也能节省面积、降低功耗
    • RISC只有简单的数据类型,同样可以简化硬件的实现
    • RISC的load/store访存模式,简化了指令相关性的判断,简化了访存操作的处理,也使得其他指令只能操作寄存器,从而可以更快地执行完成
    • RISC可以用更简单的逻辑实现,比如译码结构,节省下来的面积可以使得寄存器堆更大,从而容纳更多的指令进行乱序执行,提高性能。同时更多的寄存器也可以降低编译器的复杂性,使优化工作更容易进行
    • RISC的每条指令只执行很简单的操作,大多可以在一拍内完成,因此主频可以做到很高,流水线的吞吐量可以接近每拍完成1条指令(多发射则更多)

    总的来说,由于RISC更加简单化,因此微结构的实现可以更加高效,指令的执行效率更容易通过流水线、多发射、乱序执行等技术来提高。对于CISC所拥有的复杂指令,比如FFT,RISC则是通过软件来实现。这种复杂指令的使用场景也非常少,因此RISC也符合“常用的做得快,少用的只要对”的原则【4】。

    自从1985年以后,所有的ISA都是RISC结构。如今唯一的CISC就是x86指令集,而实际上其微结构的实现也融合了RISC的优点。

    部分指令集简述

    x86指令集

    x86指令集在个人电脑的市场占有率上毫无疑问是王者,其创立者为Intel。可以说x86指令集是目前世界上最流行的指令集了,也被认为是现存唯一的CISC指令集。

    Intel主导下的x86架构,并不一直是处理器架构做得最好的,历史上出现过的Alpha等RISC处理器其架构设计就比同时代的x86更优,1976年乔布斯和沃兹尼亚克推出的使用8位6502处理器的Apple II计算机也击败过x86架构【5】。但x86的兼容性(Compatibility)做得最好,其他如Alpha过于追求更先进的技术,甚至Alpha指令集代与代之间完全不兼容,从而淡出了市场,而x86的兼容性,使得即使在如今64位时代下,其仍能运行16位乃至8位的程序。显然如果客户每次升级处理器,都需要重写一遍程序的话,那绝对是受不了的。

    而在兼容性之外,还有Intel和AMD本身的实力,足以下很多功夫在其他方面(工艺、架构)上来提高性能,以弥补架构上的差距。同时,x86架构也逐渐吸取了RISC架构的优势,在处理器内部,通过复杂的译码逻辑,将变长的复杂指令转换成定长的、简洁的微码,随后再流水执行。这样带来的缺点就是x86的译码逻辑相对于纯正的RISC来说要复杂很多,但这也许并不全是坏处。

    说起指令集兼容性的重要性,有一件事十分典型,即x86从32位发展到64位时。首先是Intel与惠普联合推出了IA-64指令集,但其与32位的x86不兼容,因此难以推广。随后AMD推出了x86-64架构,是在32位的基础上增加了64位扩展,很快占据了市场。之后IA-64彻底失败,Intel也接纳了x86-64作为x86架构在64位时代的版本。

    x86架构处理器的两大厂商,即Intel和AMD,只是提供处理器,并不生产整机。因此Intel和AMD都与IBM达成了合作,搭上了IBM这班飞速发展的快车。此外微软的操作系统也是长期支持x86架构。总的来看,x86处理器芯片有Intel和AMD,电脑整机有IBM,操作系统有微软,在这几大厂商的联合下,使得x86指令集架构占据了绝大部分的个人电脑市场。其他整机厂商,如1984年成立的DELL所推出的第一台计算机Turbo PC也是基于Intel 8088处理器【6】。

    此外让人津津乐道的,也有AMD和Intel之间的竞争。进入20世纪后,更明确说是2006年之后,Intel几乎是压制AMD,后者也不得不在价格和性能上妥协来避免直接竞争。但在20世纪前,AMD不见得比Intel差到哪去,相反在x86最初的二十年里,AMD的实力丝毫不输于Intel,甚至更强。而AMD之所以落后则是有多方面原因,包括领导的不力、方向性的错误、Intel的不正当竞争【7】。最近几年随着锐龙架构的兴起,AMD也逐渐跟上了Intel的脚步,而Intel则饱受工艺研发的痛苦,被困在14nm工艺长达5年之久,不断滞后了先前承诺的10nm计划。

    关于x86指令集的更详细内容,可以移步Intel和AMD提供的开发手册了。【8】【9】

    ARM

    ARM,即Advanced RISC Machine,或更早些时候的Acorn RISC Machine,是一系列RISC架构处理器。如果说x86统治了个人电脑(Personal Computer,即PC)市场,那么ARM则是统治了移动设备市场,主要是手机、平板以及嵌入式系统。这得益于RISC架构的优势,其简洁性可以很容易的实现低功耗需求,降低设计难度和散热性要求,同时具备良好的扩展性可以满足众多需求。

    英国计算机公司Acorn Computers于1978年在剑桥成立,其在1980s推出了Acorn RISC Machine architecture,用于自家的PC。Acorn的第一款基于ARM的产品是一种协处理器模块,用于BBC Micro系列计算机,而BBC系列计算机也用于开发用于芯片设计的仿真软件,以及用于ARM2开发的CAD工具。

    在1980s末期,Apple Computer公司和VLSI Technology公司开始和ARM合作开发新的架构。1990年Acorn将芯片设计团队独立出去,成立了Advanced RISC Machines Ltd,其母公司则为ARM Holdings,与Apple和VLSI共同开发处理器核。在1992年推出了ARM6架构,而Apple使用了基于ARM6的ARM610作为Apple Newton PDA的基础。Acorn在破产前一直在销售基于ARM的PC,而ARM Holdings则在销售芯片架构设计【10】。

    ARM并不生产芯片,而是出售芯片设计,供其他厂商使用。ARM架构的授权方式主要有两类:核心级授权和架构级授权【11】:

    • 前者只提供处理器核,可以和其他模块组合在一起形成可用的芯片。该授权下主要有两种级别,一种是提供门级网表(gate netlist)以及一些仿真模型和测试程序,因此无法修改核心架构,使用这种授权模式的有三星的Hummingbird和Exyno、苹果的A4、A5和A5X等。另外一种是提供HDL级的处理器核架构,此时相当于有了源代码,厂家可以自行修改,进行个性化开发,使用这种授权模式的有苹果、高通、华为、三星、博通、Xilinx等等。
    • 后者则是指令集授权,可以使用ARM的ISA,内核可以自行设计,但仍需服从ARM架构。使用这种授权模式的有高通、苹果等。

    MIPS、Alpha、Power、SPARC

    比较知名的RISC,除了ARM外,简单介绍一下四种:【12】

    • MIPS(Microprocessor without Interlocked Piped Stages Architecture)是一种十分简洁的RISC架构,其出身可谓是名门之家,由斯坦福大学的Hennessy教授领导的研究小组研制开发。由于MIPS是经典的RISC架构,且广泛用于体系结构领域的教学上,如Patterson和Hennessy的系列著作《计算机体系结构·量化研究方法》就主要以MIPS为例。如今除了ARM外,再说其RISC基本上就是MIPS了。我国的龙芯也是基于MIPS指令集,拓展了自己的指令后形成了LoongISA。
    • Power是IBM开发的RISC指令集。IBM于1980年推出了全球第一台基于RISC的原型机,而1980年也是IBM在PC市场上称霸的起步时期,但IBM却选择了RISC用于高性能领域,其成功也证明了RISC比CISC在高性能上更具优势。Power架构在超算、金融等高端服务器领域表现十分成功,至今IBM仍在迭代发展Power架构。
    • Alpha是一种64位的RISC指令集架构,由DEC公司设计开发,被用于DEC自己的工作站和服务器中。Alpha是一款优秀的处理器,它不仅是最早跨过GHz的企业级处理器,而且还是最早计划采用双核,甚至是多核架构的处理器。2001年,康柏收购DEC之后,逐步将其全部64位服务器系列产品转移到Intel的安腾处理器架构之上。2004年,惠普收购康柏,从此Alpha架构淡出了人们的视野。
    • SPARC(Scalable Processor ARChitecture),是由Sun公司在1985年设计的指令集架构,是一种非常有代表性的高性能RISC架构。Oracle收购Sun公司之后,SPARC架构归Oracle所有。2017年9月,Oracle公司宣布正式放弃硬件业务,也包括了收购自Sun的SPARC处理器。

    RISC-V

    RISC-V是一个开源的指令集架构,遵循RISC的设计原则,即力求简洁性,同时保持开放性。这个开源项目于2010年起源于伯克利,随后一直发展至今。

    RISC-V最大的意义在于其开源性。现有的ISA基本上都十分昂贵,如ARM的授权。此外,设计CPU也是一个很复杂、很费钱的工作,不仅需要有经验的架构设计人员,还需要不断的经历仿真、验证、流片测试,而这则是普通公司难以承受的。

    RISC-V自诞生之日起就是为了解决这些问题,提供一个开源的、广泛应用的、经过验证的指令集。经过若干年的开发,RISC-V具备了完整的软件工具链,以及若干开源的处理器架构设计。2016年,RISC-V基金会成立,作为一个非盈利组织,负责维护RISC-V指令集手册和架构文档,并推动RISC-V持续发展。许多著名科技公司,如谷歌、惠普、Oracle、西部数据等,都是RISC-V基金会的创始会员,越来越多的芯片公司也开始使用或计划使用RISC-V架构。此外,许多体系结构领域的教材,如Patterson和Hennessy的系列著作《计算机体系结构·量化研究方法》,其作者本身也大力支持RISC-V架构,因此后续越来越多的教材也将以RISC-V为例。而随着物联网时代的加速到来,有一个统一的、通用的、开源的指令集架构是很有意义的。【13】

    然而RISC-V的野心太大,无论是PC的王者Intel,还是移动设备的霸主ARM,都不会任由其发展下去。目前的形势下,正在兴起的物联网、AI则是RISC-V主要的发展方向【14】。

    如何设计指令集

    胡老师的书中提出了四点指令集设计原则【4】:

    • 兼容性:指令集架构更新不能扔掉历史包袱,而设计的时候也要为未来留出空间。
    • 通用性:功能上要完备,能够支持各种软件,如网络应用、科学计算、操作系统等等。
    • 高效性:即简洁、规整,便于CPU的优化、编译器的实现。
    • 安全性:满足安全需求。

    只有这四点是不够的,或者说这四点只是针对通用处理器的指令集设计而言。

    而在设计一个专用处理器的ISA的时候,常常在各方面都会面临多种选择,最重要的是清楚不同设计下的优势和劣势,根据实际的需求选择设计方案。尽管真正从零开始设计一个ISA的机会并不多,但通过这种分析可以对指令集架构有更好的了解。此外目前 RISC-V架构 的发展提供了更多接触指令集设计的机会。从2014年逐渐发展起来的深度学习处理器,也出现了许多面向深度学习处理的指令集架构。

    • 运算类型:即指令集实现的功能。复杂指令越多,其单条指令能完成的功能越多,因此可以减少程序的存储空间,提高内存利用率,编译器的实现更简单,但也降低了编译优化的空间。此外复杂指令需要更复杂的硬件逻辑支持,包括译码逻辑、功能单元等。
    • 语义鸿沟:即可读性。指令集越复杂,提供的指令种类越多,其可读性越好,而越精简的指令集,其许多功能需要软件实现,可读性就更差。
    • 指令格式:变长的指令格式可以减少程序本身所需的存储空间,但会增加译码的复杂度;定长的指令格式常常需要更大的空间存储指令,但其译码更加简单,不仅更容易译码单条指令,而且更容易实现同时译码多条指令,支持更多指令同时发射。定长的指令常常也有更加统一的指令格式,如最高若干位通常表示操作码,这才是降低译码复杂度的主要原因。
    • 寄存器堆:寄存器堆越大,实现的复杂度就越高,对芯片设计的要求也更高,需要处理访问时间、功耗、面积等各方面的问题。但越大的寄存器堆可以支持更多的指令在流水线中,提供更多的乱序空间,同时降低了编译优化的难度。此外越大的寄存器堆,就需要在指令中占据更多的位来对寄存器编码。
    • 寻址模式:寻址模式越多,对编程越友好,可以增加可读性,但会加大芯片设计的难度,也会影响编译器的实现。
    • 其他方面:如何处理例外和中断;是否需要/如何保证精确例外;是否需要虚拟内存;是否需要对齐访存;是否需要向量部件;需要支持哪些数据类型;使用什么存储模型;等等

    参考资料

    [1] WiKiPedia.Dataflow architecture[EB/OL].(2019-03-05)[2019-05-04].https://en.wikipedia.org/wiki/Dataflow_architecture

    [2] Onur Mutlu.Dataflow[EB/OL].(2013-10-31)[2019-05-04].https://www.archive.ece.cmu.edu/~ece740/f13/lib/exe/fetch.php?media=onur-740-fall13-module5.2.1-dataflow-part1.pdf

    [3] adaptiver.set伪指令(mips)[EB/OL].[2019-05-04].https://blog.csdn.net/adaptiver/article/details/6760220

    [4] 胡伟武.计算机体系结构(第2版)[M].清华大学出版社:北京,2017:55-71.

    [5] Gary Anthes.Timeline: A brief history of the x86 microprocessor[EB/OL].(2008-06-05)[2019-05-05].https://www.computerworld.com/article/2535019/timeline–a-brief-history-of-the-x86-microprocessor.html

    [6] Smithsonian.PC’S Limited Microcomputer[EB/OL].[2019-05-05].https://americanhistory.si.edu/collections/search/object/nmah_1321866

    [7] Graham Singer.The Rise and Fall of AMD[EB/OL].(2012-11-21)[2019-05-07].https://www.techspot.com/article/599-amd-rise-and-fall/page1.html

    [8] Intel.Intel® 64 and IA-32 Architectures Software Developer Manuals[EB/OL].[2019-05-07].https://software.intel.com/en-us/articles/intel-sdm#combined

    [9] AMD.Developer Guides, Manuals & ISA Documents[EB/OL].[2019-05-07].https://developer.amd.com/resources/developer-guides-manuals/

    [10] David Chisnall.Understanding ARM Architectures[EB/OL].(2010-8-23)[2019-05-07].https://www.informit.com/articles/article.aspx?p=1620207

    [11] WiKiPedia.ARM architecture[EB/OL].(2019-03-03)[2019-05-07].https://en.wikipedia.org/wiki/ARM_architecture#History

    [12] 胡振波.ISA众生相[EB/OL].(2018-05-23)[2019-05-07].http://book.51cto.com/art/201805/574072.htm

    [13] 胡振波.RISC-V架构与嵌入式开发快速入门[M].人民邮电出版社:北京,2019:19-23.

    [14] 半导体行业观察.RISC-V未来将面临怎样的挑战?[EB/OL].(2019-03-10)[2019-05-07].https://www.chainnews.com/articles/711647751312.htm

    展开全文
  • 方框图来表示指令周期

    千次阅读 2017-12-10 23:54:17
    参考资料:《计算机组成原理》(第五版) 白中英等著 ...总之,计算机组成原理侧重于原理,只有计算机自己清楚指令各个环节所需的时间,所以方框图能够基本上表示出清晰的流程即可。
  • MIPS指令特点

    2019-09-26 09:12:54
    因此要想加载任何一个32位值,就得两个加载指令。16位的目标地址意味着,指令的跳转或子函数的位置必须在64K以内(上下32K); 3、所有的动作原理上要求必须在1个时钟周期内完成,一个动作一个阶段; 4、有32个...
  • OLED指令整理

    千次阅读 2020-02-16 10:56:00
    ——此为自己对OLED使用的整理 对于OLED使用经验总结: 本此次使用开发板为正点原子的stm32精英板(芯片为stm32f103zet6) 此次使用的是中景园0.96寸的OLED显示屏,采取的是七线SPI模式进行程序抒写 在写程序前,...
  • 常用搜索指令

    2019-05-07 17:30:00
    常用搜索指令 一、总结 一句话总结: 内容过滤:加号和减号:李晨 -范冰冰 域名过滤:site:intitle:视频压缩 site:zhihu.com 文档类型过滤:filetype:阿里巴巴财报 filetype:pdf 标题包含:intitle:武侠...
  • 操作符 操作符分为四大类,算数操作符、关系操作符、数值回送操作符和属性操作符。 注:这里指的是[sp+8]这样的加法,而不是我们的add指令。 算数操作符 ...(其实标志位都不需要你看,直接使用对应的跳
  • IDA学习经验和实战记录--手过花指令(2)

    千次阅读 多人点赞 2019-01-05 14:55:02
    IDA学习经验和实战记录--手过花指令(2)上一节(接着上一次自学)声明附上一次链接分析原理花指令的干扰去掉花指令原理如何识别垃圾数据如何修改程序数据认识IDC什么是IDC第一次使用IDC(大佬请略过)修改使用IDC修改...
  • 使用最精炼的语言,记录我遇到的所有常用或不常用或极其重要的汇编指令及其注意事项,以方便自己和读者进行查阅,如有错误敬请指证。 Part 1 积少成多,持续更新。(这将会是一个极其漫长的过程) 表格中各条指令的...
  • 在我的世界这个自由的...1.召唤命名实体我的世界玩家都知道,我们可以使用指令召唤一些实体,那么召唤它们主要是为了帮助我们做实验,或者是想要刷经验但是没有刷怪笼,所以只能将它们召唤出来。也有可能是为了它们...
  • AngularJS期间, 经常用到ng-repeat, 业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写。有经验的同学都应该...
  • 本系列博客学习由非官方人员 半颗心脏 ... 2、利用GPIO开始使用按钮点亮你的“第一盏灯”。 3、利用 "软件定时器 " 定时0.5秒闪烁点亮一盏LED。 4 、了解PWM,更为深入地PWM控制一盏LED的亮度变化。 5 、原生乐鑫...
  • Vue里如何注册全局自定义指令

    千次阅读 2020-09-25 17:04:16
    Vue里如何注册全局自定义指令? 根据Vue官网出的注册自定义聚焦示例,... /* 1、自定义全局自动聚焦 这个是官网出的 vue.directive('focus', { inserted: function (el) { el.focus() } }) */ /*2自定义
  • mips指令

    千次阅读 2015-06-24 13:00:40
    因此要想加载任何一个32位值,就得两个加载指令。16位的目标地址意味着,指令的跳转或子函数的位置必须在64K以内(上下32K); 3、所有的动作原理上要求必须在1个时钟周期内完成,一个动作一个阶段; 4、有32个...
  • anaconda显示conda无指令,修改了环境变量,也添加了conda.exe 总结一下经验 电脑小白,跟着csdn上很多大佬的贴子修改了很多,最后成功了,总结一下经验吧,尽量避免大家到处尝试。 方法一:修改环境变量 环境变量的...
  • 立即寻址:就是在让你做事的时候,同时把你要的东西也你,也是不用你忙活着去找。 直接寻址:就是告诉你储物柜的号码,你自己去该储物柜里把东西拿出来。 寄存器寻址:就是有几个固定的门房收发室,你找门房...
  • 东信社保卡读卡器医保卡读卡器底层指令通讯协议,本协议适用有底层开发经验的技术人员使用,支持单片机、Linux、ARM等嵌入式系统使用。 支持的产品型号有:东信EST-100身份证社保卡读卡器、东信EST-100R二维码终端...
  • 指令文档网上较少,这里引用一个链接吧 TSC条码打印机指令TSPL手册,各个厂商可能基于此指令有少量diy,具体可以查看自己打印机对应厂商的文档。 打印 请详细阅读指令手册,具体打印步骤,以打印图片为例: SIZE ...
  • 文章目录RISC 与 CISCMIPS 指令类型R Type(Register)I Type(Immediate)J Type(Jump)指令集表 RISC 与 CISC RISC(Reduced Instruction Set Computer,精简指令集计算机) 优点 :每条指令集非常简单,执行...
  • 首先根据华科出的数据通路连接自己的数据通路 这里的取地址很有讲究 因为MIPS架构是32位,四字节,而我们做的CPU是字编址,最后两位不用,存储器的容量是,所以取2-11位。 总周期的数量可以位地址来...
  • 在计算机中,CPU只能识别0、1这两个数,甚至它都不知道数是什么,它只知道要么“是”,要么“不是”,恰好0、1来表示这两种状态而已。 人发明的东西逃不出人的思维,所以,先看看我们人类的语言是怎么回事。 ...
  • 实现了部分RV32I指令集中的部分指令类型,如下表 具体指令如下: 实现了单周期CPU和五级流水线。其中,五级流水线为顺序读取、顺序放回;跳转指令可以冲刷流水线;没有预测跳转功能;占用资源较多,微架构面积较大...
  • 为什么要硬件调度方案?因为有时候编译时无法确定相关。 基本思想:允许stall后的指令继续向前流动(这么说可能有点抽象,简单的理解就是若是你因为相关被stall了,就让你后面的没有被stall的指令先来,很现实的一...
  • mips指令与寄存器详解

    万次阅读 多人点赞 2015-03-28 21:21:36
    MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下: 下表描述32个通用寄存器的别名和用途 REGISTER NAME USAGE $0 $zero 常量0...
  • 自己写的反汇编总结
  • 我查了百度上面的资料,很少有关于这一方面的知识,都是靠自己不断搜索,然后尝试出来,也非常感谢网上的前辈们把一点点的疑问解答了。...所有这里宏指令自己写代码,将16进制转化为 10进制。这样显示在触摸屏上..

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,081
精华内容 36,032
关键字:

如何用指令给自己经验