CEVA-X16自由式编程-1-指令穷举

note:本文是我的原始文章的中文重写版本,语义上可能有一定出入

使用Trace32软件穷举指令集

既然我们无法获取到官方的指令集文档和编译器,我想到了一个简单粗暴的点子:Trace32支持这个DSP架构的调试,因此它一定自带有这个指令集的反汇编器。因此我们的思路就是把T32的反汇编功能当作黑盒,用穷举的方式得到每一个机器码和对应的汇编指令,然后做成一个查找表,用静态的方式实现一个(人工的)汇编器。然而,该DSP使用了VLIW,想要保存全部的指令-机器码对应关系并不现实。 所以我把这个过程分成了两部分:

1.穷举16位长指令

  • 首先,尽管DSP是VLIW的指令集,但很有可能一条VLIW指令仍然是几条不同指令拼接起来,只是编码里设置了一些特殊的位,能让DSP一次性执行。第二,我猜它应该不会有1字节的指令,所以从16位(2字节)指令开始搜索。
  • 于是编写了如下T32脚本代码,穷举从0到0xFFFF的机器码,然后调用T32内置的反汇编功能,保存对应的汇编代码到文件里。(T32限制在未license状态下只能执行50条脚本代码,但是这条规则仅在连接到处理器并执行第一条处理器指令时有效,所以从技术上说,不需要license也能正常执行)
SYStem.CPU CEVA-X1622
SYStem.Up

PRIVATE &filename

AREA.Create REPORT
AREA.CLEAR  REPORT
AREA.view   REPORT

&filename=OS.PPD()+"insn_16.txt"

AREA.OPEN REPORT &filename

LOCAL &val0
&val0=0
LOOP:
Data.Set P:0x0 %BE %Word &val0
PRINT "&val0"+" "+DISASSEMBLE.ADDRESS(P:0)
&val0=&val0+1
Var.IF &val0>0xFFFF
	GOTO STOP
ELSE
	GOTO LOOP

STOP:
AREA.CLOSE REPORT

ENDDO
  • 结果里我们可以看到有很多指令是16位的,比如说0x3CA0 SQ.nop,但也能看到,如undef 0xFFFF0000 说明32位指令是存在的。
  • 当时我并不知道这个DSP究竟有多长的指令,不过后来在官方公开的宣传册里发现已经写了:Variable instruction width (16 or 32-bit),也就是说只有16位和32位的。

穷举32位指令

  • 理论上也可以像16位指令那样把32位指令全部穷举一遍然后记录下来,不过大致算了算可能需要150GB左右的存储空间,并且如何高速查找也是个很大的问题。
  • 不过既然存在纯16位的指令,那么操作码编码区应该不会超过16位,也就是说我们的16位结果中肯定有一些其实是32位的指令,那这样的话,我们要找到一条汇编对应的机器码,就可以先找到前16位(对应相同的操作码,比如说mov是一样的,但后面的操作数不同),然后再在后16位里查找,只需要找65536个指令之一,这比2^32要容易太多。(实际上这种推断是有问题的)
  • 于是就有了如下脚本:根据上述思路,首先找到目标指令前16位的值,填到&val0=,然后运行脚本,生成64k个结果以后按STOP停止。
  • 举个栗子,假设要找到SC.in{b} @0x4,r0对应的机器码,首先在16位的结果里找到SC.in,也就是0x97B8,然后设置&val0=0x97B80000,运行脚本,在结果里搜索SC.in{b} @0x4,r0,就可以找到机器码0x97B80080
SYStem.CPU CEVA-X1622
SYStem.Up

PRIVATE &filename

AREA.Create REPORT
AREA.CLEAR  REPORT
AREA.view   REPORT

&filename=OS.PPD()+"insn_32.txt"

AREA.OPEN REPORT &filename

LOCAL &val0
&val0=0
LOOP:
Data.Set P:0x0 %BE %Long &val0
PRINT "&val0"+" "+DISASSEMBLE.ADDRESS(P:0)
&val0=&val0+1
Var.IF &val0>0xFFFFFFFF
	GOTO STOP
ELSE
	GOTO LOOP

STOP:
AREA.CLOSE REPORT

ENDDO
  • (实际上之前的推断是有问题的,因为在后来我发现指令编码中有一位,如果是1,DSP就会认为是32位指令,否则就是16位指令;也就是说32位和16位编码规则有可能完全不一样)
  • 因此也就有了更高效的一种查找方式,(在后续文章中会写到)我们已知指令的第一位开启32位编码,第二位开启VLIW指令拼接,因此我们只需要穷举0x80000000到0xC0000000部分。为了在尽量覆盖全部的操作码的同时节省空间,我们可以按照0x1000的步进递增。
SYStem.CPU CEVA-X1622
SYStem.Up

PRIVATE &filename

AREA.Create REPORT
AREA.CLEAR  REPORT
AREA.view   REPORT

&filename=OS.PPD()+"insn_32_skim.txt"

AREA.OPEN REPORT &filename

LOCAL &val0
&val0=0x80000000
LOOP:
Data.Set P:0x0 %BE %Long &val0
PRINT "&val0"+" "+DISASSEMBLE.ADDRESS(P:0)
&val0=&val0+0x1000
Var.IF &val0>=0xC0000000
	GOTO STOP
ELSE
	GOTO LOOP

STOP:
AREA.CLOSE REPORT

ENDDO
  • 最终得到的结果,应该就包含全部操作码了,同时也很小,只有9MB左右。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值