将 VS 内联汇编器翻译成 GCC 内联汇编器
Translate VS inline assembler to GCC inline assembler
我发现这个带有内联汇编代码的 C 代码:
ReadFromCMOS (unsigned char array [])
{
unsigned char tvalue, index;
for(index = 0; index < 128; index++)
{
_asm
{
cli /* Disable interrupts*/
mov al, index /* Move index address*/
/* since the 0x80 bit of al is not set, NMI is active */
out 0x70,al /* Copy address to CMOS register*/
/* some kind of real delay here is probably best */
in al,0x71 /* Fetch 1 byte to al*/
sti /* Enable interrupts*/
mov tvalue,al
}
array[index] = tvalue;
}
}
WriteTOCMOS(unsigned char array[])
{
unsigned char index;
for(index = 0; index < 128; index++)
{
unsigned char tvalue = array[index];
_asm
{
cli /* Clear interrupts*/
mov al,index /* move index address*/
out 0x70,al /* copy address to CMOS register*/
/* some kind of real delay here is probably best */
mov al,tvalue /* move value to al*/
out 0x71,al /* write 1 byte to CMOS*/
sti /* Enable interrupts*/
}
}
}
我试图翻译成 GNU 内联汇编程序,但我失败了,主要是因为 GNU 内联汇编程序很乱,使用陈旧的 AT&T 语法并且很难使用。
给我错误的代码:
void read_cmos(unsigned char array[])
{
unsigned char tvalue, index;
for (index = 0; index < 128; ++index)
{
/* read from CMOS */
asm ("cli; outb %1, [=11=]x70; inb [=11=]x71, %0; sti" : "=a"(tvalue) : "a"(index));
}
array[index] = tvalue;
}
尝试这样的事情:
/* read from CMOS */
asm ("cli; outb %1, [=10=]x70; inb [=10=]x71, %0; sti" : "=a"(tvalue) : "a"(index));
/* write to CMOS */
unsigned char i = index;
asm volatile ("cli; outb %0, [=10=]x70; movb %1, %%al; outb %%al, [=10=]x71; sti" : "+a"(i) : "rm"(tvalue));
请注意,为 tvalue
使用额外的变量是可选的。您还可以指定
"+a"(array[index])
或
"a"(array[index])
直接。重要的是您传递的表达式具有字节大小的类型,因此 gcc 选择 al
而不是 eax
.
需要将 index
分配给 i
以允许在不更改 index
的值的情况下破坏 al
。这段代码应该可以正常工作。或者,第二组指令也可以分成两部分:
asm volatile ("cli; outb %0, [=13=]x70" :: "a"(index));
asm volatile ("outb %0, %0x71" :: "a"(tvalue));
这避免了对额外变量的需要,并在选择寄存器时为编译器提供了更大的灵活性。
看看(古老的)GCC-inline-assembly HOWTO(面向 i686 Linux,所以可能适合您使用),仔细检查参数 passing/constraints(它们允许GCC 通过例如将 inputs/outputs 放置在使用的寄存器中来正确安排调用代码)。关于内联汇编的 GCC 文档也很相关,但在我的记忆中有点不透明,更详细,详细涵盖了更多的体系结构(但可能是最新的)。
(抱歉,无法在我的 phone 上放置链接。快速搜索应该会首先找到它们。)
我发现这个带有内联汇编代码的 C 代码:
ReadFromCMOS (unsigned char array [])
{
unsigned char tvalue, index;
for(index = 0; index < 128; index++)
{
_asm
{
cli /* Disable interrupts*/
mov al, index /* Move index address*/
/* since the 0x80 bit of al is not set, NMI is active */
out 0x70,al /* Copy address to CMOS register*/
/* some kind of real delay here is probably best */
in al,0x71 /* Fetch 1 byte to al*/
sti /* Enable interrupts*/
mov tvalue,al
}
array[index] = tvalue;
}
}
WriteTOCMOS(unsigned char array[])
{
unsigned char index;
for(index = 0; index < 128; index++)
{
unsigned char tvalue = array[index];
_asm
{
cli /* Clear interrupts*/
mov al,index /* move index address*/
out 0x70,al /* copy address to CMOS register*/
/* some kind of real delay here is probably best */
mov al,tvalue /* move value to al*/
out 0x71,al /* write 1 byte to CMOS*/
sti /* Enable interrupts*/
}
}
}
我试图翻译成 GNU 内联汇编程序,但我失败了,主要是因为 GNU 内联汇编程序很乱,使用陈旧的 AT&T 语法并且很难使用。
给我错误的代码:
void read_cmos(unsigned char array[])
{
unsigned char tvalue, index;
for (index = 0; index < 128; ++index)
{
/* read from CMOS */
asm ("cli; outb %1, [=11=]x70; inb [=11=]x71, %0; sti" : "=a"(tvalue) : "a"(index));
}
array[index] = tvalue;
}
尝试这样的事情:
/* read from CMOS */
asm ("cli; outb %1, [=10=]x70; inb [=10=]x71, %0; sti" : "=a"(tvalue) : "a"(index));
/* write to CMOS */
unsigned char i = index;
asm volatile ("cli; outb %0, [=10=]x70; movb %1, %%al; outb %%al, [=10=]x71; sti" : "+a"(i) : "rm"(tvalue));
请注意,为 tvalue
使用额外的变量是可选的。您还可以指定
"+a"(array[index])
或
"a"(array[index])
直接。重要的是您传递的表达式具有字节大小的类型,因此 gcc 选择 al
而不是 eax
.
需要将 index
分配给 i
以允许在不更改 index
的值的情况下破坏 al
。这段代码应该可以正常工作。或者,第二组指令也可以分成两部分:
asm volatile ("cli; outb %0, [=13=]x70" :: "a"(index));
asm volatile ("outb %0, %0x71" :: "a"(tvalue));
这避免了对额外变量的需要,并在选择寄存器时为编译器提供了更大的灵活性。
看看(古老的)GCC-inline-assembly HOWTO(面向 i686 Linux,所以可能适合您使用),仔细检查参数 passing/constraints(它们允许GCC 通过例如将 inputs/outputs 放置在使用的寄存器中来正确安排调用代码)。关于内联汇编的 GCC 文档也很相关,但在我的记忆中有点不透明,更详细,详细涵盖了更多的体系结构(但可能是最新的)。
(抱歉,无法在我的 phone 上放置链接。快速搜索应该会首先找到它们。)