易码技术论坛

 找回密码
 加入易码
搜索
查看: 258046|回复: 8

【讨论】有兴趣的来,探讨一下文曲星增加TRACE功能的可行性及实现方案

[复制链接]
发表于 2005-5-30 18:15:00 | 显示全部楼层
汗~看了下3个方案~发现都好麻烦~个人开始比较倾向第二个方案~因为那天你和我说TRACE后我第一想到就是这个方案~当然那时候只有初步的映象~后来也没仔细想过~

现在想了一下~比较仓促~可是发现好像不太行……

1 我们需要划一块内存~做为虚拟的寄存器和指令存放地址~这个很容易~
2 然后我们通过虚拟PC读取指令和操作数~这也简单~
3 把虚拟寄存器里的内容放回真的寄存器?可是这样做的时候那些真的寄存器的值好像会发生因为我们读取虚拟寄存器而变化~如果保证我们将虚拟寄存器的值送回这个操作自身不改变寄存器的值呢?这个貌似不太好解决嘛~

这样的话第二个方案似乎不行

似乎只有第3个方案实现可能最高~

1 我们还是需要划一块内存作为虚拟寄存器和堆栈还有指令存放的空间~这块空间不会大~很小~只要TRACE时候执行的代码不要涉及这一块就可以~
2 然后通过虚拟PC读取指令和操作数
3 模拟执行这些指令~模拟更改那些虚拟寄存器的值~这个其实好像不算很难吧~就是很麻烦~所有指令的虚拟执行方法都要写出来~肯定是个庞大的程序……

以上是本人的一点拙见~想的可能不太严密~不过还是说出来~吼吼~
发表于 2005-5-30 21:48:00 | 显示全部楼层
什么是TRACE功能???
发表于 2005-5-30 22:49:00 | 显示全部楼层
以前就有人讨论过 我当时就建议用虚拟
发表于 2005-5-31 06:07:00 | 显示全部楼层
那GVBasic上的TRACE是怎么回事?
发表于 2005-5-31 11:35:00 | 显示全部楼层
TRACE就是单步跟踪嘛~~
发表于 2005-5-31 17:32:00 | 显示全部楼层
顺便一问TRACE模式下遇到JSR和INT指令怎么运行?直接执行完整个子程序?还是跳转过去继续TRACE?如果是跳转过去继续TRACE的话~方案2就不可行了啊~
所以貌似还是方案3最好~虽然麻烦~主要就是模拟对标志位的影响和跳转嘛~
 楼主| 发表于 2005-6-2 16:53:00 | 显示全部楼层
以下是引用QIQI在2005-6-2 15:51:09的发言:

加TRACE应该是比较困难的,除非用IRQ?不过SEI后就不行了,而且改IRQ很麻烦也很危险

改IRQ的难度和危险性倒是不必担心.只是现在想来,改IRQ似乎是没有什么意义的.
看来只好采用第二种方案了.唉~考试完再说吧!
发表于 2005-6-9 18:08:00 | 显示全部楼层
又是一个,不错。

应该是用模拟比较方便吧,只是速度....

JSR和INT到是比较容易实现。

记得WQX的IRQ好象是用8输入与非门到IRQ触发中断,中断线则连在数据线上,通过$01

来识别中断类型。

没时间把WQX的IRQ处理部分看完,不知道这8根线是一一对应的8种,还是编码的255种?还有没有空的?

记得乱写$01会死机啊,这说明软件写$01也会引起IRQ吧?那如果修改IRQ的服务程序是否能制作自己的软中断?
 楼主| 发表于 2005-5-30 13:45:55 | 显示全部楼层 |阅读模式
我打算为NCTOOLS增加TRACE功能,苦于实现起来比较麻烦,希望大家能帮忙考虑一下如何实现比较好,以及其它的一些你能想到的问题和要注意的东西.

目前我想了三种方案:


