庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>程序设计>汇编语言>技巧教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

动态库的执行时间

 作者:本站收集   日期:2005-8-1 15:50:26
字号选择〖 〗/ 双击滚屏 单击停止   

此文章是针对怜香的系列专题教程"从DOS到Win32"中第8篇文章的后续,读此文之前请先阅读怜香的文章.
当程序中引用了动态库后,WINDOWS是先远行程序呢?还是先加载动态库呢?

为了搞清这个问题,我们将MyDLL.ASM和10.ASM稍作修改如下:

;================MyDLL.ASM================
;例:将EDX:EAX中的值转换成十进制输出形式字符串。
;文件名:MyDll.asm,这是动态链接库的源程序
   ;编译模式="DLL"
        .386
        .model flat,stdcall
        option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

OutEdxEax PROTO: DWORD

        .DATA
szText0 db "哈哈哈...MyDLL加载",0
szText1 db "MyDLL第一次插入进程的地址空间",0
szText2 db "MyDLL从进程的地址空间卸出",0
szText3 db "同一进程的新线程生成",0
szText4 db "同一进程的线程销毁",0
szText5 db "MyDLL的函数OutEdxEax调用成功",0

        .code

;DllEntry是动态链接库的入口,当动态链接库被加载/卸载时,
;或同一进程的线程生成/退出时,都会调用该入口函数
;当然,函数名不一定非是这个,但要和最后的End DllEntry保持一致。

DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
.if reason==DLL_PROCESS_ATTACH      动态链接库第一次插入进程的地址空间
    invoke MessageBox,NULL,addr szText1,addr szText0,MB_OK
    mov    eax,TRUE
    ret
.elseif reason==DLL_PROCESS_DETACH  动态链接库从进程的地址空间卸出
    invoke MessageBox,NULL,addr szText2,addr szText0,MB_OK
    mov    eax,FALSE
    ret
.elseif reason==DLL_THREAD_ATTACH   ;同一进程的新线程生成
    invoke MessageBox,NULL,addr szText3,addr szText0,MB_OK
    mov    reason,TRUE
    ret
.elseif reason==DLL_THREAD_DETACH   ;同一进程的线程销毁
    invoke MessageBox,NULL,addr szText4,addr szText0,MB_OK
    mov    eax,FALSE
    ret
.endif
DllEntry Endp

;将EDX:EAX中的值转换成十进制输出形式字符串,很熟悉吧,前面的例子中有的!
;比如:EDX=0,EAX=01234567H,则转换后的字符串为:
;        -> '19088743',0
OutEdxEax proc uses ebx esi edi,lpString
        mov edi,lpString    指向存放结果的地址
        mov esi,lpString
        mov ecx,10          转换成十进制
        .while eax!=0 || edx!=0
            push eax    
            mov eax,edx
            xor edx,edx
            div ecx
            mov ebx,eax
            pop eax
            div ecx
            add dl,'0'      
            mov [edi],dl    存放结果
            inc edi
            mov edx,ebx
        .endw

        mov BYTE ptr [edi],0;字符串以0为结尾
        dec edi

        .while edi>esi      结果前变后,后变前!
            mov al,[esi]
            xchg al,[edi]
            mov [esi],al
            inc esi
            dec edi
        .endw
    invoke MessageBox,NULL,addr szText5,addr szText0,MB_OK
        ret
OutEdxEax endp
end DllEntry


;================10.ASM================
;例:文件名:10.asm
;调用MyDll.dll,看能否正常工作

        .386
        .model flat,stdcall
        option casemap:none

include windows.inc

include mydll.inc
include masm32.inc
include user32.inc
include kernel32.inc

includelib mydll.lib
includelib masm32.lib
includelib user32.lib
includelib kernel32.lib


        .DATA
szText  db "哈哈哈...10.exe运行",0

        .data?
CharOut db 100 dup(?)

        .code
start:
    invoke MessageBox,NULL,addr szText,addr szText,MB_OK
    mov edx,12345678h
    mov eax,87654321h
    invoke OutEdxEax,addr CharOut   ;用我们自己的程序转换!
    invoke StdOut,addr CharOut
    invoke ExitProcess,NULL  
    end start


好了,将如上修改存盘,编译运行。看到啥啦?似乎也明白了些东东哈!
对啦,我们可以看到:此时WINDOWS先加载动态库,再运行程序。


如果我们把10.ASM再作如下修改,并存盘为10_01.ASM


;================10_01.ASM================
;文件名:10_01.asm
;调用MyDll.dll,看能否正常工作

        .386
        .model flat,stdcall
        option casemap:none

include windows.inc
include masm32.inc
include user32.inc
include kernel32.inc

includelib masm32.lib
includelib user32.lib
includelib kernel32.lib


        .DATA
szText        db "哈哈哈...10_01.exe运行",0
MyDllFileName db "e:\masm32\xlfancy\mydll.dll",0
CallFuncName  db "OutEdxEax",0

        .data?
CharOut       db 100 dup(?)
MyDLLHandle   dd ?
OutEdxEaxAddr dd ?

        .code
start:
    invoke MessageBox, NULL, addr szText, addr szText, MB_OK

    invoke OutEdxEax, addr CharOut   ;用我们自己的程序转换!

    invoke LoadLibrary, offset MyDllFileName
    or     eax, eax
    jz     ExitPro
    mov    MyDLLHandle, eax
    invoke GetProcAddress, eax, offset CallFuncName
    or     eax, eax
    jz     FreeLib
    mov    OutEdxEaxAddr, eax
    lea    eax, CharOut
    push   eax
    mov    edx, 12345678h
    mov    eax, 87654321h
    call   OutEdxEaxAddr

    invoke StdOut,addr CharOut

FreeLib:
    invoke FreeLibrary, MyDLLHandle

ExitPro:
    invoke ExitProcess, NULL  
    end start


编译运行。这时看到啥啦?咦,此时WINDOWS先运行程序,再加载动态库。

以上就是动态库的两种不同的调用方法。经过这两种不同的调用方法,
我们可以粗略地认识和理解WINDOWS加载EXE和DLL的次序和不同。(狗屁!其实我根本就#@$#%#%$%)



以上都在本机编译通过,可就是看不到结果。(折腾了半天,不只所以,JMP...)
不管了,没犯路线错误就行...(马马乎乎,也敢贴出来$%$#%$%%&%&^%,"砰",怎么有砖打到脑袋上?¥#¥%¥%……%)

上一篇:矛与盾的较量——CRC原理篇    下一篇:驻留exe文件  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-8-1 15:50:26
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