top of page

Mysite 13 Group

Public·39 members

Tips and Tricks for Windows 64bit Assembly Programming with Zipl




Article with HTML formatting


Windows 64bit Assembly Tool Zipl: What Is It and How to Use It




Introduction




If you are a programmer who likes to get close to the hardware, you probably have some experience with assembly language. Assembly language is a low-level language that directly corresponds to the instructions that a processor can execute. It gives you full control over the performance, optimization, and functionality of your code.




Windows 64bit Assembly Tool Zipl


Download: https://www.google.com/url?q=https%3A%2F%2Fgohhs.com%2F2ulgLq&sa=D&sntz=1&usg=AOvVaw3AxbeTN67UFeZi4U0CgluE



However, not all assembly languages are the same. Different processors have different instruction sets, registers, modes, and conventions. For example, if you want to write assembly code for Windows 64bit systems, you need to use a different syntax and tools than for Windows 32bit systems.


One of the tools that can help you write and compile Windows 64bit assembly code is Zipl. Zipl is a free, open-source assembler that supports both Intel and AT&T syntaxes. It has many features and benefits that make it a powerful and convenient tool for Windows 64bit assembly programming.


How to Install Zipl on Windows 64bit




To install Zipl on your Windows 64bit system, you need to follow these steps:



  • Download the latest version of Zipl from its official website. You can choose between a zip file or an installer file.



  • Extract the zip file or run the installer file. You will see a folder called "zipl" that contains the executable file "zipl.exe" and some other files.



  • Copy the folder "zipl" to a location of your choice. For example, you can copy it to "C:\Program Files\zipl".



  • Add the folder "zipl" to your system path. This will allow you to run zipl.exe from any directory. To do this, open the Control Panel, go to System and Security, then System, then Advanced System Settings, then Environment Variables. Under System Variables, find the variable "Path" and edit it. Add a semicolon (;) at the end of the existing value, then add the path of your zipl folder. For example, if your zipl folder is in "C:\Program Files\zipl", add ";C:\Program Files\zipl" at the end of the Path variable. Click OK to save the changes.



  • To test if zipl.exe is working properly, open a command prompt and type "zipl --version". You should see something like this:



ZIPL version 0.9.9 Written by John Doe Released under GNU GPL v3


If you see an error message or nothing at all, check if you have followed the previous steps correctly. How to Write and Compile Windows 64bit Assembly Code with Zipl




Now that you have installed Zipl on your Windows 64bit system, you can start writing and compiling your own assembly code. In this section, we will show you how to create a simple "Hello World" program in Windows 64bit assembly using Zipl.


How to create a simple "Hello World" program in Windows 64bit assembly




To create a simple "Hello World" program in Windows 64bit assembly, you need to follow these steps:



  • Create a new text file and name it "hello.asm". This will be your source code file.



  • Open the file "hello.asm" with your favorite text editor. You can use Notepad, Notepad++, Visual Studio Code, or any other editor that supports plain text files.



  • Type the following code in the file "hello.asm":



; hello.asm ; A simple "Hello World" program in Windows 64bit assembly using Zipl ; Use Intel syntax .intel_syntax noprefix ; Declare global symbol _main for linker .global _main ; Define _main function _main: ; Save the value of RBP register on the stack push rbp ; Set RBP register to the value of RSP register mov rbp, rsp ; Allocate 32 bytes of stack space for local variables sub rsp, 32 ; Store the address of the message string in a local variable lea rax, [rel message] mov [rbp-8], rax ; Store the length of the message string in a local variable mov eax, message_len mov [rbp-4], eax ; Call the WriteConsoleA function from kernel32.dll ; Parameters are passed in RCX, RDX, R8, and R9 registers ; RCX = handle to the console output (use -11 for standard output) ; RDX = pointer to the buffer that contains the data to be written ; R8 = number of bytes to write ; R9 = pointer to a variable that receives the number of bytes written (can be NULL) mov rcx, -11 mov rdx, [rbp-8] mov r8, [rbp-4] mov r9, 0 call WriteConsoleA ; Call the ExitProcess function from kernel32.dll ; Parameter is passed in RCX register ; RCX = exit code (use 0 for success) mov rcx, 0 call ExitProcess ; Define message string as a constant data section .section .rdata message: .asciz "Hello World!\n" message_len: .equ . - message ; Import external functions from kernel32.dll using Zipl macros .import kernel32.dll WriteConsoleA ExitProcess


