幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3685|回复: 2

[通用编程] 还是汇编的问题

[复制链接]

550

主题

9116

帖子

214748万

积分

超级版主

如同神一般的存在,腿神!拖后腿的神~~

Rank: 8Rank: 8

积分
2147483647
发表于 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[esi], 0x00FFFFFF; 如果alpha为0,则跳过混合部分
            jna            BLEND_END

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

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

MMX_ALPHABLEND:
        movd        mm0, [edi]            ; 把目的像素值移入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            ; 饱和加到原图象=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        [edi], 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指令将寄存器清空
    }
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
回复

使用道具 举报

550

主题

9116

帖子

214748万

积分

超级版主

如同神一般的存在,腿神!拖后腿的神~~

Rank: 8Rank: 8

积分
2147483647
 楼主| 发表于 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[esi], 0x00FFFFFF; 如果alpha为0,则跳过混合部分
            jna            BLEND_END

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

            movd        mm0, [edi]            ; 把目的像素值移入mm0寄存器的低32位
            ;movd        mm1, [esi]            ; 把源像素值移入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            ; 饱和加到原图象=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        [edi], 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指令将寄存器清空
    }
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
回复 支持 反对

使用道具 举报

550

主题

9116

帖子

214748万

积分

超级版主

如同神一般的存在,腿神!拖后腿的神~~

Rank: 8Rank: 8

积分
2147483647
 楼主| 发表于 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[esi], 0x00FFFFFF; 如果alpha为0,则跳过混合部分
            jna            BLEND_END

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

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

MMX_ALPHABLEND:
        movd        mm0, [edi]            ; 把目的像素值移入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            ; 饱和加到原图象=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        [edi], 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指令将寄存器清空
    }
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2024-3-29 03:05 , Processed in 0.019138 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表