ARM内联汇编代码在运行时无法正常工作

时间:2014-01-14 13:55:57

标签: c assembly android-ndk arm cpu-registers

此代码用于打开opensl_es音频记录捕获单声道流,复制流并分别处理左声道和右声道,然后将两个声道混合到输出流中,稍后使用opensl_es播放。汇编代码的原因是因为我在混音函数中找到了一个瓶颈,我之前用c语言编写了一个简单的for循环来将左右缓冲区连接到输出缓冲区

好吧,这个问题很奇怪,当我把输入流中的日志放入我想要的内容时,左右缓冲区的混合工作,我在日志中看到它,当我尝试播放流时应用程序崩溃,每当我评论日志时都会发生同样的情况,由于某种原因应用程序崩溃了,所以我开始认为它与我正在使用的寄存器或汇编代码中的某些东西有关,我是汇编的新手所以关于手臂组装我有什么遗漏吗?

知道为什么会这样,或者我该如何解决这个问题?

这里是代码:第一个函数是我用来捕获声音调用过程函数的主函数。第二个“mux”是内联汇编的函数。

void start_playing()
{
    OPENSL_STREAM  *pStream;
    int samps, i, j;
    short  inbuffer[VECSAMPS_MONO], outbuffer[VECSAMPS_STEREO];
    pStream = android_OpenAudioDevice(SR,1,2,BUFFERFRAMES);
    if(pStream == NULL)
    {
        return;
    }

    on   = 1;
    iLog = 0;
    while (on)
    {
        samps = android_AudioInRaw(pStream,inbuffer,VECSAMPS_MONO); //audio recording
        //signal processing process called here for left channel then for right channel (equalizing, etc)
        mux(inbuffer, inbuffer, outbuffer,VECSAMPS_MONO); //Assembly mixing of left and right channel into output channel
        //android_AudioOutRaw(pStream,outbuffer,samps*2);//audio playing
    }

    android_CloseAudioDevice(pStream);
}


//assembly function here
void mux(short *pLeftBuf, short *pRightBuf, short *pOutBuf, int vecsamps_mono)
{
    int *pIter;
    *pIter = vecsamps_mono / 4;

    __android_log_print(ANDROID_LOG_INFO, "$$$$$$$$$$$$", "value : %d , %d , %d , %d",pLeftBuf[0],pLeftBuf[1], pRightBuf[0],pRightBuf[1]);

    asm volatile(
        "ldr r9, %[outbuf];"
        "ldr r0, %[leftbuf];"
        "ldr r1, %[rightbuf];"
        "ldr r2, %[iter];"
        "ldr r8, [r2];"

        "loop: "

        "ldr r2, [r0];"
        "ldr r3, [r1];"

        "ldr r7, =0xffff;"

        "and r4, r2, r7;"
        "and r5, r3, r7;"
        "lsl r5, r5, #16;"
        "orr r4, r4, r5;"

        "lsl r7, r7, #16;"

        "and r5, r2, r7;"
        "and r6, r3, r7;"
        "lsr r6, r6, #16;"
        "orr r5, r5, r6;"

        "str r4, [r9];"
        "str r5, [r9, #4];"

        "add r0, r0, #4;"
        "add r1, r1, #4;"
        "add r9, r9, #8;"

        "subs r8, r8, #1;"
        "bne loop"
                :[outbuf] "=m" (pOutBuf)
                :[leftbuf] "m" (pLeftBuf) ,[rightbuf] "m" (pRightBuf),[iter] "m" (pIter)
                :"r0","r1","r2","r3","r4","r5","r8","r9","memory","cc"
        );
    __android_log_print(ANDROID_LOG_INFO, "##################", "value : %d , %d , %d , %d" ,*pOutBuf,*(pOutBuf+1),*(pOutBuf+2) ,*(pOutBuf+3));
}

有什么建议吗? 这是我在logcat中得到的错误:

  

01-14 11:41:40.992:A / libc(16161):致命信号11(SIGSEGV)位于0x00000000(代码= 1),线程16178(线程-4783)

1 个答案:

答案 0 :(得分:2)

*pIter = vecsamps_mono / 4;
...
    "ldr r2, %[iter];"
    "ldr r8, [r2];"
...
     ...[iter] "m" (pIter)

也许,只是vecsamps_mono不是有效内存地址的4倍。

不是说你甚至走得那么远,在第一行取消引用一个未初始化的指针。