secondsen 发表于 2012-10-16 14:31:44

还是汇编的问题

主要是弄push pop的,但是怎么都弄不好。。。上代码

第一个是有pop 和 push 的,编译过了,调试有问题0xC0000005


    __asm
    {
        mov            edi, pDstBmp        ; 目的像素
            mov            esi, pSrcBmp        ; 源像素
            xor            ebx, ebx            ; 已混合的高度
            push        ebx
            xor            ecx, ecx

BLEND_BEGIN:
        push        ecx
            cmp            dword ptr, 0x00FFFFFF; 如果alpha为0,则跳过混合部分
            jna            BLEND_END

            ; 计算透明度
            xor            eax, eax
            mov            al, ubBlendAlpha    ; 获取blend alpha
            mov            edx, dword ptr
        shr            edx, 24                ; edx 获取源像素 alpha
            imul        eax, edx
            shr            eax, 8
            shl            eax, 24
            mov            edx, eax
            mov            eax, dword ptr
        and            eax, 0x00ffffff
            or            eax, edx

            cmp            pTone, 0            ; 如果为0跳过色调部分
            jna            MMX_ALPHABLEND

MMX_ALPHABLEND:
        movd        mm0,             ; 把目的像素值移入mm0寄存器的低32位
            movd            mm1, eax    ; 把源像素值移入mm1寄存器的低32位

            ; Core Begin
            pxor        mm2, mm2            ; 把MM2清0
            punpcklbw    mm0, mm2            ; src:8 bit到16 bit以容纳结果,32bit expand to 64 bit
            punpcklbw    mm1, mm2            ; dst:8 bit到16 bit以容纳结果.32bit expand to 64 bit
            movq        mm3, mm1            ; 因为要用dst的Alpha值
            punpckhwd    mm3, mm3            ; 高字移动到双字
            punpckhdq    mm3, mm3            ; 双字移动到四字,现在有八个像素的Alpha了!
            movq        mm4, mm0            ; mm4 = dst
            movq        mm5, mm1            ; mm5 = src
            psubusw        mm4, mm1            ; dst-src,饱和减,小于0为0
            psubusw        mm5, mm0            ; src-dst,饱和减,小于0为0
            pmullw        mm4, mm3            ; Alpha * (src-dst)
            pmullw        mm5, mm3            ; Alpha * (dst-src)
            psrlw        mm4, 8                ; 除以256,now mm4 get the result,(src-dst)<0 部分
            psrlw        mm5, 8                ; 除以256,now mm5 get the result,(dst-src)>0 部分
            paddusw        mm0, mm5            ; 饱和加到原图象:D=Alpha*(O-S)+S,(src-dst)<0 部分
            psubusw        mm0, mm4            ; 饱和加到原图象D=S-Alpha*(S-O),(dst-src)>0 部分
            packuswb    mm0, mm0            ; 紧缩到低32bit
            ; Core End

            movd        , mm0            ; 混合结果写进目的像素

BLEND_END:
        add            edi, 4
            add            esi, 4
            pop            ecx
            inc            ecx
            cmp            ecx, rc_w                ; 若ecx小于rc_w,则转移到上面继续混合
            jb            BLEND_BEGIN

            add            esi, nextLineOffset_src    ; 加上偏移量,使定位到下行起始处
            add            edi, nextLineOffset_dst

            pop            ebx
            inc            ebx
            push        ebx
            xor            ecx, ecx

            cmp            ebx, rc_h                ; 若ebx小于rc_h,则转移到上面继续混合
            jb            BLEND_BEGIN

            pop            eax
            pop            eax                  ; 平栈

            EMMS                                ; 因为从mm0到mm7,这些寄存器是“借用”浮点寄存器的低64位,所以每次在用完MMX指令后一定要用EMMS指令将寄存器清空
    }

secondsen 发表于 2012-10-16 14:35:23

