打印

请教用过汇编转C的高手 的

[复制链接]
9801|55
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dudongdao|  楼主 | 2009-8-5 22:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
移植汇编程序到C,思路上有些堵塞了。我先说一下我的疑问。
     汇编程序时中断响应232代码,接收到正确的232命令后,把对应的处理函数压栈到SP,然后执行RETI指令到处理函数处,处理完堆栈设置为一个固定值,例子如下:
PC_RS232:   

Push      PSW
Push      A
中间是命令判断RS232_FUN_EXIT:

MOV      DPTR,         #FUN5;比如要执行函数功能5
RS232_FUN_EXIT:
           POP      A
           POP      PSW
           POP      SP_TEMP
           POP      SP_TEMP
           PUSH     DPL
           PUSH     DPH
           RETI
到这里执行了RETI就跳转到FUN5执行了。
执行完之后  ,给SP一个固定的值。         
MOV      SP,        #0BFH                 ;设置堆栈位置为0BFH
JMP      WAIT_INT

整体意思是通过232判断要执行哪个功能,然后直接到哪个功能区执行,不考虑以前
在哪一步执行,不考虑以前的SP是多少,反正执行完之后给SP一个固定的值。

这么做的好处是能快速响应串口命令,比如串口发送一个命令后,单片机执行,执行时间可能是几百毫秒或者几秒,这期间如果再有其他命令则放弃本次任务,执行新任务。
进入中断马上执行新任务可能造成SP错误,所有执行完一次任务就给SP一个固定值,

现在用C改写,应该怎么做才能做到这个实时性的要求呢,C可以这么操作堆栈吗,大家有没有什么更好的办法?

相关帖子

沙发
lonely8122| | 2009-8-5 22:34 | 只看该作者
用C语言也可以改写堆栈指针

使用特权

评论回复
板凳
dudongdao|  楼主 | 2009-8-5 22:41 | 只看该作者
大侠给个例子,关键是不好操作~~   最好是不改写堆栈达到目的~~  改写堆栈是不是结构不好,而且编译器总报错

使用特权

评论回复
地板
john_light| | 2009-8-5 22:45 | 只看该作者
在C里要实现这个可以利用函数指针数组

使用特权

评论回复
5
dudongdao|  楼主 | 2009-8-5 22:49 | 只看该作者
大侠详细赐教啊~~  我还是没太明白,能给个例子吗~~

使用特权

评论回复
6
auzxj| | 2009-8-5 23:10 | 只看该作者
最讨厌你这种一个帖子发N各模块的,BS一下。。。。。

使用特权

评论回复
7
john_light| | 2009-8-5 23:20 | 只看该作者
不好意思,我没有好好地看你的帖子。

重新看过之后,我想抛开你的思路说说我的看法。

串行数据传输的速度其实不算快,两个字节之间的时间其实可以做很多事了,具体情况可以根据单片机的时钟和串行通讯的波特率来计算。我觉得没有必要在中断中做太多事。

建议的做法:串行中断只接收并设置标志,处理及响应还是交由主程序完成。

使用特权

评论回复
8
dudongdao|  楼主 | 2009-8-6 00:11 | 只看该作者
回复7楼
主程序执行的时候有些步骤时间很长,而且伴随延时~~  无法实时判断中断标志啊~~
比如执行某个功能的时候
延时1.。。延时2,,,延时3。。。
这样的时候无法及时返回的,如果在程序中加判断,是否有新的命令,要加好多的。

使用特权

评论回复
9
john_light| | 2009-8-6 08:52 | 只看该作者
如果串行中断触发的事情不复杂,就在中断里把事情做完再出来吧。
前提:主程序的延时很长,串行中断的任务相对重要而且能很快完成。
题外:长时间的延时应该使用定时器。

另外我看了你的汇编实现方法,你把进入串行中断时的地址扔掉了。虽然你执行了DTPR中存进的程序,可是这段程序跑完要RET的,它RET不到原来断开的地方了。
你的程序真的能跑起来吗?

你真的想按你的原来思路走下去的话,我建议你看一看别人实时操作系统(如µCOS-II)的任务切换实现。

使用特权

评论回复
10
冷漠| | 2009-8-6 11:04 | 只看该作者
本帖最后由 冷漠 于 2009-8-6 11:08 编辑