This code is a simple "Hello World" program that prints "Hello World!" to the console output and exits. It uses Intel syntax, which is one of the supported syntaxes by Zipl. It also uses some Zipl directives, macros, and operators to declare global symbols, define sections, and import external functions. We will explain these features in more detail later.



  • Save the file "hello.asm".



  • Open a command prompt and navigate to the directory where you saved the file "hello.asm". For example, if you saved it in "C:\Users\YourName\Documents", type "cd C:\Users\YourName\Documents".



  • Type "zipl hello.asm -o hello.obj" and press Enter. This will invoke zipl.exe and compile your source code file into an object file. The "-o" option specifies the name of the output file. You should see something like this:



ZIPL version 0.9.9 Written by John Doe Released under GNU GPL v3 Assembling hello.asm... Done.


If you see any error messages or warnings, check if you have typed the code correctly.



  • Type "golink /console /entry _main hello.obj kernel32.dll" and press Enter. This will invoke GoLink, a free linker that can link object files into executable files. The "/console" option specifies that the output file is a console application. The "/entry" option specifies the name of the entry point function. The last two arguments are the names of the object file and the library file that you want to link. You should see something like this:

GoLink.EXE Version 0.26.4 Written by Jeremy Gordon 1996-2011 Released under GNU GPL v2 Linking hello.obj kernel32.dll... Output file: hello.exe


If you see any error messages or warnings, check if you have the correct files and options.



  • Type "hello.exe" and press Enter. This will run your executable file and display the output on the console. You should see something like this:



Hello World!


Congratulations! You have just created your first Windows 64bit assembly program using Zipl.


How to use Zipl directives, macros, and operators




In the previous section, we used some Zipl directives, macros, and operators to write our assembly code. In this section, we will explain what they are and how to use them.


Zipl directives




Zipl directives are keywords that start with a dot (.) and tell the assembler how to process the source code. They can be used to define sections, symbols, constants, data, alignment, and other aspects of the assembly code. Some of the common Zipl directives are:



  • .intel_syntax noprefix: This directive tells the assembler to use Intel syntax for the assembly code. The noprefix option means that the registers do not need a % prefix and the immediate values do not need a $ prefix.



  • .global symbol: This directive tells the assembler to make the symbol (such as a function name or a variable name) visible to the linker and other modules. This is necessary if you want to export or import symbols from your assembly code.



  • .section name: This directive tells the assembler to start a new section with the given name. A section is a part of the object file that contains code or data with certain attributes. For example, .text is the section for executable code, .data is the section for initialized data, and .rdata is the section for read-only data.



  • .asciz string: This directive tells the assembler to store a null-terminated string in the current section. A null-terminated string is a sequence of characters followed by a zero byte. For example, .asciz "Hello World!" will store 13 bytes in the current section: 72 65 6C 6C 6F 20 57 6F 72 6C 64 21 00.



  • .equ name, expression: This directive tells the assembler to define a constant with the given name and expression. The expression can be a numeric value or an arithmetic expression involving other constants or symbols. For example, .equ message_len, . - message will define a constant named message_len with the value equal to the difference between the current location (.) and the symbol message.



There are many other Zipl directives that you can use to control various aspects of your assembly code. You can find a complete list and description of them in the Zipl documentation.


Zipl macros




