Первое, что, вероятно, сбивает вас с толку, это то, что список поддерживаемых компиляторов D-кодов не включает outb
, как указано в предоставленной вами функции C. После некоторых копаний я обнаружил, что outb
является более конкретным именем для общего кода операции out
. outb
указывает, что первый аргумент кода операции будет содержаться в байтовом регистре (в отличие от outw
и outl
, которые указывают размер первого аргумента, соответственно, слова и двойного слова), однако D-компилятор использует код операции out
для всех операций и определяет, какой конкретный код операции записать, основываясь на размере указанного аргумента.
Следующим шагом будет преобразование синтаксиса GCC в синтаксис D. Согласно GCC-Inline-Assembly-HOWTO, предоставленный вами код использует расширенный синтаксис сборки:
asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
Глядя на ваш шаблон, функция задает одну инструкцию по сборке (outb
) с двумя аргументами, первый из которых является байтом (%b0
), а второй - словом или коротким целым числом (%w0
).
Хитрый бит со списком входных аргументов - это строка, которая ставит префикс перед каждым из параметров вашей функции. Они, согласно HOWTO, называются ограничениями. По сути, это правила, которым GCC должен следовать, используя параметры в качестве аргументов для предоставленных инструкций по сборке. Ограничение "a"
, примененное к параметру value
, указывает, что содержимое переменной должно быть помещено в регистр eax
, ax
или al
в зависимости от размера переменной. Ограничение на переменную port
, "Nd"
, во-первых, указывает, что значение находится в диапазоне 0-255, а во-вторых, что значение должно быть помещено в регистр edx
, dx
или * 1027. * опять же, исходя из размера переменной.
Компилятор D не предлагает такой большой помощи с переменными в сборочных блоках, как GCC; во встроенном ассемблере D вам необходимо специально переместить значения параметров в соответствующие регистры. Для outb
эти регистры dx
и al
. Следуя синтаксису встроенной сборки D, вы можете переместить переменные и вызвать код операции out
следующим образом:
asm
{
MOV AL, value;
MOV DX, port;
OUT DX, AL;
}
Обратите внимание, что, поскольку GCC использует синтаксис ассемблера AT & T, а D использует синтаксис Intel ассемблера, порядок аргументов, предоставляемых OUT
, меняется на обратный.