原版,没有push pop的,编译过了,调试没毛病

    __asm
    {
        mov            edi, pDstBmp        ; 目的像素
            mov            esi, pSrcBmp        ; 源像素
            xor            ebx, ebx            ; 已混合的高度
            xor            ecx, ecx            ; 要混合的宽度

BLEND_BEGIN:
        cmp            dword ptr, 0x00FFFFFF; 如果alpha为0,则跳过混合部分
            jna            BLEND_END

            xor            eax, eax
            mov            al, ubBlendAlpha    ; 获取blend alpha
            mov            edx, dword ptr
            shr            edx, 24                ; edx 获取源像素 alpha
            imul        eax, edx
            shr            eax, 8
            shl            eax, 24
            mov            edx, eax
            mov            eax, dword ptr
            and            eax, 0x00ffffff
            or            eax, edx

            movd        mm0,             ; 把目的像素值移入mm0寄存器的低32位
            ;movd        mm1,             ; 把源像素值移入mm1寄存器的低32位
            movd            mm1, eax

            ; Core Begin
            pxor        mm2, mm2            ; 把MM2清0
            punpcklbw    mm0, mm2            ; src:8 bit到16 bit以容纳结果,32bit expand to 64 bit
            punpcklbw    mm1, mm2            ; dst:8 bit到16 bit以容纳结果.32bit expand to 64 bit
            movq        mm3, mm1            ; 因为要用dst的Alpha值
            punpckhwd    mm3, mm3            ; 高字移动到双字
            punpckhdq    mm3, mm3            ; 双字移动到四字,现在有八个像素的Alpha了!
            movq        mm4, mm0            ; mm4 = dst
            movq        mm5, mm1            ; mm5 = src
            psubusw        mm4, mm1            ; dst-src,饱和减,小于0为0
            psubusw        mm5, mm0            ; src-dst,饱和减,小于0为0
            pmullw        mm4, mm3            ; Alpha * (src-dst)
            pmullw        mm5, mm3            ; Alpha * (dst-src)
            psrlw        mm4, 8                ; 除以256,now mm4 get the result,(src-dst)<0 部分
            psrlw        mm5, 8                ; 除以256,now mm5 get the result,(dst-src)>0 部分
            paddusw        mm0, mm5            ; 饱和加到原图象:D=Alpha*(O-S)+S,(src-dst)<0 部分
            psubusw        mm0, mm4            ; 饱和加到原图象D=S-Alpha*(S-O),(dst-src)>0 部分
            packuswb    mm0, mm0            ; 紧缩到低32bit
            ; Core End

            movd        , mm0            ; 混合结果写进目的像素

BLEND_END:
        add            edi, 4
            add            esi, 4
            inc            ecx
            cmp            ecx, rc_w                ; 若ecx小于rc_w,则转移到上面继续混合
            jb            BLEND_BEGIN

            add            esi, nextLineOffset_src    ; 加上偏移量,使定位到下行起始处
            add            edi, nextLineOffset_dst

            inc            ebx
            xor            ecx, ecx

            cmp            ebx, rc_h                ; 若ebx小于rc_h,则转移到上面继续混合
            jb            BLEND_BEGIN

            EMMS                                ; 因为从mm0到mm7,这些寄存器是“借用”浮点寄存器的低64位,所以每次在用完MMX指令后一定要用EMMS指令将寄存器清空
    }

secondsen 发表于 2012-10-16 14:49:42

自己改成这样就好了。。。比顶楼简练一点了。。但是我还是看不出来顶楼的毛病出在哪里啊?

    __asm
    {
      mov            edi, pDstBmp      ; 目的像素
            mov            esi, pSrcBmp      ; 源像素
            xor            ebx, ebx            ; 已混合的高度
TWO_LOOP_BEGIN:
            push      ebx
            xor            ecx, ecx

BLEND_BEGIN:
      push      ecx
            cmp            dword ptr, 0x00FFFFFF; 如果alpha为0,则跳过混合部分
            jna            BLEND_END

            ; 计算透明度
            xor            eax, eax
            mov            al, ubBlendAlpha    ; 获取blend alpha
            mov            edx, dword ptr
      shr            edx, 24                ; edx 获取源像素 alpha
            imul      eax, edx
            shr            eax, 8
            shl            eax, 24
            mov            edx, eax
            mov            eax, dword ptr
      and            eax, 0x00ffffff
            or            eax, edx

            cmp            pTone, 0            ; 如果为0跳过色调部分
            jna            MMX_ALPHABLEND

MMX_ALPHABLEND:
      movd      mm0,             ; 把目的像素值移入mm0寄存器的低32位
            movd            mm1, eax    ; 把源像素值移入mm1寄存器的低32位

            ; Core Begin
            pxor      mm2, mm2            ; 把MM2清0
            punpcklbw    mm0, mm2            ; src:8 bit到16 bit以容纳结果,32bit expand to 64 bit
            punpcklbw    mm1, mm2            ; dst:8 bit到16 bit以容纳结果.32bit expand to 64 bit
            movq      mm3, mm1            ; 因为要用dst的Alpha值
            punpckhwd    mm3, mm3            ; 高字移动到双字
            punpckhdq    mm3, mm3            ; 双字移动到四字,现在有八个像素的Alpha了!
            movq      mm4, mm0            ; mm4 = dst
            movq      mm5, mm1            ; mm5 = src
            psubusw      mm4, mm1            ; dst-src,饱和减,小于0为0
            psubusw      mm5, mm0            ; src-dst,饱和减,小于0为0
            pmullw      mm4, mm3            ; Alpha * (src-dst)
            pmullw      mm5, mm3            ; Alpha * (dst-src)
            psrlw      mm4, 8                ; 除以256,now mm4 get the result,(src-dst)<0 部分
            psrlw      mm5, 8                ; 除以256,now mm5 get the result,(dst-src)>0 部分
            paddusw      mm0, mm5            ; 饱和加到原图象:D=Alpha*(O-S)+S,(src-dst)<0 部分
            psubusw      mm0, mm4            ; 饱和加到原图象D=S-Alpha*(S-O),(dst-src)>0 部分
            packuswb    mm0, mm0            ; 紧缩到低32bit
            ; Core End

            movd      , mm0            ; 混合结果写进目的像素

BLEND_END:
      add            edi, 4
            add            esi, 4
            pop            ecx
            inc            ecx
            cmp            ecx, rc_w                ; 若ecx小于rc_w,则转移到上面继续混合
            jb            BLEND_BEGIN

            add            esi, nextLineOffset_src    ; 加上偏移量,使定位到下行起始处
            add            edi, nextLineOffset_dst

            pop            ebx
            inc            ebx

            cmp            ebx, rc_h                ; 若ebx小于rc_h,则转移到上面继续混合
            jb            TWO_LOOP_BEGIN

            EMMS                              ; 因为从mm0到mm7,这些寄存器是“借用”浮点寄存器的低64位,所以每次在用完MMX指令后一定要用EMMS指令将寄存器清空
    }
页: [1]
查看完整版本: 还是汇编的问题