单片机跳转指令解析
控制转移类指令
条件转移指令Jcc根据指定的条件确定程序是否发生转移。如果满足条件则程序转移到目标地址去执行程序不满足条件,则程序将顺序执行下一条指令。
其通用格式为:
Jcc LABEL 条件满足,发生转移:IP?IP+8位位移量
否则,顺序执行:IP?IP+2 其中,LABEL表示目标地址(8位位移量)。因为Jcc指令为2个字节,所以顺序执行就是指令偏移指针IP加2。条件转移指令跳转的目标地址只能用前面介绍的段内短距离跳转(短转移),即目标地址只能是在同一段内,且在当前IP地址-128~+127个单元的范围之内。这种寻址方式由于是相对于当前IP 的,所以被称为相对寻址方式。条件转移指令不影响标志,但要利用标志。条件转移指令Jcc中的cc表示利用标志判断的条件,共16种。如下图:
1、判断单个标志位状态
这组指令单独判断5个状态标志之一,根据某一个状态标志是0或1决定是否跳转。
(1)JZ/JE和JNZ/JNE利用零标志ZF,判断结果是否为零(或相等)
JE指令(相等时转移)
JZ指令(等于0时转移)
这是当ZF=1时转移到目标地址的条件转移指令的两种助记符。这条指令既适用于判断无符号数的相等,又适用于判断带符号数的相等。
JNE指令(不相等转移)
JNZ指令(不等于0转移)
这是当ZF=0时能转移到目标地址的条件转移指令的两种助记符。这条指令也是既适用于判断无符号数,又适用于判断带符号数。
(2)JS和JNS利用符号标志SF,判断结果是正是负。
JS指令(为负转移)——当满足SF=1时,转移到目标地址
JNS指令(为正转移)——满足SF=0时,转移到目标地址
(3)JO和JNO利用溢出标志,判断结果是否产生溢出
JO指令(溢出转移)——OF=1时,转移到目标地址 JNO指令(未溢出转移)——OF=0时,转移到目标地址
(4)JP/JPE和JNP/JPO利用奇偶标志PF,判断结果中“1”的个数是偶是奇
JP/JPE指令(为偶转移)——满足PF=1时转移 JNP/JPO指令(为奇转移)——满足PF=0时转移 数据通讯为了可靠常要进行校验。常用的校验方法是奇偶校验,即把字符ASCII码的最高位用作校验位,是包括校验位在内的字符中为“1”的个数恒为奇数(奇校验),或恒为偶数(偶校验)。若采用奇校验,在字符ASCII中为“1”的个数已为奇数时,则令其最高位为“0”否则令最高位为“1”。
(5)JC/JB/JNAE和JNC/JNB/JAE,利用进位标志CF,判断结果是否进位或借位,CF标志是比较常用的一个标志。 JC——满足CF=1时转移 JNC——满足CF=0时转移
JB(低于转移) JNB(不低于转移) JNAE(不高于等于转移) JAE(高于等于转移) 2、用于比较无符号数高低为区别有符号数的大小,无符号数的大小用高(Above)、低(Below)表示,它需要利用CF确定高低、利用ZF标志确定相等(Equal)。两数的高低分成4种关系:低于(不高于等于)、不低于(高于等于)、低于等于(不高于)、不低于等于(高于)也就分别对应4条指令:JB(JNAE)、 JNB(JAE)、JBE(JNA)、JNBE(JA)。 JA/JNBE
JA即高于转移,JNBE即不低于且不等于转移,高于则没有进位产生,即CF=0,不等于则ZF=0,所以这两条指令满足CF=0且ZF=0时转移
JAE/JNB
高于或等于转移/不低于转移是当CF=0(高于就不产生进位)或ZF=1(等于)时转移。
JB/JNAE
即低于/不高于且不等于转移,是当CF=1(产生借位)且ZF=0(不相等)时转移。
JBE/JNA
即低于或等于/不高于转移,是当CF=1(借位产生)或ZF=1(相等)时转移。
3、用于比较有符号数大小
判断有符号数的大(Greater)、小(Less),需要组合OF、SF标志、并利用ZF标志确定相等与否。两数的大小分成4种关系:小于(不大于等于)、不小于(大于或等于)、小于等于(不大于)、不小于等于(大于)也就分别对应4条指令:JL(JNGE)、JNL(JGE)、JLE(JNG)、 JNLE(JG)。
由上可见,条件转移指令之前常有CMP、TEST、加减运算、逻辑运算等影响标志的指令,利用这些指令执行后的标志或其组合状态形成条件。
JG/JNLE
大于/不小于且不等于转移,是当标志SF与OF同号(即SF异或OF=0)且ZF=0时转移
JGE/JNL大于或等于/不小于转移,是当标志SF与OF同号(即SF异或OF=0)或ZF=0时转移
JL/JNGL
小于/不大于也不等于时转移,是当标志SF与OF异号(即SF异或OF=1)且ZF=0时转移
JLE/LNG
小于或等于/不大于转移,是当标志SF与OF异号(即SF异或OF=1)或ZF=1时转移
4、判断计数器CX是否为0
JCXZ LABEL CX=0,则转移否则顺序执行
在上一章节中,我们了解了Vue中的常用指令,同样,在本章节中继续讲解Vue中常用的指令,并且这些指令是针对语句使用的
用于条件性的渲染一块内容,只有当条件的返回值为真时,才会渲染该块的内容,一般默认值是true
当设置ok为false时,div没有被渲染到浏览器中。
要注意的是,为变量赋值Boolean类型时,不能加引号,加了引号就是字符串类型,字符串类型永远都为真
如果v-if的条件不满足,将跳转到v-else-if,而当所有的v-else-if条件都不满足时,将会跳转到v-else。v-else-if、v-esle相当于v-if的一个分支
当为type赋值A或者B时,就会将A或者B的div渲染到浏览器中,当条件都不满足时,就会渲染最后一个div到浏览器中。
要注意的是,v-else 元素要跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
v-show指令也是用于根据条件显示元素的指令,不同的是 v-show不支持v-else和<template>元素 ,并且带有 v-show 的元素 始终会被渲染并保留在 DOM 中 ,只是简单地切换元素的 CSS 属性 display。
当one赋值为真时,div就会显示在浏览器中,当one赋值为false时,div就会隐藏在浏览器中。
4.1 渲染元素
① v-if :是 “真正 ”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
② v-show:不管初始条件是什么,元素总是会被渲染,并且只是 简单地基于 CSS 进行切换 。
4.2 渲染条件
① v-if :当条件结果为 假 时, 不对元素进行渲染 ,直到条件为 真 才将元素 渲染
② v-show: 不管初始条件是什么 ,都已经将 元素渲染 到浏览器中
4.3 运行条件
① v-if:更高的切换开销,适用在 运行时条件很少改变 的情况下
② v-show: 有更高的初始渲染开销。如果需要非常 频繁地切换 ,建议使用v-show
以上就是条件语句常用的四条指令:v-if,v-else-if,v-else,v-show
在Vue中,for语句使用 v-for 的指令来操作,具体的结构如下:
其中,site可以看做是某个特定的元素,而sites则是某个元素所在的集合,可以分成以下几类:
①通过对象的 属性 来迭代对象数据,其结构是: v-for =‘value in object’
② 通过 key-value 的方式迭代对象数据
使用过 AngularJS 的朋友应该最感兴趣的是它的指令。现今市场上的前端框架也只有AngularJS 拥有自定义指令的功能,并且AngularJS 是目前唯一提供Web应用可复用能力的框架。
目前有很多JavaScript. 产品提供插件给Web开发人员。例如, Bootstrap 就是当前比较流行的提供样式和JavaScript插件的前端开发工具包。但是开发人员在使用Booostrap中的插件时, 必须切换到JavaScript. 模式来写 jQuery 代码来激活插件虽然jQuery 代码写起来十分简单,但是必须和HTML进行同步,这是一个单调乏味且容易出错的过程。
AngularJS主页展示了一个简单的例子,用于实现Bootstrap中的 Tab功能,可以在页面中轻松添加 Tab 功能,并且使用方法和 ul 标签一样简单。HTML代码如下:
复制代码
BootStrap Tab Component
This is the content of the first tab.
This is the content of the second tab.
复制代码
JavaScript代码如下:
复制代码
angular.module('components', []).
directive('tabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: [ "$scope", function($scope) {
var panes = $scope.panes = []
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false
})
pane.selected = true
}
this.addPane = function(pane) {
if (panes.length == 0) $scope.select(pane)
panes.push(pane)
}
}],
template:
'
' +
'
' +
'
'+
'{{pane.title}}' +
'
' +
'
' +
'
' +
'
',
replace: true
}
}).
directive('pane', function() {
return {
require: '^tabs',
restrict: 'E',
transclude: true,
scope: { title: '@' },
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope)
},
template:
'
' +
'
',
replace: true
}
})
复制代码
你可以从以下链接查看效果:http://jsfiddle.net/powertoolsteam/GBE7N/1/
image
正如你所见,除了拥有用于实现指令的 和 标签,页面和常规HTML页面没有什么区别。HTML开发人员无需编写任何代码。当然,总需要有第一个吃螃蟹的人,创建指令共享使用,但是目前Tabs指令已经很常见了,可以在任何地方复用(如BootStrap,、jQueryUI、Wijmo, 和一些知名的前端插件集)。
由于指令的易用和易编写,许多用户已经开始使用AngularJS编写指令了。例如, AngularJS 开发组已经基于AngularJS实现了一系列指令-UI Bootstrap 来代替Bootstrap; 知名ComponentOne 控件厂商也在AngularJS 基础上创建了Wijmo ;我们也可以在GitHub上找到一些公共指令资料库:jQueryUI widgets。
拥有了 AngularJS,是不是觉得自己已经站在了巨人的肩膀上了?但是不要高兴的太早,如果已经有了这么多的指令供我们使用,那我们为什么还要学习AngularJS ,为什么还要学习自定义指令呢?
举个简单的例子,也许你有特殊的需求:假设你在一家财务公司工作,你需要创建一张财务表单,它需要以表格的形式展示数据、拥有绑定、编辑、校验并且同步数据更新到服务器的功能。表单插件很常见但是能够满足这些具体需求的不得而知了,所以你必须根据实际业务需求来创建自定义指令。
复制代码
Offshore Investment Summary
customer="currentCustomer"
country="currentCountry">
复制代码
这就是本篇文章的目的,接下来我们会讨论如何创建 AngularJS指令。
创建自定义AngularJS 指令
文章开头的自定义指令十分的简单。它仅仅实现了同步的功能。一般指令是包含更多元素的:
复制代码
//创建指令模块 (或者检索现有模块)
var m = angular.module("myApp")
// 创建"my-dir"指令
myApp.directive("myDir", function() {
return {
restrict: "E",// 指令是一个元素 (并非属性)
scope: { // 设置指令对于的scope
name: "@", // name 值传递 (字符串,单向绑定)
amount: "=",// amount 引用传递(双向绑定)
save: "&" // 保存操作
},
template: // 替换HTML (使用scope中的变量)
"
" +
" {{name}}: " +
" Save" +
"
",
replace: true,// 使用模板替换原始标记
transclude: false, // 不复制原始HTML内容
controller: [ "$scope", function ($scope) { … }],
link: function (scope, element, attrs, controller) {…}
}
})
复制代码
效果如下:
image
注意这个自定义指令遵循一种格式:以"my" 为前缀,类似于命名空间,因此如果你在应用中引用了多个模块指令,你可以通过前缀很容易的判断出它是在哪定义的。这不是硬性要求,但是这样做可以带来很多便利。
指令的构造函数会返回带有属性的JavaScript. 对象。这些内容在AngularJS 主页中都有清晰说明。以下是我对一些属性的理解:
restrict: 说明指令在HTML中的应用形式,备选项有"A"、"E" 和 "C", "M" ,分别代表 attribute、element、class和comment(默认值为"A")。我们将更多的关注attributes-如何创建UI元素。
scope: 创建指令的作用范围,scope在指令中作为属性标签传递。Scope 是创建可以复用指令的必要条件,每个指令(不论是处于嵌套指令的哪一级)都有其唯一的作用域,它不依赖于父scope。scope 对象定义names 和types 变量。上面的例子即创建了3个scope变量。
name: "@" (值传递,单向绑定):
"@"符号表示变量是值传递。指令会检索从父级scope中传递而来字符串中的值。指令可以使用该值但无法修改,是最常用的变量。
amount: "=" (引用,双向绑定)
"="符号表示变量是引用传递。指令检索主Scope中的引用取值。值可以是任意类型的,包括复合对象和数组。指令可以更改父级Scope中的值,所以当指令需要修改父级Scope中的值时我们就需要使用这种类型。
save: "&" (表达式)
“&”符号表示变量是在父级Scope中启作用的表达式。它允许指令实现比修改值更高级的操作。
template: 替代原始模板中的标记的字符串。替换功能将替换所有旧元素为新值。注意template是如何使用Scope中定义的变量的。这允许你无需写任何额外的代码即可创建macro-style. 风格指令。replace: 说明是否替换原始标记中的值或是追加原始标记中的值。默认值是false,这时原始标记将被保留。
transclude: 说明自定义指令是否复制原始标记中的内容。例如,之前展示的“tab”指令设置了transclude 为 true,因为tab 元素包含其他HTML 元素。 "dateInput" 指令则需要在初始化时为空,所以需要设置transclude 为false。
link: 该方法在指令中扮演着重要的角色。它负责执行DOM 操作和注册事件监听器等。link 方法包含以下参数:
scope: 指令Scope的引用。scope 变量在初始化时是不被定义的,link 方法会注册监视器监视值变化事件。
element: 包含指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(如果没有加载jQuery,还可以使用Angular's jqLite )。
controller: 在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互, tab 指令就是使用该参数较典型的例子:http://jsfiddle.net/powertoolsteam/GBE7N/1/
注意,当调用link 方法时, 通过值传递("@")的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法。