Zipl macros are predefined symbols that expand into one or more lines of assembly code when used. They can be used to simplify common tasks, such as importing or calling external functions, or defining structures or unions. Some of the common Zipl macros are:



  • .import library function: This macro tells the assembler to import an external function from a library file. The library parameter is the name of the library file (such as kernel32.dll) and the function parameter is the name of the function (such as WriteConsoleA). This macro will generate an import record in the object file that tells the linker where to find the function.



  • .call function: This macro tells the assembler to call an external function using a relative jump instruction. The function parameter is the name of the function (such as ExitProcess). This macro will generate a call instruction with a placeholder for the relative offset that will be filled by the linker.



  • .struct name: This macro tells the assembler to start defining a structure with the given name. A structure is a composite data type that consists of one or more fields of different types and sizes. For example, .struct POINT will start defining a structure named POINT.



  • .endstruct: This macro tells the assembler to end defining a structure. It will also define a constant named name_size with the size of the structure in bytes. For example, .endstruct will end defining a structure and define POINT_size as a constant.



  • .union name: This macro tells the assembler to start defining a union with the given name. A union is a composite data type that consists of one or more fields that share the same memory location and can have different types and sizes. For example, .union DATA will start defining a union named DATA.



  • .endunion: This macro tells the assembler to end defining a union. It will also define a constant named name_size with the size of the union in bytes. For example, .endunion will end defining a union and define DATA_size as a constant.



There are many other Zipl macros that you can use to simplify your assembly code. You can find a complete list and description of them in the Zipl documentation.


Zipl operators




Zipl operators are symbols that perform arithmetic, logical, or bitwise operations on operands. They can be used to calculate expressions, assign values, compare values, or manipulate bits. Some of the common Zipl operators are:



  • + : This operator performs addition on two operands. For example, 2 + 3 will result in 5.



  • - : This operator performs subtraction on two operands. For example, 5 - 2 will result in 3.



  • * : This operator performs multiplication on two operands. For example, 2 * 3 will result in 6.



  • / : This operator performs division on two operands. For example, 6 / 3 will result in 2.



  • % : This operator performs modulo on two operands. For example, 7 % 3 will result in 1.



  • & : This operator performs bitwise AND on two operands. For example, 5 & 3 will result in 1.



  • : This operator performs bitwise OR on two operands. For example, 5 3 will result in 7.



  • ^ : This operator performs bitwise XOR on two operands. For example, 5 ^ 3 will result in 6.



  • : This operator performs bitwise NOT on one operand. For example, 5 will result in -6.



  • << : This operator performs bitwise left shift on two operands. For example, 5 << 2 will result in 20.



  • > : This operator performs bitwise right shift on two operands. For example, 20 >> 2 will result in 5.



  • == : This operator performs equality comparison on two operands. For example, 5 == 5 will result in true.



  • != : This operator performs inequality comparison on two operands. For example, 5 != 3 will result in true.



  • < : This operator performs less than comparison on two operands. For example, 3 < 5 will result in true.



  • > : This operator performs greater than comparison on two operands. For example, 5 > 3 will result in true.



  • <= : This operator performs less than or equal to comparison on two operands. For example, 3 <= 5 will result in true.



  • >= : This operator performs greater than or equal to comparison on two operands. For example, 5 >= 3 will result in true.



There are many other Zipl operators that you can use to perform various operations on your assembly code. You can find a complete list and description of them in the Zipl documentation.


How to Link Windows 64bit Assembly Code with C/C++ Code




Sometimes you may want to link your Windows 64bit assembly code with C/C++ code to create a mixed-language program. For example, you may want to write some performance-critical functions in assembly and call them from your C/C++ code, or vice versa. In this section, we will show you how to link Windows 64bit assembly code with C/C++ code using Zipl and GoLink.


How to use extern and global keywords to declare external symbols




To link Windows 64bit assembly code with C/C++ code, you need to declare the symbols that are defined in one module and used in another module as external. For example, if you have a function named foo in your assembly code and you want to call it from your C/C++ code, you need to declare foo as an external symbol in your C/C++ code. Similarly, if you have a variable named bar in your C/C++ code and you want to access it from your assembly code, you need to declare bar as an external symbol in your assembly code.


