您好,欢迎进入山西润盛进出口有限公司!

咨询服务热线

15383419322

Spoc CPU软核 Part 3-软件(即程序员)模型

发布时间:2024-01-22 14:32人气:

Spoc 有一个小指令集和一些寻址模式。这使得 Spoc 程序员的模型易于学习。

指令集

Spoc 目前支持 8 条指令:

1705888178193292.png

例子:

incRA2//incrementsregisterRA2 decA//decrementsaccumulator selWA10//selectsWA10 do#0xBA00+WA22>A//addsvalue0xBA00toregisterWA22,andwritestheresulttotheaccumulator doAand#0x5555->@//logicalANDbetweenaccumulatorandvaluegoestomemory doAxnor#0x5555>RA0//logicalXNORbetweenaccumulatorandvaluegoestoregisterRA0,selectsRA0 notRA1//invertsallthebitsinregisterRA1,selectsRA1 jsrA+RA10//calculatesA+RA10,andjumpstothisaddress(subroutine,returnswithRET) jmp#loop//jmptolabel"loop"

寻址模式

Spoc 支持 3 种寻址模式:

1705888324903172.png

例子:

do#1234->A//Immediateaddressing:movesvalue1234toaccumulator doA->RA4//Directaddressing:writesaccumulatorvaluetoregisterRA4 do@->A//Indirectaddressing:readsmemorytoaccumulator doA->@//Indirectaddressing:writesaccumulatortomemory

可以对源操作数和目标操作数使用间接寻址。

do@->@ do@+#0x22->@ doAor@->@

间接寻址与“选定的寄存器”有关(参见下面的“存储器和寄存器文件”段落)。

DO指令

DO 指令是最强大的,因为它可以使用多达 2 个源执行操作,并将结果写入多达 2 个目的地。要写入 2 个目标,请用逗号分隔它们。示例:写入 2 个目标时,一个始终是累加器,另一个是寄存器 (RAxx/WAxx) 或存储器 (@)。

do#22->A,RA0 doA+#22->A,WA1 doA-@->A,WA1 doAorRA3->WA4,A do@and#22->A,@ doWA6xor#22->A,@

累加器和数据大小

每个 spoc 指令都从可能的大小列表中指定一个数据大小。Spoc0 具有 4 种有效数据大小:1、8、16 和 32 位。 默认值为 16 位(未指定数据大小时)。数据大小是通过后缀指令(.bit、.byte、.word 和 .dw)来指定的。Spoc 还为每个有效数据大小提供了一个累加器。使用 Spoc0,这为我们提供了 4 个累加器。累加器是独立的(写入一个不会影响其他累加器)。

例子:

do.bit#1->A//writes1tothe1-bitaccumulatorinc.byteA//incrementsthe8-bitsaccumulator do.wordA+#0x1000->A//adds0x1000tothe16-bitsaccumulator do.dw#0x12DECF80->A//writes0x12DECF80tothe32-bitsaccumulator

分支

指令 JMP 用于分支到新的程序位置。指令 JSR 用于分支到新的程序位置,最终使用指令 RET 从该位置返回。这些指令可以有条件地执行(借助 C 和 Z 标志,请参阅下一段)。

例子:

jmp#gothere//jumpsunconditionally jsr#gotosubroutine//jumpsunconditionallytosubroutine jmp.Z=0#gothere//jumpsconditionally(ifflagZis0)

分支指令可以使用计算地址进行分支。 例如,可以有子例程表。注意:在任何分支指令之后,将取消选择当前寄存器(有关“选定”寄存器的讨论,请参阅后面的内容)。

在使用 JSR 指令之前,请确保初始化 SP(堆栈指针)寄存器。

例:

do#0x0C00>SP//stackfrom0x0C00to0x0FFF,enoughforadepthof64subroutinecalls jsr#mysubroutine

堆栈用于存储子例程返回地址。 堆栈使用内存并向上增长(在 Spoc0 中,SP 指针对于每个 JSR 指令递增 16,对于每个 RET 递减 16)。

标志和条件执行

