Несмотря на то, что чаще GNU ассемблер AS применяют на Linux, мы также можем использовать этот ассемблер и на Windows. Поскольку синтаксис будет в целом аналогичен тому, что был рассмотрен ранее, сосредоточимся на тех моментах, которые на Windows будут отличаться.
GNU ассемблер AS распространяется в рамках набора компиляторов GCC. Для Windows одной из наиболее популярных версий GCC является пакет средств для разработки от некоммерческого проекта MSYS2. Следует отметить, что для MSYS2 требуется 64-битная версия Windows 7 и выше (то есть Vista, XP и более ранние версии не подходят)
Итак, загрузим программу установки MSYS2 с официального сайта MSYS2:
После загрузки запустим программу установки:
На первом шаге установки будет предложено установить каталог для установки. По умолчанию это каталог C:\msys64:
Оставим каталог установки по умолчанию (при желании можно изменить). На следующем шаге устанавливаются настройки для ярлыка для меню Пуск, и затем собственно будет произведена установка. После завершения установки нам отобразить финальное окно, в котором нажмем на кнопку Завершить
После завершения установки запустится консольное приложение MSYS2.exe. Если по каким-то причинам оно не запустилось, то в папке установки C:/msys64 надо найти файл usrt_64.exe:
Теперь нам надо установить собственно набор компиляторов GCC. Для этого введем в этом приложении следующую команду:
pacman -S mingw-w64-ucrt-x86_64-gcc
Для управления пакетами MSYS2 использует пакетный менеджер Packman. И данная команда говорит пакетному менелжеру packman установить пакет mingw-w64-ucrt-x86_64-gcc
,
который представляет набор компиляторов GCC (название устанавливаемого пакета указывается после параметра -S
).
Если после завершения установки мы откроем каталог установки и зайдем в нем в папку C:\msys64\ucrt64\bin, то найдем там все необходимые файлы компиляторов:
В частности, файл as.exe как раз и будет представлять GNU ассемблер AS.
Далее для упрощения запуска компилятора мы можем добавить путь к нему в Переменные среды. Для этого можно в окне поиска в Windows ввести "изменение переменных среды текущего пользователя":
Нам откроется окно Переменныех среды:
И добавим путь к компилятору C:\msys64\ucrt64\bin
:
Чтобы убедиться, что ассемблер успешно установлен, введем следующую команду:
as --version
В этом случае нам должна отобразиться версия ассемблера:
c:\asm>as --version GNU assembler (GNU Binutils) 2.40 Copyright (C) 2023 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or later. This program has absolutely no warranty. This assembler was configured for a target of `x86_64-w64-mingw32'. c:\asm>
В Windows возвращаемый статусный код программы помещается в регистр %rax (а не в %rdi как в Linux). Чтобы завершить программу, мы можем использовать стандартную инструкцию ret, которая завершает вызов функции. Например, напишем программу, которая просто будет устанавливать статусный код возврата. Для этого определим файл, который пусть будет называться hello.s:
.globl _start .text _start: movq $44, %rax ret
Здесь с помощью инструкции movq просто помещаем в регистр %rax число 44 - это будет наш статусный код возврата из программы. Скомпилируем программу. Сначала перейдем в командной строке в папку, где располагается файл и для компиляции выполним команду:
as hello.s -o hello.o
Данная команда создаст в текущей папке объектный файл hello.o. Для его компоновки в исполняемое приложение выполним команду:
ld hello.o -o hello.exe
В результате будет создан исполняемый файл hello.exe размером порядка 4 КБ. Запустим его:
hello.exe
После того, как файл отработает, для получения статусного кода выполним команду
echo %ERRORLEVEL%
В результате консоль должна вывести то число, которое мы поместили в регистр %rax. Полный вывод консоли:
c:\asm>as hello.s -o hello.o c:\asm>ld hello.o -o hello.exe c:\asm>hello.exe c:\asm>echo %ERRORLEVEL% 44 c:\asm>
Проблемы могут возникнуть с работой с секцией .data (либо при обращении к данным в других секциях). Например:
.globl _start .data num1: .quad 5 num2: .quad 6 .text _start: movq num1, %rax addq num2, %rax ret
Здесь также довольно простейшая программа, которая просто складывает два числа, определенных в секции .data
, и результат помещает в регистр %rax. И если компиляция этой программы
пройдет нормально, то при компоновке мы можем столкнуться с ошибками:
c:\asm>as hello.s -o hello.o c:\asm>ld hello.o -o hello.exe hello.o:fake:(.text+0x4): relocation truncated to fit: R_X86_64_32S against `.data' hello.o:fake:(.text+0xc): relocation truncated to fit: R_X86_64_32S against `.data' c:\asm>
Здесь мы сталкиваемся с проблемой релокаций. Самое простое решение - использовать адресацию относительно регистра %rip. То есть при загрузке данных писать не
movq num1, %rax
а обращаться к переменным относительно %rip:
movq num1(%rip), %rax
Так, перепишем предыдущую программу:
.globl _start .data num1: .quad 5 num2: .quad 6 .text _start: movq num1(%rip), %rax # обращаемся к num1 относительно регистра %rip addq num2(%rip), %rax # обращаемся к num2 относительно регистра %rip ret
Теперь компоновка программы пройдет без проблем:
c:\asm>as hello.s -o hello.o c:\asm>ld hello.o -o hello.exe c:\asm>hello.exe c:\asm>echo %ERRORLEVEL% 11 c:\asm>