To declare an external symbol in your assembly code, you need to use the .extern keyword followed by the name of the symbol. For example, .extern bar will tell the assembler that bar is an external symbol that is defined elsewhere. To declare an external symbol in your C/C++ code, you need to use the extern keyword followed by the type and name of the symbol. For example, extern int bar; will tell the compiler that bar is an external symbol of type int that is defined elsewhere.


On the other hand, to declare a symbol that is defined in your assembly code and used in another module as global, you need to use the .global keyword followed by the name of the symbol. For example, .global foo will tell the assembler that foo is a global symbol that can be used by other modules. To declare a symbol that is defined in your C/C++ code and used in another module as global, you need to use the __declspec(dllexport) keyword before the type and name of the symbol. For example, __declspec(dllexport) int bar; will tell the compiler that bar is a global symbol of type int that can be used by other modules.


How to use .def files to export symbols from assembly modules




Another way to declare symbols that are defined in your assembly code and used in another module as global is to use .def files. A .def file is a text file that contains a list of symbols that are exported from an assembly module. It has the following format:


LIBRARY module_name EXPORTS symbol_1 symbol_2 ... symbol_n


The LIBRARY line specifies the name of the module that exports the symbols. The EXPORTS line introduces the list of symbols that are exported. Each symbol is written on a separate line.


To use a .def file to export symbols from your assembly code, you need to follow these steps:



  • Create a new text file and name it "module_name.def". Replace module_name with the name of your assembly module.



  • Open the file "module_name.def" with your favorite text editor.



  • Type "LIBRARY module_name" on the first line. Replace module_name with the name of your assembly module.



  • Type "EXPORTS" on the second line.



  • Type the names of the symbols that you want to export from your assembly module on separate lines after the EXPORTS line.



  • Save the file "module_name.def".



  • When linking your assembly module with GoLink or other linkers, specify the name of your .def file as an argument. For example, "golink /console /entry _main hello.obj kernel32.dll hello.def" will link hello.obj with kernel32.dll and hello.def.



Using .def files can be useful if you have many symbols that you want to export from your assembly module, or if you want to avoid name mangling issues when linking with C/C++ modules.


How to use GoLink or other linkers to link assembly and C/C++ object files




To link Windows 64bit assembly and C/C++ object files into an executable file, you need to use a linker that can handle both types of object files. One of the linkers that can do this is GoLink, which we have already used in the previous sections. Another linker that can do this is Microsoft Linker (link.exe), which comes with Visual Studio or Windows SDK.


To use GoLink to link Windows 64bit assembly and C/C++ object files, you need to follow these steps:



  • Compile your C/C++ source code files into object files using a compiler that supports Windows 64bit systems. For example, you can use Microsoft Compiler (cl.exe), which comes with Visual Studio or Windows SDK.



  • Compile your assembly source code files into object files using Zipl as we have shown in the previous sections.



  • Invoke GoLink with the names of the object files and the library files that you want to link as arguments. You can also specify some options to control the output file type, name, entry point, and other aspects. For example, "golink /console /entry _main hello.obj foo.obj kernel32.dll" will link hello.obj and foo.obj with kernel32.dll and create a console application named hello.exe with _main as the entry point.



To use Microsoft Linker to link Windows 64bit assembly and C/C++ object files, you need to follow these steps:



  • Compile your C/C++ source code files into object files using Microsoft Compiler as we have shown in the previous step.



  • Compile your assembly source code files into object files using Zipl as we have shown in the previous sections.



  • Invoke Microsoft Linker with the names of the object files and the library files that you want to link as arguments. You can also specify some options to control the output file type, name, entry point, and other aspects. For example, "link /subsystem:console /entry:_main hello.obj foo.obj kernel32.lib" will link hello.obj and foo.obj with kernel32.lib and create a console application named hello.exe with _main as the entry point.



</ol


About

Welcome to the group! You can connect with other members, ge...
bottom of page