在之前的文章中,我们测试过一些简短的一小段程序,这些程序都有一个共同的程序运行流程,就是一句一句地向下执行,比如:
movea.l #$325, a0 * ↓
move.b #$01, (a0) * ↓
move.b #$02, $01(a0) * ↓
move.b #$03, $02(a0) * ↓
move.b #$04, $03(a0) * ↓
move.b #$05, $04(a0) * ↓
move.b #$06, $05(a0) * ↓
move.b #$07, $06(a0) * ↓
也就是程序从第一句开始,按照顺序执行,这里就要了解一个特别的寄存器:
PC (Program Counter) 程序计数器寄存器
PC寄存器也是M68K的一个寄存器,他的作用是存储当前运行程序的位置,我们在之前的所有测试程序,都是存在“只读存储器”中的,也就是常常说到的ROM。ROM可以把数据固化在存储器中,只可读出,但无法改写。ROM的特点是把信息写入存储器以后能长期保存,不会因电源断电而丢失信息。当然,我们可以通过一些手段来改写ROM中的数据,这个在之后的文章中会是主要的知识点。
和内存一样,所保存的每个数据,都有一个地址指向这个数据,我们来看看上面这段程序的例子:
*-----------------------------------------------------------
* Title :
* Written by :
* Date :
* Description:
*-----------------------------------------------------------
ORG $1000
START: ; first instruction of program
* Put program code here
movea.l #$325, a0
move.b #$01, (a0)
move.b #$02, $01(a0)
move.b #$03, $02(a0)
move.b #$04, $03(a0)
move.b #$05, $04(a0)
move.b #$06, $05(a0)
move.b #$07, $06(a0)
SIMHALT ; halt simulator
* Put variables and constants here
END START ; last line of source
我们同时打开内存窗口查看
可以发现两者的数据是一模一样的。我们查看当前的PC寄存器:
也就是说,当前PC寄存器的值为$1000,也就是说,程序将要执行的指令地址为$1000。我们点击步进按钮一次,同时观察PC寄存器的变化:
可以看到,PC寄存器的值变成了$1006,那么,为什么该值是增加了$6呢,我们来查看上一句执行的代码:
我们可以看到,在地址$1000的位置,数据分为两个部分:
地址 | 机器码 | 指令码
0000 1000 | 207C 0000 0325 | movea.l #$325, a0
我们可以看到指令码部份,是我们输入的程序指令代码,我们可以称呼这部份为助记符,我们输入的这部份指令,经过编译器的编译,会把这一句代码翻译为计算机可以识别的机器码:
207C 0000 0325
那么,也就是说,这句我们输入的指令,经过编译器的翻译,生成了一段长度为6个字节的16进制的数值。当然,并非所有的指令都会生成长度为6个字节的数值,生成的长度因指令不同而不同。比如该段代码的第二句,是生成了长度为4个字节的数值
地址 | 机器码 | 指令码
0000 1006 | 10BC 0001 | move.b #$01,(a0)
那么,如果我们再次步进,PC寄存器的值应该就会增加$4,我们再次步进,观察PC值的变化:
可以观察到,步进后PC寄存器的值变为了$1006 + $4 = $100a。
我们可以尝试改变PC的值,我们在PC寄存器的输入框中把寄存器的值更改为$1000,并再次步进来观察程序的运行情况:
可以观察到,程序并未运行应该运行的下一句$100A,而是回到$1000重新运行了一次。
这里需要注意,我们PC值的选择必须为指令的开始,如果设置了比如$1002,那么机器会执行:0000 0325这段指令,这种情况下,计算机不会正常运行完整的指令,这会造成两种情况,运行错误或者不能实现指令的功能。我们把程序重置,来测试一下:
步进,并观察A0寄存器,如果正常运行该指令,A0寄存器会变为$325:
这时,我们可以观察到,A0并未发生变化,也就是说当设定了一个错误的地址,会造成程序的运行错误。
在M68K中,有部份指令可以在程序的运行中,更改PC寄存器的值:比较常用的有jmp,bra,jsr等:
jmp指令
jmp - 该指令会把目的操作数传递到PC寄存器
我们可以测试一下该指令:
*-----------------------------------------------------------
* Title :
* Written by :
* Date :
* Description:
*-----------------------------------------------------------
ORG $1000
START: ; first instruction of program
* Put program code here
movea.l #$325, a0
move.b #$01, (a0)
move.b #$02, $01(a0)
move.b #$03, $02(a0)
jmp $1000
move.b #$04, $03(a0)
move.b #$05, $04(a0)
move.b #$06, $05(a0)
move.b #$07, $06(a0)
SIMHALT ; halt simulator
* Put variables and constants here
END START ; last line of source
这段代码在之前的测试代码中间加入了一句jmp $1000,也就是说,当运行完这一句代码后,我们的PC寄存器会被更改为$1000,也就是程序会跳回到$1000,我们来测试一下:
我们步进到jmp指令处,当我们再次步进,就可以发现,程序回到了$1000