在64位Windows上设置汇编程序 [英] Setting up an assembler on 64-bit Windows

查看:83
本文介绍了在64位Windows上设置汇编程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的需要这里的帮助.我已经在网上搜索了大约2天,但似乎找不到我遇到的问题的答案.

I really need some help here. I've been searching online for about 2 days now and can't seem to find an answer to the problems that I got.

  1. 我下载了nasm并安装了它,它似乎可以工作,但是我似乎找不到在Windows 64bit上运行的任何示例代码(如果您可以为我或其他人创建一个简单的hello world示例,那就太好了. ). (以及如何编译)

  1. I downloaded nasm and installed it it seems to work but I can't seem to find any example code that works on windows 64bit (it would be awesome if you could make a simple hello world example for me or something). (And how to compile it)

我如何将.o文件转换为.exe?

How would I turn the .o file into a .exe?

我将如何访问屏幕或GPU内存(我认为)以在屏幕上打印内容(例如某种控制台应用程序)?

How would I accesses the screen or gpu memory (I think) to print stuff on the screen (like some sort of console application)?

推荐答案

在Windows下使用NASM进行汇编编程时,需要考虑以下几点:

There a a few things to consider when programming in assembly using NASM under Windows:

  1. NASM只是一个汇编程序
    需要链接器来创建可执行文件.

  1. NASM is just an assembler
    A linker is needed to create an executable.

Windows API被实现为用户空间库.
该库并不完全在用户空间中,某些功能是跨界的,但是应用程序的接口是一组DLL,最著名的是:kernel32.dll,user32.dll等.

Windows API are implemented as a user space library.
The library is not entirely in user space, some functions cross the boundary, but the interface to the application is a set of DLL, most notably: kernel32.dll, user32.dll and so on.

Windows的可执行文件可以具有不同的子系统.
其中, IMAGE_SUBSYSTEM_WINDOWS_GUI IMAGE_SUBSYSTEM_WINDOWS_CUI 最常用,前者由创建窗口的应用程序使用,后者由使用控制台 1 的应用程序使用sup>.

Windows' executables can have different subsystems.
Among the others the IMAGE_SUBSYSTEM_WINDOWS_GUI and IMAGE_SUBSYSTEM_WINDOWS_CUI are the most used, the former being used by applications that create windows and the latter by applications that use a console1.


链接器使用汇编程序生成的 COFF 对象(.obj)文件,使用一组库定义(.lib)并执行以下重要步骤:


The linker takes to COFF object (.obj) file generated by the assembler, takes a set of library definitions (.lib) and perform these important steps:

  1. 它可以解决对在目标文件中找到的外部函数的调用.
    标记为 external 的功能旨在在库定义之一中找到,然后链接程序将调用指令固定为指向在运行时将找到功能地址的位置.

  1. It resolves the call to external functions found in the object file.
    A function marked as external is meant to be found in one of the library definition, the linker then fixes the call instruction to point to a location where the address of the function will be found at run-time.

它将依赖项库添加到最终的可执行文件中.
这是借助于 PE文件格式完成的,基本上是 F (如果在库 L 上找到),则将 L 以及写 F 地址的位置添加到依赖项列表. br> 加载程序将完成剩下的工作.

It add the dependency libraries to the final executable.
This is done with the help of the PE file format, basically if F if found on the library L then L is added to the dependencies list along with a location where to write the address of F.
The loader will do the rest.

实际上,链接要复杂得多.
它还负责设置各种PE标志和设置,包括子系统和入口点.

The linking is actually more complex than that.
It is also responsible for setting the various PE flags and settings, including the subsytem and the entrypoint.

要在需要时使用NASM编写可执行文件,请执行以下操作:

To write an executable using NASM with need:

  1. 链接器.
  2. 一组库定义.

这些可以在 Windows SDK 2 .

在此示例中将使用的链接器是Microsoft LINK链接器.

The linker we will use in this example is the Microsoft LINK linker.

正如@CodyGray在其评论中指出的那样(引用是因为我很懒):

As @CodyGray pointed out in its comment (quoting because I'm lazy):

您链接的SDK的Windows 7版本确实包含所有构建工具. Windows 8 SDK已更改,并且不再附带命令行构建工具,从而迫使您下载Visual Studio程序包

The Windows 7 version of the SDK that you linked does include all of the build tools. The Windows 8 SDK changed and no longer ships with the command-line build tools, forcing you to download a Visual Studio package


有了这些工具,就可以开始编程了.
我们将使用
WriteFile 将字符串写入标准输出(就像我们在Linux汇编中那样).
必须使用


Once we have the tools, we can start programming.
We will use WriteFile to write a string to the standard output (like we would in Linux assembly).
The handler to the standard output must be retrieved with GetStdHandle though.

在Windows中,即使没有链接的CRT(C运行时),也可以使用ret退出进程(即,在裸进程中).

In Windows you can exit a process with a ret even with no CRT (C run-time) linked (i.e. in a bare process).

我不会解释Window 64 ABI或64位编程的棘手问题.

I won't explain the Window 64 ABI nor the trickery of programming in 64-bit.

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位目标文件:

To create an executable from this source, we first assemble it into a 64-bit object file:

nasm -fwin64 hello.asm -o hello.obj

然后将其链接到 kernel32 库(我们唯一需要的库):

then we link it against the kernel32 library (the only one we need):

link /MACHINE:X64 /SUBSYSTEM:CONSOLE /OUT:hello.exe /NODEFAULTLIB /ENTRY:main kernel32.lib hello.obj

CLI开关非常简单, NODEFAULTLIB 避免与Microsoft CRT MSVCVRXX.lib 链接. 这些是在此示例中构建可执行文件所需的最少开关.

the CLI switches are pretty straightforward, NODEFAULTLIB avoid linking with MSVCVRXX.lib, the Microsoft CRT. Those are the minimal switches necessary to build an executable in this example.

我假设您足够聪明,可以在发出上述命令时解决路径问题,尤其是您可以告诉 link 在哪里可以找到lib文件.
对于此示例,我只是从SDK安装文件夹中复制了它们.

I assume you are smart enough to fix the path issues when issuing the commands above, particularly you can tell link where to find the lib files.
For this example I just copied them from the SDK installation folder.

如其他答案中所建议,您可以使用链接器附带的其他汇编器.
另一个可能的开发环境是使用 gcc (在 cygwin 内部或作为 mingw )来执行链接器步骤.

As proposed in other answers, you can use other assemblers that may came with a linker.
Another possible developing environment is to use gcc (either inside cygwin or as mingw) to perform the linker step.

1 在这种情况下,Windows将自动为应用程序创建一个控制台并适当地设置标准处理程序. GUI应用程序也可以重新创建控制台(或多个控制台),因此 IMAGE_SUBSYSTEM_WINDOWS_GUI 必须用作默认情况下没有控制台".

1 In this case Windows automatically create a console for the application and set the standard handlers appropriately. GUI application can recreate the console too (or more than one), so IMAGE_SUBSYSTEM_WINDOWS_GUI must be intended as "No console by default".

2 链接的版本是Google的第一个结果,要花更多的时间来寻找合适的版本.另外,我不确定Windows SDK中是否有链接器,或者您需要下载Visual Studio.

2 The version linked is the first Google result, invest more time in finding a suitable version. Also, I'm not sure if there is a linker in the Windows SDK or you need to download a Visual Studio instead.

这篇关于在64位Windows上设置汇编程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