This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

c代码中调用汇编函数有问题

Other Parts Discussed in Thread: MATHLIB

c代码是这样的:(test.c)

extern int u32_sqrt2(int, int*);

int  main()
{

	int ival[16] = {1073741824,536870912,268435456,134217728,67108864,33554432,16777216,8388608,4194304,2097152,1048576,524288,262144,131072,65536,32768};

        int m = u32_sqrt2(49, ival);

	printf("m:%d---------------",m);

       return (m);

}

 

 

汇编代码是这样的:(lab.asm)

.global u32_sqrt2
u32_sqrt2:

 SUBAW.D2      B15,0x6,B15
 MV.L1X        B4,A3
 ||         STW.D2T1      A4,*B15[1]
 STW.D2T1      A3,*B15[2]
 ;36         int r = 0;
 MVK.L1        0,A3
 STW.D2T1      A3,*B15[3]
 ;39         for(i=0;i<16; i++)
 MV.L2X        A3,B4
 STW.D2T2      B4,*B15[4]
 MVK.S2        16,B5
 CMPLT.L2      B4,B5,B0
  [!B0]  BNOP.S1       L4,5
 ;41             int x = ival[i];
L1:
 MV.L2         B4,B5
 ||         LDW.D2T2      *B15[2],B4
 LDW.D2T2      *B4[B5],B4
 NOP           4
 STW.D2T2      B4,*B15[5]
 ;43             if(x + r <= val)
 LDW.D2T2      *B15[3],B5
 LDW.D2T2      *B15[1],B6
 NOP           3
 ADD.L2        B5,B4,B4
 CMPGT.L2      B4,B6,B0
  [ B0]  BNOP.S1       L2,5
 ;45               val -= x + r;
 LDW.D2T2      *+B15[5],B6
 LDW.D2T2      *+B15[1],B31
 NOP           3
 ADD.L2        B5,B6,B4
 SUB.L2        B31,B4,B4
 STW.D2T2      B4,*B15[1]
 ;46               r = (r >> 1) | x;
 LDW.D2T2      *B15[3],B4
 MV.L2         B6,B5
 NOP           3
 SHR.S2        B4,0x1,B4
 OR.L2         B5,B4,B4
 STW.D2T2      B4,*B15[3]
 ;47             }
 BNOP.S1       L3,5

 ;50               r = r >> 1;
L2:
 MV.L2         B5,B4
 SHR.S2        B4,0x1,B4
 STW.D2T2      B4,*B15[3]
 ;39         for(i=0;i<16; i++)
L3:
 LDW.D2T2      *B15[4],B4
 ADD.L2        B4,1,B4
 STW.D2T2      B4,*B15[4]
 MVK.S2        16,B5
 CMPLT.L2      B4,B5,B0
 [ B0]  BNOP.S1       L1,5
 ;53          return r;
L4:
 LDW.D2T1      *+B15[3],A4
 ;55       }
 ADDK.S2       24,B15
 BNOP.S2       B3,5
 
汇编对应的c语言是这样的:
int u32_sqrt(int val, int* ival)
{
  int r = 0;
  int i;

  for(i=0;i<16; i++)
  {
      int x = ival[i];

      if(x + r <= val)
      {
        val -= x + r;
        r = (r >> 1) | x;
      }
      else
      {
        r = r >> 1;
      }
  }
   return r;

}

 

 

编译正常,运行时发现调用u32_sqrt2一直不会返回。 请问这段汇编代码有问题吗? 

  • #1. 这段汇编是下现C函数编译产生的?还是你根据C代码自己写的汇编?

    #2.  TI提供了sqrt的库函数了(rts库,以及mathlib),没必要自己写。

  • 这段代码是C函数编译产生的反汇编,我做了一点修改,否则编译不通过。

    这是我用来练习的,所以没有用TI的库。

  • 我发现汇编代码在下面这一句出错了:

     ;39         for(i=0;i<16; i++)
    L3:
     LDW.D2T2      *B15[4],B4         
     ADD.L2        B4,1,B4            
     STW.D2T2      B4,*B15[4]          

    这里每次从*B15[4]取出的i都是0,加1后变为1,再存放到,*B15[4], 下次再调到这儿时,LDW.D2T2      *B15[4],B4得到的数据是0。

    代码中修改*B15[4]的只有这个地方,请问哪儿有问题?  多谢了!

  • #1. 为什么C代码产生的汇编不做修改编译不过?

    #2. 上面*B15操作没有考虑指令的延时,LDW的delay slot 为 4, 即4个nop后取值才到达目标寄存器。所以上面的代码第一次的ADD B4,1, B4的B4的值不是上面LDW来的。

    指令说明参考sprufe8b。写汇编一定要了解每条指令的delay slot,不然错了都不知道怎么回事。

    其实不建议写汇编了。

  • 因为编译器产生的汇编代码中包含了

    .fphead       p, l, W, BU, nobr, nosat, 1011111b 这样的语句,

    这些被我删除了, 删除的地方有些需要添加NOP