DSP汇编中的结构体参数传入及使用、双条件操作

2019-03-26 15:48发布

DSP汇编中的结构体参数传入及使用、双条件操作 我的板子是c6740,开发中遇到几个汇编问题求教:
1. 结构体参数传入及使用
比如一个实现简单游程编码的测试程序,如下:
struct _STREAM
{
    BYTE *buffer;
    int  size; //buffer长度
}
void encode(BYTE *pSrc, datasize, STREAM *pDstStream)
在DSP汇编中,A4接收pSrc,B4接收datasize, 问题:
--那哪个寄存器接收*pDstStream?是正常的A6接收,还是有特殊的寄存器?
--如何对结构体成员操作,如把数据存到buffer、size++等 2. 在汇编中如何写双条件判断语句啊?
如下面源程序中的!input && datasize?
while(!input && datasize)
{
    numZeros++;
    GetNextInput(input);
} 3.优化
如实现上面功能的汇编程序,因为程序需要一个字节一个字节去判断,然后进行操作,程序中有比较多的循环操作,
所以,在汇编中会出现比较多的NOP指令,这样程序性能会比较低吧?请问应该如何去提高程序性能呢? [ 本帖最后由 breeze505 于 2012-5-9 11:04 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
carrotchen
1楼-- · 2019-03-26 20:40
< 1. pDstStream用A6传。
访问结构体成员,需要手工计算偏移量。
LDW *+A6[0], A16 ; A16 = buffer,再以A16为指针,使用LDB指令访问buffer指向的内容
LDW *+A6[1], A17 ; A17 = size

2. 使用CMP和B指令(仅供参考)
   ; B16 = input, B17 = datasize
   CMPEQ B16, 0, B0
   [B0] B end_of_while
   NOP 4
   MV B17, B1
   [!B1] B end_of_while
   NOP 5
   ...
end_of_while:
   ...

3. 在汇编代码中,不建议使用结构体,因为需要手工计算偏移量,效率不高且容易出错,可以考虑在C一级把结构体拆开,再调用汇编代码。
考虑把GetNextInput函数内联,其中合适的指令提前来做。
另外如果while语句中有多个逻辑判断,会比较难以优化。for语句的循环便于优化,研究程序能否改写。
breeze505
2楼-- · 2019-03-26 20:43
 精彩回答 2  元偷偷看……
carrotchen
3楼-- · 2019-03-26 22:08
1. A_buffersize用错了,不是指针。
* ================= LOOP PROLOG ============================ *
MV .S2 B4, B_loopcount
LDW .D1T1 *+A6[0], A_pBuffer
LDW .D1T1 *+A6[1], A_buffersize ; ====> A_buffer = size,注意A_buffer是值,不是指针
ZERO .S1 A_size
* ===================== LOOP KERNEL ============================== *
loop:
LDB .D1T1 *A4++[1], A_tmp
SUB .S2 B_loopcount, 1,B_loopcount
NOP 3
STB .D1T1 A_tmp,*A_pBuffer++[1]
ADD .S1 A_size, 1, A_size

[B_loopcount] B .S2 loop
NOP 5
*===================== LOOP EPILOG ============================== *
STW .D1T1 A_size,*A_buffersize++[1] ; ====> STW A_size, *+A6[1],注意A6才是结构体指针
NOP 1
[!B_loopcount]B .S2 B3
|| MVK .S1 1,A4 ;return 1
.end

2. 对于判断较多的代码,只能改写其算法,避免多个条件判断的情况。
你的while代码块的作用大概是:逐个读取pSrc的内容,直到读到0或者长度到达data_size;记录读取0的个数到numZeros;退出循环时input的值是pSrc的内容或者0(如果长度到达data_size)
改写后的C代码是:(未验证,仅提供思路)
input = 0;
for (; data_size > 0; data_size--) // 使用条件寄存器保存data_size
{
    input = *pSrc++;
    if (input != 0) // 使用条件寄存器保存input,numZeros++可以用带条件的ADD指令
    {
         break;
    }
    else
    {
         numZeros++;
    }
}
if (data_size == 0) input = 0; // 这句代码应该是不需要了,只有data_size为0,input才未赋值,所以在开头加上初始化,需验证!

[ 本帖最后由 carrotchen 于 2012-5-10 17:16 编辑 ]
breeze505
4楼-- · 2019-03-27 03:50
 精彩回答 2  元偷偷看……
carrotchen
5楼-- · 2019-03-27 08:10
1. 如果要在encode函数中修改stream->size的值,需要传指针。
tmp = encode(pSrc, datasize, stream->pBuffer, &(stream->size));

你的程序跑飞的原因可能是因为B6中保存的是stream->size的值,而非地址。
STW         .D2T2        B4, *+B6[0]执行了非法指针操作。

2. 是的
breeze505
6楼-- · 2019-03-27 13:48
1. 双条件的我写了汇编如下,这样感觉NOP不是很多,你看是否正确:               
        [B_InputDatasize] LDH .D1T1 *A4++[1], A_input
        [!B_InputDatasize] ZERO        .L1        A_input
        ZERO        .D1 A_numZeros
        NOP 2
        [A_input] B        .S2        RunLength
        [B_InputDatasize]BDEC        .S2        loop, B_InputDatasize
        [!A_input]ADD .S1        A_numZeros, 1, A_numZeros               
        NOP 4
RunLength:
...
2.我的程序里分很多调用其他小程序,如计算一个bit位,写一个bit位等,循环下来会调用多次这样的小程序,请问这该怎么处理比较好呢?
能不能把这些小程序独立出来?那这样的话汇编里怎么调用这些小程序?

谢谢你指导下!

一周热门 更多>