很简单:
1、另开一C模块,假设SIO.C。模块中写出C中断函数的哑函数,例如:
#pragma  SRC
void PC_RS232(void) interrupt 4
{  }

单独编译之,得到SIO.src文件。打开,即宏汇编框架。填入你的汇编代码,RETI 结尾。

2、汇编SIO.src,即是SIO.C的OBJ文件。

3、如果搞不懂,很简单:在C环境写一个中断函数
void PC_RS232(void)   interrupt   4
{   
abc( );

}

其中任意调用一个C函数abc( ),看看它的CODE码,任意修改这段CODE码就行了。

使用特权

评论回复
评分
参与人数 1威望 +30 收起 理由
程序匠人 + 30 鼓励
11
dudongdao|  楼主 | 2009-8-6 15:15 | 只看该作者
回复9楼
中断地址仍了啊,所有函数执行完之后都没有RET,所有函数最后都到一个地方
JMP      WAIT_INT
并且之前是对SP重新初始化过。
没有出现RET

有些函数执行要时间,不能放中断里。

使用特权

评论回复
12
dudongdao|  楼主 | 2009-8-6 15:17 | 只看该作者
回复10楼:
我想试验一下你的第三种方案,但是还没完全看懂~~  能详细讲解一下吗~~~

使用特权

评论回复
13
john_light| | 2009-8-6 15:57 | 只看该作者
主程序的断点可以随便扔掉,那主程序的重要性可见一斑了。

我没其它想法了,看其他人给你出主意吧。

使用特权

评论回复
14
冷漠| | 2009-8-6 18:25 | 只看该作者
本帖最后由 冷漠 于 2009-8-6 18:31 编辑

回12楼:
abc()是用宏汇编完成的C调用。会写吗?
看来真是又要我上机复习功课啦。

回13楼:LZ的方案实用中常见,可行。主程序的断点确实可以随便扔掉。关键是正确的方法。就好像我们正在按部就班地执行一个计划,但是计划中有一项:一旦X 事件(中断即事件)发生,原计划中止,全班人马改变原计划计划转向另一应急方案。一旦Y 事件发生,又转向其他方案,等等等等。

呵呵,就像《我的兄弟叫顺溜》中,刘司令多次中止原计划救援陈大雷。那是救命,谁重要?

使用特权

评论回复
15
starlite_jason| | 2009-8-6 20:10 | 只看该作者
去研究一下OS的内核,看看任务是怎么切换的,你这样胡乱的设置不会出问题吗

使用特权

评论回复
16
dudongdao|  楼主 | 2009-8-6 20:25 | 只看该作者
回复14楼:
我有很多疑问现在~~  现在是彻底用C,不用汇编了~~
用C如何定义SP呢~~  如何做到实时响应~~  
大侠请赐教啊~~  我是一头雾水~~

使用特权

评论回复
17
呆板书生| | 2009-8-6 22:32 | 只看该作者
使用 setjmp 和 longjmp

主程序开始的时候用 setjmp
中断后 longjmp

使用特权

评论回复
18
dudongdao|  楼主 | 2009-8-6 22:49 | 只看该作者
?????   没懂啊~~  看的一头雾水~~

使用特权

评论回复
19
冷漠| | 2009-8-7 08:24 | 只看该作者
本帖最后由 冷漠 于 2009-8-7 08:38 编辑

很简单:送你段中断程序。
进入中断后的最初语句与你源程序相同:
........
MOV      DPTR, #FUN5;
CALL    RS232_FUN_EXIT

;下面的语句就可以看做是一个子程序了。
......
MOV      SP,        #0BFH    ;设置堆栈位置为0BFH
JMP      WAIT_INT

END


(  如果不好理解,要正规,可以仿照以前,写为:
MOV  SP, #0BFH
MOV  DPTR, #WAIT_INT
PUSH   DPL
PUSH   DPH
RET  ; 或者再次RETI




RS232_FUN_EXIT:
           POP      A
           POP      PSW
           POP      SP_TEMP
           POP      SP_TEMP
           PUSH     DPL
           PUSH     DPH
           RETI

使用特权

评论回复
20
冷漠| | 2009-8-7 08:35 | 只看该作者
一定要用C写中断程序,那你就在C程序中把汇编语句段用#pragma  asm/#pragma  endasm  罩起来就行了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

90

主题

413

帖子

1

粉丝