========
方案一
========
今天上午刚学习了8086/8088系统中断的工作机理,也对比了一下文曲星的CPU.由于8086/8088CPU在硬件设计时PSW寄存器中设计了TF标志位,所以它实现DEBUG中的TRACE功能相对来说要容易得多.但6502的CPU却不行了,硬件上无法产生单步中断,因此只好使用软件模拟单步中断服务.
我大体想了一下,要是使用软件模拟单步执行服务的话,要做到以下几点:
1.判断是否启用单步执行.若是则执行一些功能,如果不是则直接返回.
2.在单步中断服务程序执行时必须保证不再处于单步状态.否则的话....
3.单步执行中断服务必须在每执行一条指令后都能有效地发挥作用,也就是说,必须真正做到 "单"步.这个要精确地控制在"本条指令执行后,下一条指令读取之前".这样的话,必须在每执行完一条执令后有一个中断,使CPU转向单步执行服务程序.这样的话会大大影响文曲星的运行速度.
这三点不是太容易实现.因为仅仅第二个就足以让人大伤脑筋,更不用说第三个了.
想来想去,觉得把单步执行中断服务放在系统的IRQ中比较好.因为这样的话,系统一旦进入IRQ,就不会再响应同等级的中断,也就不会再响应单步中断了.这样可以解决第二个问题了.只是不知道IRQ在多少时间内会产生一次,能不能抓住每一条指令.假如两次IRQ发生的时间差一定小于CPU运行两条指令的时间差,那么这种方案可行.这样的话,单步中断服务程序的主要任务有下面几个:
1.禁用IRQ.这个已经在进入服务程序时实现了.
2.判断是否处于TRACE状态,若否,则返回.
3.输出上条指令执行后CPU的各寄存器的值,放于指定位置.
4.返回.


========
方案二
========
直接使用子程序,什么时候需要单步,就直接调用子程序来完成单步执行一条指令.
这样的话,需要有下面的功能:
给定CPU的初值和下一条指令的地址后,能准确地提取下一条指令的操作码和操作数,能有效地控制CPU只执行这么一条指令并准确地记录执行完这么一条指令后CPU各寄存器的状态.
子程序大约有下面的结构:
程序功能: 单步执行一条指令
入口参数: 下一条指令所在地址(PC值);下一条指令执行前的 A,X,Y,P,S 的值;执行后CPU各寄存器的值要放的位置.
出口参数: 入口参数中给定位置的指令执行后, PC,A,X,Y,P,S 的值.
运行过程:
A.获取PC,置于伪PC.
B.读取指令的操作码,发送到 临时指令缓存区; 伪PC要加一.
C.根据指令的操作码,读取操作数,发送到 临时指令缓存区; 伪PC适当地增加或者不变; 生成 临时指令缓存区中的返回指令.
D.保护现场,并将提供的 A,X,Y,P 的值读入CPU相应的寄存器.
E.调用缓冲区程序.
F.记录 A,X,Y,P 的值,写入指定位置; 根据情况计算PC和S的值,并记录于指定位置.
G.恢复现场
H.返回.
这样的话,可以实现单步执行的模拟.缺点是:
1.在主程序中要写调用单步的代码,而且要求提供的入口参数较多;
2.如果遇到与堆栈相关的操作,必须想办法处理原程序与本段程序的堆栈使用冲突,有些还要考虑程序对PC的影响.这些操作包括: PHA,PLA;PHP,PLP;JSR,RTS;INT,RTI.

========
方案三
========
完全模拟CPU的运作
这种方法可以很好地解决方案二中的第二个缺点中提到的问题.只是整体实现起来很麻烦,因为要重新创建堆栈区,以及其它的一些存储区.然后完全模拟CPU的工作,一条指令一条指令地执行,每执行一条就相应地处理这些存储区域.这种方法很笨,很慢,而且想起来很乱.


不知道大家有没有其他的好的方法,希望能共同探讨一下
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-18 09:24 , Processed in 0.011378 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表