转换帮助:__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-Inline-汇编-HOWTO
http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
但我不懂汇编语言,所以我需要一些帮助。任何帮助将不胜感激。谢谢。
I would like to port C's outb function to D.
static __inline void outb (unsigned char value, unsigned short int port)
{
__asm__ __volatile__ ("outb %b0,%w1"
:
:
"a" (value),
"Nd" (port));
}
This is D version.
extern(C)
{
void outb (ubyte value, ushort port)
{
// I couldn't figure out this part
}
}
These are some links about the subject.
D Inline Assembler
GCC-Inline-Assembly-HOWTO
http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
But I don't know assembly language so I need some help. Any help would be appreciated. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
outb
指令只能以outb %al, %dx
形式调用,其中%al
是值,%dx
> 是端口。D 使用 x86 的 Intel 语法,而不是默认使用 AT&T 语法的 GNU 汇编器。相应的 Intel 语法将是
out dx, al
,D 中的相应代码如下所示:请注意,您根本不需要编写程序集,因为 druntime 具有
core.bitop.outp
函数执行相同的指令。The
outb
instruction should only be called asoutb %al, %dx
where%al
is the value and%dx
is the port.D uses Intel syntax for x86, as opposed to GNU assembler which uses the AT&T syntax by default. The corresponding Intel syntax would be
out dx, al
, and corresponding code in D would look like:Note that you don't need to write the assembly at all, because druntime has the
core.bitop.outp
function which perform the same instruction.可能让您困惑的第一件事是 D 编译器支持的操作码列表不包括您提供的 C 函数指定的
outb
。经过一番挖掘,我发现outb
是通用操作码out
的更具体名称。outb
表示操作码的第一个参数将包含在字节寄存器中(与outw
和outl
不同,后者表示第一个参数分别为一个字和一个双字的大小),但是,D 编译器对所有操作使用操作码out
,并根据您输入的参数的大小确定要写入的特定操作码。指定。解决了这个问题,接下来要做的就是将 GCC 语法转换为 D 语法。根据 GCC-Inline-Assembly-HOWTO,您提供的代码使用扩展的汇编语法:
查看您的模板,该函数指定一个带有两个参数的汇编指令 (
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
操作码,如下所示:请注意,由于 GCC 使用 AT&T 汇编器语法,而 D 使用 Intel 汇编器语法,因此提供给
OUT
的参数被颠倒。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 thatoutb
is a more specific name for the general opcodeout
.outb
indicates that the first argument to the opcode will be contained in a byte register (as opposed tooutw
andoutl
, which indicate a first argument size of, respectively, a word and a double word), however, the D compiler uses the opcodeout
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:
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 thevalue
parameter indicates that the contents of the variable must be placed in either registereax
,ax
, oral
depending on the size of the variable. The constraint on theport
variable,"Nd"
, indicates first that the value is in the range of 0-255, and second, that the value must be placed in either registeredx
,dx
, ordl
, 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 aredx
andal
. Following D's inline assembly syntax, you can move the variables and call theout
opcode as follows: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.