加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

编写Windows x86程序集

发布时间:2020-12-14 05:26:02 所属栏目:Windows 来源:网络整理
导读:我想用x86汇编为 Windows编写简单的程序(控制台输入/输出),主要是因为我只是好奇.如果有人能指出我正确的方向,那就太好了.我已经对一些更简单的x86指令,寄存器的功能等有了相当好的理解,但对于程序如何与操作系统连接并使用标准输入和输出仍然是一个谜.我知
我想用x86汇编为 Windows编写简单的程序(控制台输入/输出),主要是因为我只是好奇.如果有人能指出我正确的方向,那就太好了.我已经对一些更简单的x86指令,寄存器的功能等有了相当好的理解,但对于程序如何与操作系统连接并使用标准输入和输出仍然是一个谜.我知道这些东西与advapi32.dll和kernel32.dll这样的库有关,并且有相关的静态库.lib文件,它们使编译器能够使用这些动态链接的库,但除此之外我不知道这是怎么回事发生.我甚至模糊C语言中的头文件如何使用.lib文件.

解决方法

也许最简单的方法是建立一些简单的程序,让你从那里推断出来.首先,您需要一些源代码:

.386
.MODEL flat,stdcall

; This is what would come from a header -- a declaration of a the Windows function:
MessageBoxA PROTO near32 stdcall,window:dword,text:near32,windowtitle:near32,style:dword

.stack 8192

.data
message db "Hello World!",0
windowtitle   db "Win32 Hello World.",0

.code
main proc
        invoke MessageBoxA,near32 ptr message,near32 ptr windowtitle,0
        ret
main endp
        end main

要构建它,我们会调用masm:

ml hello32.asm -link -subsystem:windows user32.lib

这告诉它要汇编的文件,当它链接时,告诉它将其链接为Windows子系统(主要替代方案是-subsystem:console)并链接user32.lib.后者为我们提供了MessageBoxA的定义.

写入控制台的类似程序(奇怪的是)稍微复杂一点:

.386
.MODEL flat,stdcall

getstdout = -11

WriteFile PROTO NEAR32 stdcall,
        handle:dword,
        buffer:ptr byte,
        bytes:dword,
        written: ptr dword,
        overlapped: ptr byte

GetStdHandle PROTO NEAR32,device:dword

ExitProcess PROTO NEAR32,exitcode:dword

.data
message db "Hello World!",13,10
msg_size dd $- offset message

.data?
written  dd ?

.code
main proc   
    invoke GetStdHandle,getstdout

    invoke WriteFile,
           eax,
           offset message,
           msg_size,
           offset written,
           0

    invoke ExitProcess,0
main endp
        end main

构建几乎是相同的,除了它使用控制台,因此我们指定控制台子系统,我们正在使用的函数在内核中定义:

ml hello_console.asm -link -subsystem:console kernel32.lib

标头将包含我在上面给出的MessageBoxA,GetStdHandle,WriteFile等的声明的等价物.每个标头通常会有更多的声明 – 例如,kernel32中的所有函数可能都在一个标题中.

对于图书馆来说,所涉及的机制有些牵连,但大多不相关.要完成工作,请查看(例如)MSDN,并查看要链接的库,并在命令行中添加它.

更复杂的解释是,至少当您链接到静态库时,它只是找到您调用的任何函数,并将每个函数的副本放入您的可执行文件/ DLL中.如果(如上所述)你正在使用DLL中的代码,它基本上只是将一条记录放入可执行文件中,该记录告诉它所依赖的DLL中的函数.然后,当你加载/运行程序时,加载器会查找你的程序所依赖的所有DLL,并加载它们(当然也可以递归地加载它们所依赖的任何东西).然后加载器修复这些引用,因此DLL中函数的引用将填入该DLL中为该函数分配的任何地址.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读