flat assembler
Message board for the users of flat assembler.
Index
> Tutorials and Examples > Windows on ARM64 - simple example with fasmg |
Author |
|
Tomasz Grysztar 14 Oct 2022, 19:04
I have finally got my hands on an ARM64-based machine running Windows, and - obviously - one of the very first things I wanted to try was to assemble some new PE files.
It turned out to be very easy with already available resources. I used the existing aarch64 includes for fasmg (made by tthsqe) and the standard PE formatter that comes with fasmg. My first working example, analogous to the basic PE demos from fasm packages: Code: format binary as 'exe' PE.Settings.Magic = 0x20B PE.Settings.Machine = IMAGE_FILE_MACHINE_ARM64 PE.Settings.ImageBase = 0x140000000 PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE + IMAGE_FILE_LARGE_ADDRESS_AWARE PE.Settings.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT + IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI include 'format/pe.inc' include 'aarch64.inc' define xIP0? x16 ; Windows-specific aliases define xIP1? x17 section '.text' code readable executable entry $ mov x0,0 adr x1,_message adr x2,_caption mov x3,0 bl MessageBoxA bl ExitProcess MessageBoxA: adr xip0,imp__MessageBoxA ldr xip0,[xip0] br xip0 ExitProcess: adr xip0,imp__ExitProcess ldr xip0,[xip0] br xip0 section '.data' data readable writeable _caption db 'Windows on ARM64',0 _message db 'Hello, world of assembly!',0 section '.idata' import data readable writeable dd 0,0,0,RVA kernel_name,RVA kernel_table dd 0,0,0,RVA user_name,RVA user_table dd 0,0,0,0,0 kernel_table: imp__ExitProcess dq RVA _ExitProcess dq 0 user_table: imp__MessageBoxA dq RVA _MessageBoxA dq 0 kernel_name db 'KERNEL32.DLL',0 user_name db 'USER32.DLL',0 _ExitProcess dw 0 db 'ExitProcess',0 _MessageBoxA dw 0 db 'MessageBoxA',0 section '.reloc' fixups data readable discardable if $=$$ dd 0,8 ; if there are no fixups, generate dummy entry end if This might encourage me to work on CALM-based ARM64 instruction set myself... But no promises. And my PE tutorial deserves another chapter. |
|||
14 Oct 2022, 19:04 |
|
Tomasz Grysztar 17 Oct 2022, 16:12
Taking the universal_template.asm from the PE tutorial as a starting point, just a couple of minor changes suffices to turn it into a valid ARM64 PE.
Obviously, we need to change the CPU instruction set. Replace Code: use 'x64.inc'
use64 Code: use 'aarch64.inc'
define xIP0? x16
define xIP1? x17 The default image base needs to be different for ARM64, with a value above 32-bit range: Code: DEFAULT_IMAGE_BASE := 0x140000000 Code: .Machine dw IMAGE_FILE_MACHINE_ARM64 Code: EntryPoint: mov x0,0 adr x1,MessageString adr x2,CaptionString mov x3,0 bl stub_MessageBoxA bl stub_ExitProcess stub_MessageBoxA: adr xip0,MessageBoxA ldr xip0,[xip0] br xip0 stub_ExitProcess: adr xip0,ExitProcess ldr xip0,[xip0] br xip0 Code: adrp xip0,MessageBoxA ldr xip0,[xip0,(MessageBoxA-IMAGE_BASE) and 0FFFh] Note: this variant does not work with tthsqe's aarch64.inc, because current implementation there tries to generate a superfluous relocation record for ADRP. But it is easy to fix, works for me with a simple correction. If this becomes the official part of the tutorial, I'm going to provide a corrected aarch64.inc in the tutorial packages. And that is all - after applying these changes and assembling with fasmg, we get a working template for the new architecture (tested on Windows 11 on ARM). |
|||
17 Oct 2022, 16:12 |
|
Tomasz Grysztar 07 Jun 2023, 15:35
The COFF formatter differs from the PE one quite substantially, so it should not be surprising that following this template is not enough to get it working. I haven't tried this myself yet.
|
|||
07 Jun 2023, 15:35 |
|
revolution 07 Jun 2023, 15:39
I notice the data sizes are not ARM compatible. Is that a deliberate choice?
It looks very wrong to me to see this with "dd": Code: dd 0,0,0,RVA kernel_name,RVA kernel_table ; <--- ARM uses dw for 32-bit values |
|||
07 Jun 2023, 15:39 |
|
Tomasz Grysztar 07 Jun 2023, 16:50
To replace the x86-compatible names, the formatter modules that use them should either be moved to a separate namespace, or cleaned up to only use EMIT everywhere. I should do the latter anyway sometime, but for an easily patched up proof of concept they were all left unchanged. Note that the PE formatter is taken straight from the "fasm 1 compatibility package" which by definition has been x86-focused.
|
|||
07 Jun 2023, 16:50 |
|
tthsqe 08 Jun 2023, 02:23
Thomasz, I hope you got my message giving you the green lights. I didn't know what I was doing when I attempted the relocations, and hope you fixed some of the bugs, one of which I commented in the code.
|
|||
08 Jun 2023, 02:23 |
|
alorent 08 Jun 2023, 10:49
Thanks guys.
I have been doing some tests and finally got the ARM64 .OBJ to link with VS2022 (ARM64). Example: Code: include 'format/format.inc' format MS COFF COFF.Settings.Machine = IMAGE_FILE_MACHINE_ARM64 include 'cpu/aarch64.inc' include 'win32ax.inc' .code public MyArmFunction as 'MyArmFunction' proc MyArmFunction mov x1, 1 mov x2, 2 endp I had to change one line in the "coffms.inc" file. I changed this line: Code: if COFF.MACHINE = IMAGE_FILE_MACHINE_I386 for Code: if COFF.MACHINE = IMAGE_FILE_MACHINE_I386 | COFF.MACHINE = IMAGE_FILE_MACHINE_ARM64 And this is the C++ code in VS2022 to call it: Code: extern "C" void __stdcall MyArmFunction(void); int main() { MyArmFunction(); } Probably Tomasz has a more elegant way to do it Thanks! |
|||
08 Jun 2023, 10:49 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.