Первое, что вас, вероятно, сбивает с толку, это то, что список кодов операций, поддерживаемых компилятором 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
или dl
, опять же, в зависимости от размера Переменная.
Компилятор D не так сильно помогает с переменными в блоках сборки, как GCC; во встроенном ассемблере D вам нужно будет специально переместить значения параметров в соответствующие регистры. Для outb
это регистры dx
и al
. Следуя синтаксису встроенного ассемблера D, вы можете перемещать переменные и вызывать код операции out
следующим образом:
asm
{
MOV AL, value;
MOV DX, port;
OUT DX, AL;
}
Обратите внимание: поскольку GCC использует синтаксис ассемблера AT&T, а D использует синтаксис ассемблера Intel, порядок аргументов, предоставленных OUT
, меняется на обратный.
person
Adam Maras
schedule
23.12.2011