首页
社区
课程
招聘
[求助]为什么程序运行的很慢
发表于: 2009-2-8 21:31 4317

[求助]为什么程序运行的很慢

2009-2-8 21:31
4317
这是书上的一个C写的随机显示矩形的例子,里面调用了C库函数rand().例子显示的飞快.
我用汇编改写了一下.变得很慢,如果把随机数函数改成C库函数rand(),就会变快,看来是随机数函数的问题,但是我的随机数函数很简单啊,为什么会慢呢?

.386
.model flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include gdi32.inc
includelib gdi32.lib
include c_stdlib.inc
includelib c_msvcrt.lib

WinMain proto :dword,:dword,:dword,:dword
DrawRectangle proto :dword
myRand proto :dword,:dword

RGB macro red,green,blue
        mov ah,blue
        shl eax,8
        mov ah,green
        mov al,red
endm

.data
szAppName db 'randrect',0  

.data?
hInstance dd ?
hWinMain dd ?
cxClient dd ?
cyClient dd ?

.code
start:
        invoke GetModuleHandle,NULL
        mov hInstance,eax
        invoke WinMain,hInstance,NULL,NULL,NULL
        invoke ExitProcess,NULL

WinMain proc uses edi esi ebx,hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:dword,CmdShow:dword
        local wc:WNDCLASSEX
        local msg:MSG

        mov wc.cbSize,sizeof wc
        mov wc.lpfnWndProc,offset WndProc
        mov wc.lpszClassName,offset szAppName
        mov wc.lpszMenuName,NULL
        mov eax,hInstance
        mov wc.hInstance,eax
        mov wc.style,CS_VREDRAW or CS_HREDRAW
        mov wc.cbWndExtra,NULL
        mov wc.cbClsExtra,NULL
        invoke LoadIcon,NULL,IDI_APPLICATION
        mov wc.hIcon,eax
        mov wc.hIconSm,eax
        invoke LoadCursor,NULL,IDC_ARROW
        mov wc.hCursor,eax
        invoke GetStockObject,WHITE_BRUSH
        mov wc.hbrBackground,eax
        invoke RegisterClassEx,addr wc
        invoke CreateWindowEx,NULL,offset szAppName,NULL,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,\
                        CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL
        mov hWinMain,eax
        invoke ShowWindow,hWinMain,SW_SHOWNORMAL
        invoke UpdateWindow,hWinMain

        .while TRUE
                invoke PeekMessage,addr msg,NULL,0,0,PM_REMOVE
                .if eax
                        .break .if (msg.message==WM_QUIT)
                        invoke TranslateMessage,addr msg
                        invoke DispatchMessage,addr msg
                .else
                        invoke DrawRectangle,hWinMain
                .endif
        .endw
        mov eax,msg.wParam
        ret
WinMain endp

WndProc proc uses edi esi ebx,hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
       
        .if uMsg==WM_DESTROY
                invoke PostQuitMessage,NULL
        .elseif uMsg==WM_SIZE
                mov eax,lParam
                shr eax,16
                mov cyClient,eax
                mov eax,lParam
                and eax,0ffffh               
                mov cxClient,eax       
        .else
                invoke DefWindowProc,hWnd,uMsg,wParam,lParam
                ret
        .endif
        xor eax,eax
        ret
WndProc endp

DrawRectangle proc uses ebx edi esi,hWnd:HWND
        local hdc:HDC
        local hBrush
        local rect:RECT
        local tmp1
        local tmp2
        local tmp3
        local tmp4
        local tmp5:byte
        local tmp6:byte
        local tmp7:byte

        .if (cxClient==0||cyClient==0)
                ret
        .endif

        ;COMMENT!
        invoke myRand,0,cxClient       
        mov tmp1,eax
        invoke myRand,0,cyClient
        mov tmp2,eax
        invoke myRand,0,cxClient
        mov tmp3,eax
        invoke myRand,0,cyClient
        mov tmp4,eax
        ;!

        COMMENT!
        ;rand()%cxClient,rand()%cyClient
        ;使用C库函数rand()取得随机数
        invoke rand
        xor edx,edx
        div cxClient
        mov tmp1,edx
        invoke rand
        xor edx,edx
        div cyClient
        mov tmp2,edx
        invoke rand
        xor edx,edx
        div cxClient
        mov tmp3,edx
        invoke rand
        xor edx,edx
        div cyClient
        mov tmp4,edx
        !       
       
        invoke SetRect,addr rect,tmp1,tmp2,tmp3,tmp4

        COMMENT!       
        invoke myRand,0,256
        mov tmp5,al
        invoke myRand,0,256
        mov tmp6,al
        invoke myRand,0,256
        mov tmp7,al       
        !

        ;COMMENT!
        ;使用C库函数rand()取得随机数
        mov ebx,256
        invoke rand
        xor edx,edx
        div ebx
        mov tmp5,dl
        invoke rand
        xor edx,edx
        div ebx
        mov tmp6,dl
        invoke rand
        xor edx,edx
        div ebx
        mov tmp7,dl
        ;!

        RGB tmp5,tmp6,tmp7       
        invoke CreateSolidBrush,eax

        mov hBrush,eax
        invoke GetDC,hWnd
        mov hdc,eax
        invoke FillRect,hdc,addr rect,hBrush
        invoke ReleaseDC,hWnd,hdc
        invoke DeleteObject,hBrush

        ret
DrawRectangle endp

myRand proc uses ebx  min:dword,max:dword   
    mov ebx,max
    sub ebx,min   
    invoke GetTickCount
    xor edx,edx
    div ebx
    add edx,min
    mov eax,edx

     ret
myRand endp

end start

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
2
; C的Rand函数内部没有调用其他函数,所以速度上比较快。你的函数内部每次都要调用一下GetTickCount,所以可能比较慢吧。
2009-2-8 22:22
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
3
; 改编自VC的rand和老罗的代码。
_srand proc seed:DWORD
  ifndef holdrand
    .data
      holdrand dd ?
     .code
  endif
  push seed
  pop holdrand
  ret
_srand endp

_rand proc min:DWORD, max:DWORD
  ifndef holdrand
    .data
      holdrand dd ?
     .code
  endif
  mov eax,holdrand
  mov ecx,214013
  mul ecx
  add eax,2531011
  mov holdrand,eax
  mov ecx,max
  sub ecx,min
  inc ecx
  xor edx,edx
  div ecx
  add edx,min
  mov eax,edx
  ret
_rand endp
2009-2-8 22:51
0
雪    币: 190
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
太感谢了,用了 _rand proc min:DWORD, max:DWORD 果然变得飞快.
我还想请问下
.data
      holdrand dd ?
.code
这段的作用是取得随机数种子吧,像这样在代码段中定义未初始化的变量是系统随机赋值的吗?
另外如果我把holdrand改成未初始化的局部变量,很奇怪矩形无法达到显示区域的四个角落.
未初始化的局部变量应该也是系统随机赋值的吧.
还有mov holdrand,eax这句的作用是什么?
2009-2-9 10:47
0
游客
登录 | 注册 方可回帖
返回
//