标志用于有条件地执行其他指令。Spoc0 使用 2 个标志:

  • Z(零)标志。用于检测零值或“相等”比较。

  • C(携带)标志。对于无符号数字的“大于”比较很有用(还可以检测无符号添加/子操作的溢出)。

如果上一个操作的结果为 0,则 Z 标志为 0。如果上一个操作的结果不是 1,则 Z 标志为 0(注意:许多 CPU 采用相反的约定......标志由所有执行的指令设置。

例子:

do#3>AdecA//Abecomes0x0002,Cis0,Zis1 decA//Abecomes0x0001,Cis0,Zis1 decA//Abecomes0x0000,Cis0,Zis0 decA//Abecomes0xFFFF,Cis1,Zis1 decA//Abecomes0xFFFE,Cis0,Zis1 decA//Abecomes0xFFFD,Cis0,Zis1

您可以执行没有目标的 DO 操作。 在这种情况下,将执行操作,结果将丢失,但标志仍会更新。

例子:

do#3->WA0//writes3toregisterWA0 //nowwearegoingtodo3subtractions,withoutsavingtheresults.Buttheflagsarestillupdated. doWA0-#2//WA0>2,sowegetC=0,Z=1 doWA0-#3//WA0=3,sowegetC=0,Z=0 doWA0-#4//WA0<4,sowegetC=1,Z=1 //nowrunsomeconditionalinstructions jmp.c=0#mylabel1//conditionaljump,notexecutedsinceC=1 add.z=0WA0+A>RA2//conditionaladdition,notexecutedsinceZ=1 jmp.z=1#mylabel2//conditionaljump,executedsinceZ=1

最后,如果未执行条件指令,则标志也不会更新。

例:

do#1>A//Ais0x0001,Cis0,Zis1 dec.z=0A//notexecuted,andflagsnotchanged

将标志作为操作数

进位标志也可以在源操作数中使用(在源操作数中,进位标志可以命名为“C”或“CY”或“carry”)。

例:

doCY->A doA+#22+C->A doAxorCARRY->RA0

对于算术运算,进位标志值不是有符号扩展的,但对于逻辑运算,它是有符号扩展的(换句话说,对于算术运算,进位值为 0 或 1,对于逻辑运算,进位值为 0 和 0xFFFF)。

例:

do#0->AdecA//A=0xFFFF,C=1 doCY+#22->A//arithmeticoperation,soA=23 do#0->AdecA//A=0xFFFF,C=1 doCYxor#0x1111->A//logicaloperation,soA=0xEEEE

存储器和寄存器文件

符号“@”用于表示内存访问。它与名为“RAxx”和“WAxx”的寄存器结合使用。

内存读取示例(从地址0x200读取):

do#0x0200->RA0do@->A //readsmemory0x200,andputsthevalueinaccumulator

内存写入(写入地址0x200)示例:

do#0x0200->WA17 doRA3->@//writescontentofRA3tomemory0x200

读取存储器访问的地址由“RAxx”寄存器给出。写存储器访问的地址由“WAxx”寄存器给出。寄存器是寄存器文件的一部分,因此您可以使用其中的许多寄存器。Spoc0 有 32 个 RA 寄存器,命名为 RA0 到 RA31,以及 32 个 WA 寄存器,命名为 WA0 到 WA31。每个文件的一个寄存器在给定的执行时间被“选择”。 要选择寄存器,您可以使用“sel”指令,也可以写入寄存器。当指令进行内存访问时,所选寄存器的值用作内存地址。在每次内存访问期间,寄存器都会自动递增。

例:

do#0x0200->RA5//writes0x200toRA5,andselectsit do#0x0300->WA7//writes0x300toWA7,andselectsit //RA5andWA7arebothselected do@->@//copiesthevaluefrommemorylocation0x200tomemorylocation0x300 //nowRA5=0x210andWA7=0x310 doWA7+#0x20->RA6//RA6isnowselectedwiththevalue0x330 do@->A //memorylocation0x330isreadandcopiedtotheaccumulator selRA5 //re-selectRA5.Sinceitwasnon-persistent,itsvalueisbackto0x0200(seelaterforexplanationonpersistentregisters)

寄存器 RAxx/WAxx 还可用于存储器访问以外的其他目的。 它们具有与累加器几乎相同的功能,因此可以递增、添加、异或编辑......它们还可用于子例程参数传递。

内存空间

使用 Spoc0 时,每个寄存器 WAxx 和 RAxx 的宽度为 16 位 (.word),因此它可以寻址 64K。数据空间是“位可寻址”的。 因此,您可以在没有任何对齐限制的情况下访问它的任何部分。 例如,可以将一个 32 位值写入寻址0xABCD,然后在地址0xABC3写入另一个值,最后从地址0xABC7读取(读取两个值的一部分)。代码空间通常无法直接访问。 它用于保存要执行的指令。 但是有一个钩子可以访问代码空间,这样你就可以存储表、数据、字符串......Spoc0 使用寄存器 CS 访问代码空间。

例:

do#GreetingString->CS//CSpointstoastring,andselectsCSdo.byte@->A//readthe"H"intotheaccumulator ... GreetingString:data.byte"Helloworld!",13

另一个保留值是“$”。 它代表实际的PC(程序代码位置,当前执行指令的位置)。 这是一个只读值。

例:

jmp$//foreverloop(ifyouwantspocto"die")

当您使用 blockram 时(如在 Spoc0 中),代码空间是位可寻址的,如果使用串行闪存,则代码空间是字节可寻址的。 这为 Spoc64 提供了 0Kbits 的空间,而使用串行闪存时则为 64KB 的空间。

预留空间

Spoc0 使用一个块 (4Kbits) 作为数据空间,它填充0x0000到0x0FFF的地址。在此之上,0x1000 0xFFFF的空间是“外部存储器”。它应该用于连接外部外围设备。此外,保留 blockram 数据空间的前 1Kbit(地址 0x0000 到 0x03FF)来保存寄存器 RAxx/WAxx 的值。 如果你知道自己在做什么,你仍然可以使用它......

保留寄存器

寄存器 WA30/31 和 RA30/31 是保留的。 不要使用它们。例如,在 Spoc0 中,寄存器 WA31 用作 PC...所以如果你要使用 WA31,你实际上会跳到某个地方......

持久寄存器

当一个寄存器被取消选择,然后在以后重新选择时,它的值可以是“持久的”(它在最后一次自动递增之后恢复该值),也可以是“非持久的”(它恢复最初受影响的值,即在任何内存访问/自动递增之前)。您可以选择是否希望在选择寄存器时将其持久化(通过使用或不使用“.p”后缀)。

例:

do#0x0200->RA5//RA5isselected(notpersistent) do@->A//copiesthevaluefrommemorylocation0x200toaccumulator //RA5valueisnow0x210do#0x0300->RA6.p//RA6isselected(persistent) do@->A//copiesthevaluefrommemorylocation0x300toaccumulator //RA6valueisnow0x310 selRA5.p//re-selectsRA5.Sinceitwasnon-persistent,itsvalueisbackto0x0200 //notethatitisnowpersistent! do@->A//copiesthevaluefrommemorylocation0x200toaccumulator //RA5valueisnow0x210 selRA6//re-selectsRA6.Sinceitwaspersistent,itsvalueis0x0310 do@->A//copiesthevaluefrommemorylocation0x310toaccumulator //RA6valueisnow0x320 selRA5//re-selectsRA5(notpersistent).Butsinceitwaspersistent,itsvalueis0x0210 do@->A//copiesthevaluefrommemorylocation0x210toaccumulator //RA5valueisnow0x220

上一篇:Spoc CPU软核 Part 2-主要特征

下一篇:Spoc CPU软核 Part 4-硬件接口

  • 联系方式
  • 传 真:
  • 手 机:15383419322
  • 电 话:15383419322
  • 地 址:山西太原市杏花岭区解放路 175 号万达中心 A 座 33 楼 3301 室
友情链接
plc控制器
自动化设备
自动化设备
伺服驱动器
在线咨询

咨询电话:

15383419322

  • 微信扫码 关注我们

Copyright © 2022-2024 山西润盛进出口有限公司 版权所有 晋ICP备2021008479号-14

晋公网安备 14010702070906号

扫一扫咨询微信客服
15383419322