一次不成功的汇编优化

最近跟一个同事讨论一个读取bmp图片显示的问题时,他提出想用汇编进行优化。于是我就写了个例子尝试了一下,代码如下:

   #include <iostream>
#include <windows.h>
using namespace std;

#define SOURCE_LEN 400000
#define DEST_LEN   800000
int main()
{
    char *pBuff = new char[SOURCE_LEN]; // 先分配400k
    char *pDest = new char[DEST_LEN];
    FILE *fp = fopen("c://test.bmp", "rb");
    if (!fp)
        return -1;

    int iCount = fread(pBuff, 1, SOURCE_LEN, fp);
    if (iCount == 0)
        return -2;

    BITMAPFILEHEADER *pfHeader = (BITMAPFILEHEADER*) pBuff;
    int iOffSet = pfHeader->bfOffBits;
    BITMAPINFOHEADER* pIheader = (BITMAPINFOHEADER*) &(pBuff[sizeof(BITMAPFILEHEADER)]);
    if (pIheader->biBitCount != 24)
        return -3;

    int iWidth = pIheader->biWidth;
    int iHeight = pIheader->biHeight;
   
    int i24Pitch = pIheader->biSizeImage / iHeight;
    int i32Pitch = iWidth * 4;
    char* pb24 = &pBuff[iOffSet];
    char* pb32 = &pDest[i32Pitch*(iHeight-1)]; //pb32 指向缓冲最后一行的开头, pb24指向bmp文件数据第一行

__asm
{    
        push esi
        push edi
        push ecx
        push eax
        mov ecx, iHeight

_loop1:
        mov esi, pb24
        mov edi, pb32
        push ecx
        mov ecx, iWidth

_loop2:
        mov al, byte PTR [esi]; 按位来移动, 因为esi的值是按三增加的,不对齐
        mov byte ptr[edi+2], al
        mov al, byte PTR [esi+1]
        mov byte ptr[edi+1], al
        mov al, byte PTR [esi+2]
        mov byte ptr[edi], al
        mov al, 0xff
        mov byte PTR[edi+3], al
        
        add esi,3;  24  要加3        
        add edi,4;  32 加 4
        dec ecx;
        jnz _loop2;
        
        ; 每处理一行pb24 要制向下一行.pb32要指向上一行
        mov eax, pb24;
        add eax, i24Pitch
        mov pb24, eax

        mov eax, pb32
        sub eax, i32Pitch
        mov pb32, eax
        
        pop ecx
        dec ecx
        jnz _loop1
        
        pop eax ; 恢复寄存器
        pop ecx
        pop edi
        pop esi
}

    delete pBuff;
    delete pDest;

    return 0;
}

这个是显示的测试代码. 直接写点,主要是测试代码是否正确,没有考虑效率问题.

for (int i = 0; i < m_iHeight; i++)
    {
            for (int j = 0; j < m_iWidth; j++)
            {
                int iIndex = i*m_iWidth*4+j*4;
                DWORD dwColor = *(DWORD*)&m_pDest[iIndex];
                dwColor = dwColor & 0x00ffffff;
                pDC->SetPixel(j, i, dwColor);
            }
        }

这个内联汇编实现了把bmp的24位格式转换为可在DirectDraw下使用的32位RGBA格式.
写完之后,发现与用c写出的代码相比,效率并无提高.以前就听说编译器优化是如何强劲,
现在是领教了哦.
其中有一些值得关注的问题,
1. BMP文件中颜色数据是以BGR的方式保存的,需要进行转换.
2. 要记得保存使用的寄存器.虽然VC inline Assemble 不要求保存寄存器,但是还是要有这个意识才可以哦.
3. 图片文件每行要4字节对齐,所以必须计算Pitch,而不能通过每次累加3来确定每行边界.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值