(1)无条件绝对转移指令:AJMP addr11 (2)无条件长转移指令:LJMP addr16 (3)无条件相对转移指令:SJMP rel 在讲解上面这三条指令之前先来认识一下三个符号:add11、add16、rel。其中add11 和add16 表示外部ROM 的16 位和11 位地址,前面我们已经讲过,单片机的外部ROM 可以扩展到64K,add16 就 表示64K 程序存储器的任何地址,换句话说LJMP 指令可以跳转到程序的任何地方,而add11 则表示下 一条指令的2K 页面,也就是说,SJMP 指令只能跳转到程序的2K 范围之内;rel 表示8 位的偏移量,其 范围是下一条指令第一字节的前128 到后127 个字节(即-128-+127B)。介绍完了三个符号,再看上面的 三条转移类指令,如果要仔细分析的话,它们之间其实区别较大,但在初学时,我们可以不理会这么多, 统统把它们理解成:(*JMP 标号),比如SJMP LOOP,就是跳转到有LOOP 标号处。原则上,所有用SJMP 或AJMP 的地方都可以用LJMP 来替代。因此在初学时,需要跳转时可以全用LJMP 代替,除了一个场合, 什么场合呢?先看一下AJMP,AJMP 是一条双字节指令,也就说这条指令本身占用存储器(ROM)的两个 单元,而LJMP 则是一条三字节指令,即这条指令占用存储器(ROM)的三个单元,这就是区别。下面再 来看第4 条跳转指令: (4)无条件间接转移指令:JMP @A+DPTR 这条指令的用途也是跳转,跳转到什么地方去呢?这可不能由标号简单地决定了,让我们从一个 实际的例子入手吧: MOV DPTR,#TAB ;将TAB 所代表的地址送入DPTR MOV A,R0 ;从R0 中取数(详见下面说明) MOV B,> ; MUL A,B; A 中的值乘2 ;(详见下面的说明) JMP A,@A+DPTR ;跳转 TAB: AJMP S1 ;跳转表格 AJMP S2 ; AJMP S3 ; 。 。 。 。 。 应用背景介绍:在单片机开发中,经常要用到键盘,见下面的9 个按键的键盘图。我们的要求是: 当按下功能键AG 时去完成不同的功能,这用程序设计语言来表达的话,就是:按下不同的键去执 行不同的程序段,以完成不同的功能,怎么样来实现这个功能呢? 看图,前面的程序读入的是按键的值,如按下‘A"键后获得的键值是“0”,按下‘B"键后获得的 值是“1”等等,然后根据不同的值进行跳转,如键值为“0”就转到S1 处执行,如键值为“1”就转到 S2 处执行,到底如何来实现这一功能呢? 先从程序的下面看起,是若干条AJMP 语句,这若干条AJMP 语句最后在存储器中是这样存放的(见 图),也就是每个AJMP 语句都占用了两个存储器的空间,并且是连续存放的。而AJMP S1 存放的地址是 TAB,到底TAB 等于多少,我们不需要知道,把它留给汇编程序来算好了。 下面我们来看这段程序的执行过程:第1 条MOV DPTR,#TAB 执行完了之后,DPTR 中的值就是 TAB,第2 条是MOV A,R0,我们假设R0 是由按键处理程序获得的键值,比如按下‘A’键,R0 中的值 是“0”,按下‘B’键,R0 中的值是“1”以此类推;现在我们假设按下的是‘B’键,则执行完第 2 条指令后,A 中的值就是“1”。并且按照我们的分析,按下‘B’后应当执行S2 这段程序,让我们来 看一看是否是这样呢?第3 条、第4 条指令是将A 中的值乘“2”,即执行完第4 条指令后A 中的值是“2”, 下面就执行JMP @A+DPTR 了,现在DPTR 中的值是“TAB”,而A+DPTR 后就是“TAB+2”,因此,执行完 这条程序后,将会跳到TAB+2 这个地址处继续执行;看一看在TAB+2 这个地址里面放的是什么?就是 AJMP S2 这条指令,因此,马上又执行AJMP S2 这条指令,程序将跳到S2 处往下执行,这与我们的要 求相符合。请大家自行分析按下键‘A’、‘C’、‘D’之后的情况。 这样我们用JMP @A+DPTR 这条指令就实现了按下一个键跳转到相应程序段去执行的这样一个要 求。再提一个问题,为什么取得键值后要乘“2”呢?如果例程下面的所有指令换成LJMP,即:LJMP S1,LJMP S2这段程序还能正确地执行吗?如果不能,应该怎么改? |
|