我正在尝试编写一个包含两个源文件的程序:用C语言编写的主程序和从C调用的程序集(x86 32和64)模块。程序集例程的C语句如下所示: void mirrorbmp1(void * img,int width,int height)
该任务涉及水平镜像/翻转1 bpp .BMP图像,同时正确处理任何图像宽度,而不仅是8的倍数。
我是汇编编程的新手,对我应该怎么做这个问题一无所知。
任何帮助都将不胜感激。
答案 0 :(得分:1)
解决方案应该基于汇编程序中的shift和rotate指令。如果您知道如何使用宏进行编程,则可以创建一个智能宏,它将为每个图像宽度生成8个例程(最后一个字节为0到7位)。
宽度为8的倍数的基本情况示例:
;al ... byte from input
;bl ... for output
;load from [esi] to al and move to next byte:
lodsb
repeat 8x:
shr al
rol bl
;store bl do [edi] and move to previous byte:
mov [edi],bl
dec edi
宽度不是8的倍数的示例:
repeat 3x:
shr al
rol bl
lodsb
repeat 5x:
shr al
rol bl
mov [edi],bl
dec edi
我希望这些简短的例子可以为您提供足够的指导,以便您可以自己制作完整的解决方案。祝你好运。
答案 1 :(得分:0)
如果图像是.BMP,则每条线在DWORD边界上对齐,因此每行的开头至少在字节边界处对齐。
要镜像图像,必须反转每个字节中的位顺序,并反转字节顺序。它们可以轻松组合:
void rev_line(unsigned char* line, unsigned char* tmp_buff, int line_sz){
unsigned char* line2 = line + line_sz/8 - 1; // last complete byte of the input buffer
int bit_delta = line_sz % 8; // number of unaligned bits.
// special case for bit_delta == 0 :
if (!bit_delta){ // just reverse the input
while (line < line2){
unsigned char c = reverse(*line);
*line++ = reverse(*line2);
*line2-- = c;
};
if (line == line2) // odd number of bytes, so we'll just reverse it.
*line = reverse(*line);
return;
};
// now we have to take bit_delta bits from
for (; line2 >= line; line2--)
*tmp_buff++ = (reverse(line2[1]) >> (8 - bit_delta) | // not sure about endianness here!
(reverse(line2[0]) << bit_delta;
memcpy(line, tmp_buff, (line_sz + 7) / 8);
};
它没有优化,但解释了这个想法。请注意,你必须非常擅长组装才能击败C编译器,所以要测量!
答案 2 :(得分:0)
我不知道.bmp文件是如何存储在内存中的,但是在第一种方法中我会做类似于(伪代码)的事情:
for y = 1 to row_num
for x = 1 to col_num / 2
swap pixel(x, y) with pixel(col_num - x, y);
next x
next y