【发布时间】:2019-05-11 19:23:05
【问题描述】:
我发现这个带有内联汇编代码的 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, $0x70; inb $0x71, %0; sti" : "=a"(tvalue) : "a"(index));
}
array[index] = tvalue;
}
【问题讨论】:
-
我们不知道上下文,但通常您应该为
cli、sti和out拥有(或制作)单独的函数或宏,因此您不需要使用内联汇编到处都是。 -
我实际上正在制作一个引导加载程序。感谢@fuz,我解决了我的问题,但没有奏效,它可能会产生堆栈溢出?。
-
@konniskatt 您的困惑在哪里?或许我可以帮忙清理一下。
-
假设一个相对简单的 ABI 用于传递参数等,我认为你最好在汇编中简单地编写这些函数! hard 部分已经提供,剩下的只是记账。结合@fuz 的答案,编译 C -> assembler,然后花时间检查、验证并可能优化结果。
-
@konniskatt 问题是您使用
-std=c99编译,其中asm未被识别为关键字。将asm的所有提及更改为__asm__以解决此问题或改用-std=gnu99。如果您 (a) 发布了您遇到的所有错误,并且 (b) 您为编译代码而键入的命令的确切顺序,这将更容易找到。我花了一段时间才找到这个。
标签: gcc assembly x86-16 inline-assembly gnu-assembler