Introduction to Windows X64 assembly

Introduction to Windows X64 assembly (1)
tankaiha

    recently came into contact with some knowledge of 64-bit assembly. Here is a summary. One is a review of the stage of learning, and the other is that it is helpful for novice 64-bit assembly. I am also new to this area of ​​knowledge. There must be something wrong in the text.
The title of the article contains the main contents of the four aspects of this article:
(1) Windows: This article is the assembler design under the windows environment, the debugging environment is Windows Vista 64-bit version, all call the windows API.
(2) X64: This article discusses x64 assembly, where x64 represents AMD64 and Intel's EM64T, but does not include IA64. As for the difference between the three, you can search for yourself.
(3) Assembly: As the name implies, the programming language discussed in this article is assembly, and 64-bit programming in other high-level languages ​​does not belong to the discussion category.
(4) Entry: Since it is an entry, it will not be complete. First, there is a lot of knowledge in the article that just points to the end, and more in-depth study is left for future hard work. Second, it is convenient for novices like me who are new to x64 assembly.
        The debugging environment of all the code in this article: Windows Vista x64, Intel Core 2 Duo.

1. Establish development environment
1.1 The choice of compiler
    corresponds to different x64 assembly tools, and the development environment is also different. The most common one is Microsoft's MASM. In the x64 environment, the corresponding compiler has been renamed to ml64.exe, which was released with Visual Studio 2005. Therefore, if you are a loyal fan of Microsoft, you can install VS2005 directly. When running, just open the corresponding 64-bit command line window (Figure 1) and you can compile with ml64.


    The second recommended compiler is GoASM, which contains three files: GoASM compiler, GoLINK linker and GoRC resource compiler, and comes with Include directory. Its biggest advantage is that it is small, and there is no need to install a few G VS in order to learn 64-bit assembly. Therefore, the code in this article is compiled under GoASM.

    The third Yasm, because I'm not familiar with it, so I won't repeat them. Interested friends test it by themselves.
Different compilers have different syntax, which will be described below.

1.2 IDE selection
    Search the Internet and find no IDE that supports asm64, not even an editor. Therefore, the easiest way is to modify the masm syntax file of EditPlus, which is also the method I used, at least you can get syntax highlighting. Of course, if you are too lazy to use it, then use notepad.
    Without an IDE, you have to manually input a lot of parameters and options every time you compile, just do a batch process.

1.3 Hardware and operating system The
    hardware requirement is a 64-bit CPU. The operating system must also be 64-bit. If a 32-bit operating system is installed on a 64-bit CPU, the program cannot be run even if the compilation is successful.

2. The change of register
    assembly is the language that directly deals with registers, so the hardware has a great influence on the language. Let's take a look at what is more and what has changed in the hardware of x64 compared to x32 (Figure 2).


    X64 has 8 more general registers: R8, R9, R10, R11, R12, R13, R14, R15, of course, they are all 64-bit. In addition, eight 128-bit XMM registers have been added, but they are usually not needed.
    The original registers in X32 are all extended to 64 bits in X64, and the first letter of the name is changed from E to R. But we can still call 32-bit registers in 64-bit programs, such as RAX (64-bit), EAX (low 32), AX (low 16-bit), AL (low 8-bit), AH (8 to 15-bit) Correspondingly, there are R8, R8D, R8W and R8B. However, do not use registers such as AH in the program, because this usage on AMD CPUs will conflict with certain instructions.

3. The first x64 assembler In
    this section, we begin to write our first x64 assembler. Before that, let me talk about the changes in the calling convention.
3.1 API calling method
    Put the Calling convention in the first talk, which represents its importance. In 32-bit assembly, when we call an API, we use stdcall, which has two characteristics: one is that all parameters are put on the stack and passed through the vertebral stack; the second is that the called API is responsible for the recovery of the stack pointer (ESP), We don't need to add esp, 14h after calling MessageBox, because MessageBox has been restored.
In x64 assembly, both aspects have changed. One is that the first four parameter analyses are passed through four registers: RCX, RDX, R8, R9. If there are more parameters, they are passed through the vertebra stack. The second is that the caller is responsible for the allocation and recycling of the stack space.
    Below is a piece of code, the function is to display a simple MessageBox, pay attention to the operation of RSP:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

