Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 转换帮助:\uuuu asm\uuuuu\uuuuu volatile___C_Assembly_D_Inline Assembly - Fatal编程技术网

C 转换帮助:\uuuu asm\uuuuu\uuuuu volatile__

C 转换帮助:\uuuu asm\uuuuu\uuuuu volatile__,c,assembly,d,inline-assembly,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),

我想把C的outb函数移植到D

static __inline void outb (unsigned char value, unsigned short int port)
{
    __asm__ __volatile__ ("outb %b0,%w1"
                          :
                          :
                         "a" (value),
                          "Nd" (port));
}
这是D版本

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

}
这些是关于这个主题的一些链接

D内联汇编程序

GCC内联程序集如何操作


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

指令
outb
只能称为
outb%al,%dx
,其中
%al
是值,
%dx
是端口

D为x86使用Intel语法,而GNU assembler默认使用AT&T语法。相应的英特尔语法将是
out dx,al
,D中的相应代码如下所示:

void outb (ubyte value, ushort port)
{
    asm {
        mov AL, value;
        mov DX, port;
        out DX, AL;
    }
}
请注意,您根本不需要编写程序集,因为druntime具有执行相同指令的函数

void outb (ubyte value, ushort port)
{
    import core.bitop;
    outp(port, value);
}

第一件可能让您感到困惑的事情是,D编译器支持的操作码列表不包括您提供的C函数指定的
outb
。经过一些挖掘,我发现
outb
是通用操作码
out
的一个更具体的名称
outb
表示操作码的第一个参数将包含在字节寄存器中(与分别表示一个字和一个双字的第一个参数大小的
out
outl
相反),但是,D编译器对所有操作都使用操作码
out
,并根据指定参数的大小确定要编写的特定操作码

这样,接下来要做的就是将GCC语法转换为D语法。根据GCC内联程序集HOWTO,您提供的代码使用扩展程序集语法:

asm ( assembler template 
    : output operands                  /* optional */
    : input operands                   /* optional */
    : list of clobbered registers      /* optional */
    );
查看模板,该函数指定一条汇编指令(
outb
)和两个参数,第一个是字节(
%b0
),第二个是字或短整数(
%w0

输入参数列表中的一个棘手问题是每个函数参数的前缀字符串。根据HOWTO,这些被称为约束。它们本质上是GCC在使用参数作为提供的汇编指令的参数时必须遵循的规则。应用于
参数的约束
“a”
表示变量的内容必须放置在寄存器
eax
ax
al
中,具体取决于变量的大小。
端口
变量
“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使用英特尔汇编程序语法,因此提供给
OUT
的参数顺序相反