C 转换帮助:\uuuu asm\uuuuu\uuuuu volatile__
我想把C的outb函数移植到DC 转换帮助:\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),
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
的参数顺序相反