;示例代码1.asm

;语法:GoASM

DATA SECTION

text     db 'Hello x64!', 0

caption  db 'My First x64 Application', 0

 

CODE SECTION

START:

sub rsp,28h

xor r9d,r9d

lea r8, caption

lea rdx, text

xor rcx,rcx

call MessageBoxA

add rsp,28h

ret



    This code is compiled in GoASM. The instruction part of GoASM is similar to ML64. The key is that some macros have different definitions. For example, the .code in masm becomes CODE SECTION here. Let me talk about the difference below, compile first. Compiling in GoASM is divided into two steps:
(1) Compiling: goasm / x64 1.asm
(2) Linking: golink 1.obj user32.dll
    If something is normal, the content of Figure 3 should be displayed on the command line.


    Run it, our first 64-bit windows program will run.


    Another feature of GoASM is the support of macros: ARG and INVOKE. Using these two macros can save programmers from operating the vertebra stack themselves. But for beginners, it is better to master from the basics. The following piece of code has the same function MASM code, pay attention to see the difference. ML64 still does not support macros, so every step of the work must be done by yourself.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

;示例代码2.asm

;语法:ML64

extrn MessageBoxA: proc

 

.data

text     db 'Hello x64!', 0

caption  db 'My First x64 Application', 0

 

.code

Main proc

sub rsp,28h

xor r9d,r9d

lea r8, caption

lea rdx, text

xor rcx,rcx

call MessageBoxA

add rsp,28h

ret

 

Main ENDP

end



    编译这段代码的命令行是:ml64 2.asm /link /subsystem:windows /entry:Main user32.lib。如果正常,应该如图5显示那样。


    很有意思吧,在64位系统下,我们仍然调用user32的API。可能是名称用习惯了,微软自己都懒得改了吧。

3.2        64位的椎栈
    代码中还有一处值得注意,那就是sub rsp,28h和add rsp,28h。28h这个数值是怎么来的呢?
首先,x64中椎栈被扩展为64位;其次,我们在调用MessageBoxA时,要给四个参数外加一个返回地址留空间,因此8(位)*5=40=28h。
    另外一些小问题要注意,AMD64不支持push 32bit寄存器的指令,最好的方法就是push和pop都用64位寄存器。EM64T如何?看了下Intel的开发手册,各个指令都分三种情况:纯32位、纯64位和32与64位混合。下面是手册的片段:

Opcode*      Instruction        64-Bit Mode       Compat/Leg Mode      Description
FF /6         PUSH r/m16         Valid                 Valid            Push r/m16.
FF /6         PUSH r/m32         N.E.                  Valid            Push r/m32.
FF /6         PUSH r/m64         Valid                  N.E.           Push r/m64.
Default operand size 64-bits.

    没别的好方法,使用中多注意,尽量在64位程序中保用64位寄存器。

4.        一些参考资料
    写完了第一个hello world,本文就此打住。本还想写一些内容,但掌握不深,留待下回吧。感觉有些资料不得不在第一篇文章中放出来,因为它们是现有学习x64汇编的最好教材了,文中很多代码和知识点也来自于这些资料。
(1)《Moving to Windows x64》,出自:http://www.ntcore.com/Files/vista_x64.htm
(2)GoASM的帮助文档,目前最好的64位汇编教程。出自:www.jorgon.freeserve.co.uk
(3)《开始进行 64 位 Windows 系统编程之前需要了解的所有信息》,出自:http://www.microsoft.com/china/MSDN/library/Windev/64bit/issuesx64.mspx
(4)来自CodeGurus的两篇文章
《Assembler & Win64》,
http://www.codegurus.be/codegurus/Programming/assembler&win64_en.htm
《bout RIP relative addressing》
http://www.codegurus.be/codegurus/Programming/riprelativeaddressing_en.htm
(5)AMD开发手册
(6)Intel开发手册,注意是新的《ntel® 64 and IA-32 Architectures software Developer’s Manual》

发布了54 篇原创文章 · 获赞 89 · 访问量 68万+

Guess you like

Origin blog.csdn.net/ayang1986/article/details/104291349