转换帮助:__ asm__ __volatile__

Erd*_*dem 9 c assembly d inline-assembly

我想将C的outb函数移植到D.

static __inline void outb (unsigned char value, unsigned short int port)
{
    __asm__ __volatile__ ("outb %b0,%w1"
                          :
                          :
                         "a" (value),
                          "Nd" (port));
}
Run Code Online (Sandbox Code Playgroud)

这是D版.

extern(C) 
{
    void outb (ubyte value, ushort port)
    {
        // I couldn't figure out this part
   }

}
Run Code Online (Sandbox Code Playgroud)

这些是关于该主题的一些链接.

D内联汇编程序

http://dlang.org/iasm.html

GCC-内联汇编-HOWTO

http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

但我不懂汇编语言,所以我需要一些帮助.任何帮助,将不胜感激.谢谢.

ken*_*ytm 9

outb指令只应被调用为outb %al, %dxwhere %al%dx是哪个端口.

D对于x86使用Intel语法,而不是默认使用AT&T语法的GNU汇编程序.相应的Intel语法将是out dx, al,D中的相应代码如下所示:

void outb (ubyte value, ushort port)
{
    asm {
        mov AL, value;
        mov DX, port;
        out DX, AL;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您根本不需要编写程序集,因为druntime具有core.bitop.outp执行相同指令的功能.

void outb (ubyte value, ushort port)
{
    import core.bitop;
    outp(port, value);
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*ras 5

可能绊倒你的第一件事是D编译器支持的操作码列表不包括outb,正如您提供的C函数所指定的那样.经过一番挖掘,我发现这outb是一般操作码的更具体的名称out.outb指示到操作码的第一个参数将被包含在一个字节寄存器(而不是outwoutl,其指示的,分别是第一参数的大小,一个字和一个双字),但是,d编译器使用的操作码out对所有的操作,并根据您指定的参数的大小确定要写入的特定操作码.

除此之外,接下来要做的是将GCC语法转换为D语法.根据GCC-Inline-Assembly-HOWTO,您提供的代码使用扩展汇编语法:

asm ( assembler template 
    : output operands                  /* optional */
    : input operands                   /* optional */
    : list of clobbered registers      /* optional */
    );
Run Code Online (Sandbox Code Playgroud)

查看模板,函数指定一个outb带有两个参数的汇编指令(),第一个是byte(%b0),第二个是word或short integer(%w0).

关于输入参数列表的棘手问题是为每个函数参数添加前缀的字符串.根据HOWTO,这些被称为约束.它们本质上是GCC必须遵循的规则,使用参数作为提供的汇编指令的参数."a"应用于value参数的约束表示变量的内容必须放在任一寄存器eaxax,或者al取决于变量的大小.对port变量的约束"Nd"首先表示该值在0-255的范围内,其次,该值必须放在任一寄存器edxdx,或者dl再次基于变量的大小.

D编译器不像GCC那样提供组装块中变量的帮助; 在D的内联汇编程序中,您需要专门将参数值移动到适当的寄存器中.因为outb,这些寄存器是dxal.遵循D的内联汇编语法,您可以移动变量并调用out操作码,如下所示:

asm
{
    MOV AL, value;
    MOV DX, port;
    OUT DX, AL;
}
Run Code Online (Sandbox Code Playgroud)

请注意,由于GCC使用AT&T汇编语法,而D使用Intel汇编语法,因此提供的参数顺序OUT相反.