The first thing that's probably tripping you up is that the D compiler's supported list of opcodes does not include outb
, as specified by the C function you provided. After some digging, I've found out that outb
is a more specific name for the general opcode out
. outb
indicates that the first argument to the opcode will be contained in a byte register (as opposed to outw
and outl
, which indicate a first argument size of, respectively, a word and a double word), however, the D compiler uses the opcode out
for all of the operations, and determines which specific opcode to write based on the size of the argument you specify.
With that out of the way, the next thing to do is to convert the GCC syntax to D syntax. According to the GCC-Inline-Assembly-HOWTO, the code you provided uses the extended assembly syntax:
asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
Looking at your template, the function specifies one assembly instruction (outb
) with two arguments, the first being a byte (%b0
) and the second being a word or short integer (%w0
).
The tricky bit about the input arguments list is the string that prefixes each of your function parameters. These, according to the HOWTO, are called constraints. They're essentially rules that GCC must follow in using the parameters as arguments to the provided assembly instructions. The constraint "a"
applied to the value
parameter indicates that the contents of the variable must be placed in either register eax
, ax
, or al
depending on the size of the variable. The constraint on the port
variable, "Nd"
, indicates first that the value is in the range of 0-255, and second, that the value must be placed in either register edx
, dx
, or dl
, again, based upon the size of the variable.
The D compiler doesn't offer as much help with variables in assembly blocks as GCC does; in D's inline assembler, you'll need to specifically move the values of the parameters into the proper registers. For outb
, these registers are dx
and al
. Following D's inline assembly syntax, you can move the variables and call the out
opcode as follows:
asm
{
MOV AL, value;
MOV DX, port;
OUT DX, AL;
}
Note that, because GCC uses the AT&T assembler syntax, and D uses the Intel assembler syntax, the order of the arguments provided to OUT
is reversed.