我正在开发一个基于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图像的像素上线写入/读取到第二张图像?代码的哪一部分我错了?
我认为我没有留下任何标签可以解决我的问题,感谢任何可以提供的帮助(我错在哪里)。另外,水平翻转(上面的垂直方向)只是意外地完成了程序:
答案 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。