[英]Converting help: __asm__ __volatile__
我想将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-内联汇编-HOWTO
http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
但我不懂汇编语言,所以我需要一些帮助。 任何帮助,将不胜感激。 谢谢。
outb
指令应仅作为outb %al, %dx
调用outb %al, %dx
其中%al
是值, %dx
是端口。
D对于x86使用Intel语法,而不是默认使用AT&T语法的GNU汇编程序。 相应的英特尔语法将是out dx, al
,D中的相应代码如下所示:
void outb (ubyte value, ushort port)
{
asm {
mov AL, value;
mov DX, port;
out DX, AL;
}
}
请注意,您根本不需要编写程序集,因为druntime具有执行相同指令的core.bitop.outp
函数。
void outb (ubyte value, ushort port)
{
import core.bitop;
outp(port, value);
}
第一件可能让你outb
事情是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必须遵循的规则,使用参数作为提供的汇编指令的参数。 应用于value
参数的约束"a"
表示变量的内容必须放在寄存器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
的参数顺序相反。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.