Создание программ для Windows ARM64

Первая программа для Windows ARM64

Последнее обновление: 05.08.2023

Устройства на базе Arm становятся все более популярными благодаря своему экономичному характеру, более длительному времени автономной работы и повышенной производительности. Это обусловило постепенный рост количества устройств на Windows, которые работают на платформе ARM64.

Для создания приложений на ассеммблере под Windows ARM64 прежде всего необходимо установить среду разработки Visual Studio. Visual Studio доступна в ряде редакций. Мы будем использовать выпуск Visual Studio Community. Причем стоит отметить, что Visual Studio имеет полноценную поддержку ARM64.

Итак, для установки среды загрузим установщик со страницы https://visualstudio.microsoft.com/ru/vs/community/. После запуска программы установщика выберем пункт Разработка классических приложений на C++:

Установка Visual Studio для ассемблера ARM64 на Windows

Стоит отметить, что хотя сама Visual Studio и имеет поддержку ARM64, но ее установщик не является нативным приложением ARM64 и представляет общее приложение для разных архитектур, поэтому на ARM он может работать чуть медленее. Однако при установке он установщик определит платформу системы и загрузит и установит именно те файлы, которые подходят для данной системы, то есть для x86-64 устанавливается одна версия Visual Studio, а для ARM64 - другая.

После установки в панели Пуск среди установленных программ мы сможем найти кроме собственно Visual Studio также ряд установленных сопутствующих консольных утилит

Установка ARM64 Native Tools Command Prompt for Visual Studio для ассемблера на Windows

Здесь нас будет интресовать прежде всего утилита ARM64 Native Tools Command Prompt for VS 2022. Эта утилита позволяет напрямую обращаться к ассемблеру armasm64, который представляет своего рода версию MASM для платформы ARM64. Например, запустим данную утилиту и введем название ассемблера "armasm64", и нам отобразится его версия и опции:

**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.6.5
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'arm64'

C:\Program Files\Microsoft Visual Studio\2022\Community>armasm64
Microsoft (R) ARM Macro Assembler Version 14.36.32537.0 for 64 bits
Copyright (C) Microsoft Corporation.  All rights reserved.

error A2033: missing input source file

 Usage:      armasm [<options>] sourcefile objectfile
             armasm [<options>] -o objectfile sourcefile
             armasm -h              for help


C:\Program Files\Microsoft Visual Studio\2022\Community>

Первая программа на ассемблере ARM64 для Windows

Теперь создадим простейшую программу для Windows. В целом armasm64 применяет тот же синтаксис, те же инструкции, что и ассемблер GAS, однако есть и различия. Поэтому в дальнейшем я буду акцентировать внимание именно на различиях.

Итак, определим для хранения файлов с исходным кодом какой-нибудь каталог. Например, в моем случае это будет папка С:\arm64. В этой папке создадим файл hello.asm и определим в нем следующий код:

    area main, CODE     ; определение раздела main, который имеет тип CODE
    global __main       ; делаем видимой извне функцию __main

__main                  ; определение функции __main    
    mov x0, #2          ; помещаем в регистр Х0 число 2
    mov x1, #3          ; помещаем в регистр Х1 число 3
    add x0, x0, x1      ; складываем числа - Х0 = Х0 + Х1
    ret                 ; завершение функции __main
    end                 ; завершение программы

Определение программы начинается с директивы AREA, которая определяет раздел.

area main, CODE

Директиве передается название раздела - произвольный идентификатор, который указывает на имя разделя. В данном случае раздел называется main. Затем указывается тип раздела. Здесь это CODE. Данный тип указывает, что раздел представляет собой секцию с инструкциями программы. То есть это аналогично применению в ряде ассемблеров директивы .code или .text

Далее идет директива GLOBAL, которая позволяет сделать видимым, доступным из вне некоторый идентификатор.

global __main

В нашем случае делаем доступной извне процедуру __main, которая будет выступать в качестве точки входа в программу. Это необходимо компоновщику, чтобы он определил точку входа.

Затем располагает собственно определение процедуры/функции __main. Оно начинаяется с имени функции, за которым идет набор составляющих ее инструкций. Обратите внимание на отступы и что у названия функции отступа нет.

В самой функции __main для простоты с помощью инструкции MOV помещаем в регистры Х0 и Х1 числа 2 и 3 и с помощью инструкции ADD складываем эти числа и результат помещаем в регистр Х0

mov x0, #2
mov x1, #3
add x0, x0, x1

Функция __main завершается вызовом инструкции ret, а сама программа завершается инструкцией end

Теперь скомпилируем программу. Для этого запустим утилиту ARM64 Native Tools Command Prompt for VS 2022 и с помощью команды cd перейдем в ней к папке, где располагается наш файл hello.asm. Затем для компиляции выполним следующую команду

armasm64 hello.asm -o hello.obj

Эта команда передает ассемблеру armasm64 исходный файл "hello.asm". С помощью опции -o указывается название файла, в который будет производиться компиляция. То есть в данном случае файл hello.asm будет компилироваться в файл hello.obj.

Итак, после выполнения этой команды в папке с исходным кодом у нас появится скомпилированный объектный файл hello.obj. Теперь его надо скомпоновать в исполняемый файл, чтобы его можно было запускать как обычное приложение. Для этого выполним команду

cl hello.obj /link /entry:__main /subsystem:console

Команда cl представляет вызов компилятора языка C++, который устанавливается вместе с Visual Studio. Этому компилятору передается файл hello.obj. А с помощью опции /link передатся настройки для компоновщика. В частности, опция /entry устанавливает точку входа в программу. В нашем случае это функция __main, которую в коде программы мы экспортировали во вне с помощью директивы GLOBAL. Если наша точка входа имеет другое имя, то соответственно также меняется значение этого параметра. Кроме того, опция /subsystem:console указывает, что мы компилируем консольное приложение.

Стоит отметить, что вместо компилятора cl мы могли бы просто вызвать программу компоновщика/линкера в виде утилиты link и передать ей те же параметры:

link hello.obj /entry:__main /subsystem:console

После выполнения этой команды с папке с исходным кодом появится собственно файл программы - hello.exe. И мы можем запустить его, вызвав команду

hello.exe

Однако поскольку программа ничего не выводит на консоль, то и консоль при вызове этой программы ничего не отобразит. Тем не менее в программе изменяется значение регистра Х0. Данный регистр обычно используется при завершении программы как числовой код завершения программы (в нашем случае в регистре Х0 располгается число 5). И чтобы получить этот числовой код, после выполнения скомпилированной программы надо выполнить команду

echo %ERRORLEVEL%

Полный вывод консоли ARM64 Native Tools Command Prompt for VS 2022:

**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.6.5
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'arm64'

C:\Program Files\Microsoft Visual Studio\2022\Community>cd c:\arm64

c:\arm64>armasm64 hello.asm -o hello.obj
Microsoft (R) ARM Macro Assembler Version 14.36.32537.0 for 64 bits
Copyright (C) Microsoft Corporation.  All rights reserved.


c:\arm64>cl hello.obj /link /entry:__main /subsystem:console
Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32537 for ARM64
Copyright (C) Microsoft Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:hello.exe
/entry:__main
/subsystem:console
hello.obj

c:\arm64>hello.exe

c:\arm64>echo %ERRORLEVEL%
5

c:\arm64>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850