翻转图像汇编代码

时间:2017-01-17 06:17:53

标签: c qt assembly

我正在开发一个基于c的程序,该程序可用于图像扭曲的装配。应该工作的伪代码是这个(总是使用240x320的图像

 voltearHorizontal(imgO, imgD){

    dirOrig = imgO;

    dirDest = imgD;

    dirOrig = dirOrig + 239*320; //bring the pointer to the first pixel of the last row 

    for(f=0; f<240; f++){

       for(c=0; c<320; c++){

       [dirDest]=[dirOrig];

       dirOrig++­­;

       dirDest++;

   }

   dirOrig=dirOrig+640;//move the pixel to the first one of the upper row

   }

 }

但是当应用于汇编时,在结果上,第一行不会被读取,而是将空格保留为黑色。

https://gyazo.com/7a76f147da96ae2bc27e109593ed6df8

这是我编写的代码,它应该可以工作,而这一个是图像真正发生的事情:

https://gyazo.com/2e389248d9959a786e736eecd3bf1531

为什么使用此代码,不将origen图像的像素上线写入/读取到第二张图像?代码的哪一部分我错了?

我认为我没有留下任何标签可以解决我的问题,感谢任何可以提供的帮助(我错在哪里)。另外,水平翻转(上面的垂直方向)只是意外地完成了程序:

https://gyazo.com/a7a18cf10ac3c06fc73a93d9e55be70c

1 个答案:

答案 0 :(得分:2)

任何特殊原因,为什么你把它写成慢速汇编程序?

为什么不把它保存在快速的C ++中? https://godbolt.org/g/2oIpzt

#include <cstring>

void voltearHorizontal(const unsigned char* imgO, unsigned char* imgD) {
    imgO += 239*320; //bring the pointer to the first pixel of the last row 
    for(unsigned f=0; f<240; ++f) {
      memcpy(imgD, imgO, 320);
      imgD += 320;
      imgO -= 320;
    }
}

将使用gcc6.3 -O3编译为:

voltearHorizontal(unsigned char const*, unsigned char*):
        lea     rax, [rdi+76480]
        lea     r8, [rdi-320]
        mov     rdx, rsi
.L2:
        mov     rcx, QWORD PTR [rax]
        lea     rdi, [rdx+8]
        mov     rsi, rax
        sub     rax, 320
        and     rdi, -8
        mov     QWORD PTR [rdx], rcx
        mov     rcx, QWORD PTR [rax+632]
        mov     QWORD PTR [rdx+312], rcx
        mov     rcx, rdx
        add     rdx, 320
        sub     rcx, rdi
        sub     rsi, rcx
        add     ecx, 320
        shr     ecx, 3
        cmp     rax, r8
        rep movsq
        jne     .L2
        rep ret

IE中。比你的内联asm更有效率800%。

无论如何,在你的问题中,问题是:

dirOrig=dirOrig+640;//move the pixel to the first one of the upper row

您需要-= 640才能返回两行。

关于屏幕中的那些内联asm ...将它们作为文本提出质疑,但是从快速查看它们我只需要用C ++重写它并将它保存到编译器中,你在asm中做了许多性能错误的事情,所以我没有看到这样做的任何意义,加上内联asm是丑陋的,难以维护,并且难以正确编写。

我确实检查过asm in picture。您在eax中有行计数器,但您使用al复制像素,因此它会破坏行计数器值。

下次使用调试器。

顺便说一句,你的照片是320x240,而不是240x320。