汇编/霓虹灯代码崩溃

时间:2014-11-24 22:33:19

标签: assembly neon

我使用以下代码:

#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char **argv) {
    char *auyvy = malloc(640 * 480 * 2);
    char *ay8 = malloc(640 * 480);

    int fd = open("input.uyvy", O_RDONLY);
    if (fd >= 0) {
        read(fd, auyvy, 640 * 480 * 2);
        close(fd);
    }

    __uyvy_luma_extract(640, 480, auyvy, 640 * 2, ay8, 640);

    fd = open("output.y8", O_RDWR | O_CREAT);
    if (fd >= 0) {
        write(fd, ay8, 640 * 480);
        close(fd);
    }
}

附加两个文件: https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/__uyvy_luma_extract.S https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/yuv.inc

我使用&#34; gcc -g convert.c编译__uyvy_luma_extract.S -mfpu = neon&#34;

奇怪的是,程序在转换过程中崩溃了。知道我做错了吗?

*第一次编辑* 我上传了一个包含各种文件的zip文件,以便在ARM平台上轻松重现:http://www.gentil.com/tmp/convert.zip

*第二次编辑* 我更新了不正确的汇编文件链接。

*第三次编辑* gdb给出以下内容:

Starting program: /home/ai/convert/convert                                      

Program received signal SIGSEGV, Segmentation fault.
0x00008036 in ?? ()
(gdb) bt
#0  0x00008036 in ?? ()
#1  0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38
#2  0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

2 个答案:

答案 0 :(得分:5)

哦,这是一个很好的。

如果使用-marm构建但使用-mthumb中断,则可以正常工作。 Ubuntu和Android可能有不同的默认值。

它在Thumb模式下中断的原因是汇编函数(总是非Thumb)缺少符号的类型规范,因此链接器不知道它需要使用BLX指令来调用它拇指代码。执行程序时,因此在Thumb状态下错误地调用汇编函数。当解释为Thumb指令时,此函数的第一个半字0x47ff是BLX pc,它对于不可预测的行为是无效的。显然,Cortex内核只是以明显的方式执行它,即切换到ARM状态,分支到PC值(Thumb状态下的当前指令+4),并将下一个(Thumb)指令地址存储在LR中,从而给出简单地忽略了STM指令的外观。

修复方法是将此行添加到程序集文件中:

.type __uyvy_luma_extract, STT_FUNC

答案 1 :(得分:0)

你给出了错误的链接。正确的是: https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/__uyvy_luma_extract.S

图书馆被窃听。或者,当您最有可能使用完全降序堆栈时,作者会假定空降序堆栈。 将第39行和第40行更改为:

ldr     pY,         [sp, #(11 * 4)]
ldr     dstStride,  [sp, #(12 * 4)]

无论如何,在性能方面,图书馆相当黯淡。非常业余的写作,将以NEON的潜在速度的一半运行。

=============================================== ========================

编辑:查看PROLOG宏,它显示该库也推动了lr。这意味着上面的部分没有被窃听。

该功能应该正常工作,尽管不是最佳的。请检查以下内容:

  • 内存分配(不太可能)
  • 异常处理(未定义的指令异常)

您的代码崩溃了什么异常?