| Both sides previous revisionPrevious revision | |
| en:multiasm:papc:chapter_6_9 [2025/12/19 08:42] – [Programming in Assembler for Windows] pczekalski | en:multiasm:papc:chapter_6_9 [2025/12/19 09:00] (current) – pczekalski |
|---|
| <note tip>Code written in assembler and compiled to machine code is always an unmanaged one!</note> | <note tip>Code written in assembler and compiled to machine code is always an unmanaged one!</note> |
| |
| | ==== Dynamic memory management considerations ==== |
| | Using dynamic memory management at the level of the assembler code is troublesome: allocating and releasing memory require calls to the hosting operating system. It is possible, but complex. Moreover, there is no dynamic, automated memory management, as in .NET, Java, and Python, so the developer is on their own, similar to programming in C++. For this reason, it is common to allocate adequate memory resources on the high-level code, e.g., the GUI front-end and pass them to the assembler code as pointers. Note, however, that for some higher-level languages, such as C#, it is necessary to follow a strict pattern to ensure correct and persistent memory allocation, as described in the following sections. |
| |
| | <note tip>Using dynamic memory management at the level of the assembler code is troublesome. Common practice is to dynamically allocate memory resources in the scope of the calling (high-level) application and pass them to the assembler code via pointers.</note> |
| |
| ==== Pure Assembler Applications for Windows CMD ==== | ==== Pure Assembler Applications for Windows CMD ==== |
| The ''and rsp, not 8'' instruction causes stack alignment to be required before application leave or before following system function calls. | The ''and rsp, not 8'' instruction causes stack alignment to be required before application leave or before following system function calls. |
| |
| ==== Dynamic memory management considerations ==== | ==== Merging of the High-Level Languages and Assembler Code ==== |
| Using dynamic memory management at the level of the assembler code is troublesome: allocating and releasing memory require calls to the hosting operating system. It is possible, but complex. Moreover, there is no dynamic, automated memory management, as in .NET, Java, and Python, so the developer is on their own, similar to programming in C++. For this reason, it is common to allocate adequate memory resources on the high-level code, e.g., the GUI front-end and pass them to the assembler code as pointers. Note, however, that for some higher-level languages, such as C#, it is necessary to follow a strict pattern to ensure correct and persistent memory allocation, as described in the following chapters. | A common scenario is to wrap assembler code with stateless functions and encapsulate it in one or more DLL files. All arguments are passed from the calling code, usually written in C++ |
| |
| <note tip>Using dynamic memory management at the level of the assembler code is troublesome. Common practice is to dynamically allocate memory resources in the scope of the calling (high-level) application and pass them to the assembler code via pointers.</note> | |
| |
| **Programming for applications written in unmanaged code** | **Programming for applications written in unmanaged code** |
| |
| **Programming for applications written in managed code** | **Programming for applications written in managed code** |
| In the case of managed code, things get more complex. The .NET framework features automated memory management, which automatically releases unused memory (e.g., objects for which there are no more references) and optimises variable locations for improved performance. It is known as a .NET Garbage Collector (GC). GC instantly traces references and, in the event of an object relocation in memory, updates all references accordingly. It also releases objects that are no longer referenced. This automated mechanism, however, applies only across managed code apps. The problem arises when developers integrate a front-end application written in managed code with assembler libraries written in unmanaged code. All pointers and references passed to the assembler code are not automatically traced by the GC. Using dynamically allocated variables on the .NET side and accessing them from the assembler code is a very common scenario. GC cannot "see" any reference to the object (variable, memory) made in the unmanaged code; thus, it may release memory or relocate it without updating the reference address. It causes very hard-to-debug errors that occur randomly and are very serious (e.g. null pointer exception). | In the case of managed code, things get more complex. The .NET framework features automated memory management that releases unused memory (e.g., objects for which there are no more references) and optimises variable locations to improve performance. It is known as a .NET Garbage Collector (GC). GC instantly traces references and, in the event of an object relocation in memory, updates all references accordingly. It also releases objects that are no longer referenced. This automated mechanism, however, applies only across managed code apps. The problem arises when developers integrate a front-end application written in managed code with assembler libraries written in unmanaged code. All pointers and references passed to the assembler code are not automatically traced by the GC. Using dynamically allocated variables on the .NET side and accessing them from the assembler code is a very common scenario. GC cannot "see" any reference to the object (variable, memory) made in unmanaged code; thus, it may release or relocate memory without updating the reference address. It causes very hard-to-debug errors that occur randomly and are very serious (e.g. null pointer exception). |
| Luckily, there is a strict set of rules that must be followed when integrating managed and unmanaged code. We discuss it below. | Luckily, there is a strict set of rules to follow when integrating managed and unmanaged code. We discuss it below. |
| |
| |
| ===== Programming in Assembler for Linux ===== | ===== Programming in Assembler for Linux ===== |