© Jo Van Hoey 2019
J. Van HoeyBeginning x64 Assembly Programminghttps://doi.org/10.1007/978-1-4842-5076-1_39

39. Hello, Windows World

Jo Van Hoey1 
(1)
Hamme, Belgium
 

In this and the following chapter, we will start assembly coding in Windows. As with Linux, it is best to install a Windows virtual machine. You can download a license for a 90-day Windows 10 trial here: https://www.microsoft.com/en-us/evalcenter/evaluate-windows-10-enterprise . Install the trial version of Windows 10, and do the updates, which can take a while.

Getting Started

Microsoft has developed its own assembler, called MASM , and it is included in Visual Studio. Being able to use Visual Studio is certainly an advantage, because it is a comprehensive development tool. The assembler instructions used in MASM are the same as those in NASM, but the assembler directives are very different. Configuring and learning to work with Visual Studio has a learning curve, depending on your previous experience as a Windows developer.

To soften the culture shock, in this book we will use NASM on Windows and use the CLI. We already know NASM on Linux from the previous chapters, which gives us a head start. However, making the switch to MASM should not be too difficult to do on your own.

If you want to develop for Windows, learning to use Visual Studio is worth the effort. On the Internet you can even find how to use NASM with Visual Studio.

Find NASM for Windows on the Internet and install it (currently:  https://www.nasm.us/pub/nasm/releasebuilds/2.14.03rc2/win64/ ). Make sure your Windows environment path variable has an entry that points to the folder where you installed NASM. See Figure 39-1. You can verify the NASM installation with nasm -v at the CLI.
../images/483996_1_En_39_Chapter/483996_1_En_39_Fig1_HTML.jpg
Figure 39-1

Windows 10 environment path variable

We will also use a version of MinGW (Minimalist GNU for Windows) , which is a set of Linux development tools ported to Windows. MinGW will allow us to use the tools make and GCC, which we have used often in the previous chapters of the book. The version you have to install is MinGW-w64. Before you start downloading and installing, if you plan to use SASM on Windows, be aware that SASM installs NASM and some MinGW-w64 tools in its own subdirectories (except make). If you manually install SASM and MingGW-w64, you will end up with double installations. In the SASM settings, you can configure SASM to use your installed versions of NASM and GCC instead of the older versions that come with SASM.

Currently you will find the download files for MinGW-w64 here: http://mingw-w64.org/doku.php/download . Choose MingW-W64-builds, download and install it, and choose x86_64 in the installation window.

Go to the Windows environment variables, and add the path to the MinGW-W64 bin folder to the environment variable path, shown in Figure 39-1. The bin folder contains GCC. After updating the path variable, go to the PowerShell CLI and type gcc -v to verify the installation.

Download the win64 version of SASM ( https://dman95.github.io/SASM/english.html ), and if you want SASM to use the new versions of NASM and GCC, modify the build settings to your freshly installed NASM and GCC. Do not forget to update the Windows environment path variable with an entry for SASM.

If you do not have a preferred text editor on Windows, install Notepad++. It is simple and provides syntax highlighting for a large number of programming languages, including assembly. And you can easily set the encoding to UTF-8, UTF-16, and so on. You can find the assembly language setting on the menu bar under Language.

It is annoying that MinGW-w64 does not have a make command but provides only ming32-make.exe, which is a long command to use. To solve this, create a make.bat file with Notepad++ (run as Administrator) containing this line:
mingw32-make.exe

Save the file in UTF-8 format in the MinGW-W64 bin folder.

Here are some hints if you struggle with Windows:
  • To open an application as administrator, right-click the application icon, and choose the option Run as administrator.

  • It is always handy to have easy access to PowerShell, the Windows CLI. To open it, type PowerShell in the search field on the taskbar at the bottom and then click Open. A PowerShell icon will appear on the taskbar; right-click this icon and choose Pin to taskbar.

  • In a window that shows icons for files or directories, press Shift and right-click at the same time, and on the menu that pops up, you can select Open PowerShell window here.

  • To show hidden files and directories, click the File Explorer icon on the taskbar. Open the View menu item and select Hidden items.

  • To find the environment variables, type environment variables in the search field on the taskbar.

Writing Some Code

Now you are ready to start coding. Listing 39-1 and Listing 39-2 show our first program.
; hello.asm
extern printf
section .data
      msg   db 'Hello, Windows World!',0
      fmt   db "Windows 10 says: %s",10,0
section .text
      global main
main:
push rbp
mov rbp,rsp
      mov   rcx, fmt
      mov   rdx, msg
      sub   rsp,32
      call  printf
      add   rsp,32
leave
ret
Listing 39-1

hello.asm

hello.exe: hello.obj
      gcc -o hello.exe hello.obj
hello.obj: hello.asm
      nasm -f win64  -g -F cv8 hello.asm -l hello.lst
Listing 39-2

makefile

There is nothing spectacular here, right? Or is there?

Well, first there is sub rsp,32 , which in Linux we used to create stack variables. With this instruction, we create shadow space on the stack before calling a function. More on that later. After the printf function executes, we restore the stack with add rsp,32, which in this case is not strictly necessary because the stack will be restored by the leave instruction. The registers we use to pass arguments to printf are different from the ones used in Linux. That is because the calling conventions in Windows are different from the calling conventions in Linux. Windows requires you to use the Microsoft x64 calling convention, while Linux wants you to use System V Application Binary Interface, also called System V ABI.

You can find an overview of the Microsoft calling convention here: https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019 . This page tends to move from time to time; if you can’t find it, search on the Microsoft site for the x64 calling convention. Here is the short version:
  • Integer arguments are passed in rcx, rdx, r8, and r9, in that order.

  • If you want to pass more arguments, you push them onto the stack.

  • Floating-point arguments are passed in the xmm0-xmm3 registers; further arguments are passed using the stack.

  • Registers rcx, rdx, r8, r9, and, additionally, rax, r10, r11, xmm4, and xmm5 are volatile, meaning that the caller has to save them if needed. The other registers are callee saved.

  • The caller needs to provide a 32-byte space on the stack (shadow space) for four function arguments to be passed to the callee, even if the callee does not take that many arguments.

  • As in Linux, the stack must be 16-byte aligned.

Figure 39-2 shows the output of our first program.
../images/483996_1_En_39_Chapter/483996_1_En_39_Fig2_HTML.jpg
Figure 39-2

hello.asm output

Debugging

If you launch GDB to debug our first program, you are in for a surprise. You can execute a number of commands, but stepping through your code will not work. You will see the following message:
Single stepping until exit from function main,
which has no line number information.
0x0000000000402a60 in printf ()

This means that GDB is of limited use here! However, SASM comes to the rescue. SASM does not seem to have this problem. In our makefile we still include the debug flags; maybe in a future version of GDB this will be solved. In the makefile we specify cv8 (Microsoft CodeView 8) as the debugging format.

Syscalls

In our example code, we used printf instead of a syscall as we did with our first Linux assembly program. There is a reason for that: you do not use syscalls in Windows. Windows has syscalls, but they are for “internal” use only. You need to use the Windows API when you want to access system resources. Of course, you can dig around in the Windows code or on the Internet to find out what the Windows syscalls are, but know that newer versions of Windows can change the use of syscalls, and that can break your code if you use them.

Summary

In this chapter, you learned about the following:
  • How to install and use NASM, SASM, and Linux development tools in Windows

  • That calling conventions in Windows are different from those in Linux

  • That it’s better not use syscalls

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.12.207