我真的需要一些帮助。我现在已经在网上搜索了大约2天,似乎找不到我遇到的问题的答案。
我下载了nasm并安装它似乎工作但我似乎无法找到适用于Windows 64bit的任何示例代码(如果你能为我做一个简单的hello world示例,那将会很棒或者其他的东西)。 (以及如何编译它)
如何将.o文件转换为.exe?
我如何访问屏幕或gpu内存(我认为)在屏幕上打印内容(比如某种控制台应用程序)?
答案 0 :(得分:4)
在Windows下使用NASM进行汇编编程时需要考虑以下几点:
NASM只是一个汇编程序
需要链接器来创建可执行文件。
Windows API实现为用户空间库 库不是完全在用户空间,有些函数跨越边界,但应用程序的接口是一组DLL,最值得注意的是:kernel32.dll,user32.dll等。
Windows'可执行文件可以有不同的子系统 其中 IMAGE_SUBSYSTEM_WINDOWS_GUI 和 IMAGE_SUBSYSTEM_WINDOWS_CUI 是最常用的,前者由创建窗口的应用程序使用,后者由使用控制台 1的应用程序
链接器获取汇编程序生成的 COFF 对象(.obj)文件,获取一组库定义(.lib)并执行以下重要步骤:
它解析对目标文件中找到的外部函数的调用。
标记为 external 的函数意味着在其中一个库定义中找到,然后链接器将调用指令固定为指向将在运行时找到函数地址的位置。
它将依赖库添加到最终的可执行文件中。
这是在PE file format的帮助下完成的,基本上如果 F ,如果在库 L 上找到,那么 L 被添加到依赖项列表以及写入 F 地址的位置
装载机将完成其余工作。
链接实际上比这更复杂 它还负责设置各种PE标志和设置,包括子系统和入口点。
使用需要的NASM编写可执行文件:
这些可以在Windows SDK 2 中找到。
我们将在此示例中使用的链接器是Microsoft LINK链接器。
正如@CodyGray在其评论中指出的那样(引用因为我很懒):
您链接的SDK的Windows 7版本确实包含所有构建工具。 Windows 8 SDK已更改,不再附带命令行构建工具,强制您下载Visual Studio软件包
有了这些工具,我们就可以开始编程了 我们将使用WriteFile将字符串写入标准输出(就像在Linux程序集中一样) 必须使用GetStdHandle检索标准输出的处理程序。
在Windows中,您可以使用ret
退出流程,即使没有链接CRT(C运行时)(即在裸流程中)。
我不会解释Window 64 ABI,也不会解释64位编程的技巧。
BITS 64
DEFAULT REL ;RIP relative addressing by default
GLOBAL main ;Main must be visible to the linker
;Function the linker will look for in other modules (libs or objs)
EXTERN WriteFile
EXTERN GetStdHandle
STD_OUTPUT_HANDLE EQU -11
SECTION .data
strHelloWorld db "Hello world!", 13, 10, 0
lenHelloWorld dd $-strHelloWorld
hOut dd 0 ;Will store STDOUT handler
SECTION .text
main:
sub rsp, 30h ;20h (Home space) + 10h (params)
;Get STDOUT handler (Handler are 32-bit values)
mov ecx, STD_OUTPUT_HANDLE
call GetStdHandle
mov DWORD [hOut], eax ;Useless as now, for future reuse
;Write strHelloWorld to STDOUT
mov ecx, eax
lea rdx, [strHelloWorld]
mov r8d, DWORD [lenHelloWorld]
xor r9, r9
mov QWORD [rsp+20h], r9
call WriteFile
add rsp, 30h
ret
要从此源创建可执行文件,我们首先将其组装到64位目标文件中:
nasm -fwin64 hello.asm -o hello.obj
然后我们将它与 kernel32 库(我们唯一需要的)链接起来:
link /MACHINE:X64 /SUBSYSTEM:CONSOLE /OUT:hello.exe /NODEFAULTLIB /ENTRY:main kernel32.lib hello.obj
CLI开关非常简单, NODEFAULTLIB 避免与 MSVCVRXX.lib (Microsoft CRT)链接。 这些是在此示例中构建可执行文件所需的最小开关。
我认为您在发布上述命令时足够聪明,可以解决路径问题,尤其是您可以告诉 link 在哪里找到lib文件。
对于此示例,我只是从SDK安装文件夹中复制它们。
正如其他答案中所提出的,您可以使用链接器附带的其他汇编程序 另一种可能的开发环境是使用 gcc (在 cygwin 内部或作为 mingw )来执行链接器步骤。
1 在这种情况下,Windows会自动为应用程序创建一个控制台并相应地设置标准处理程序。 GUI应用程序也可以重新创建控制台(或多个),因此 IMAGE_SUBSYSTEM_WINDOWS_GUI 必须打算为“默认情况下没有控制台”。
2 链接的版本是Google的第一个结果,投入更多时间寻找合适的版本。另外,我不确定Windows SDK中是否有链接器,或者您需要下载Visual Studio。
答案 1 :(得分:1)
下载Flat Assembler。(下载 - >用于Windows的平面汇编程序)
提取拉链。
转到'examples / win64 / pe64demo /'
打开'pe64demo.exe'
(源代码在'pe64demo.asm')