+ -
当前位置:首页 → 问答吧 → 求助c语言的内嵌汇编编译时的问题

求助c语言的内嵌汇编编译时的问题

时间:2006-03-14

来源:互联网

linux0.11源代码中内存管理处有一个关于分配一页空闲物理内存的函数get_free_page
源代码如下:(自己提炼了一下)

#define MEM_SIZE 15
#define LOW_MEM 0x100000
#define PAGING_MEM (MEM_SIZE*1024*1024)
#define PAGING_PAGES (PAGING_MEM>>12)

static unsigned char mem_map[PAGING_PAGES] = {0};

unsigned long get_free_page()
{
register unsigned long __res asm("eax");

__asm__ ("std; repne; scasb\n\t"
"jne 1f\n\t"
"movb $1, 1(%%edi)\n\t"
//计算实际的物理地址
"sall $12, %%ecx\n\t"
"addl %2, %%ecx\n\t"
"movl %%ecx, %%edx\n\t" //物理地址存放在edx中
//清空所分配的内存
"movl $1024, %%ecx\n\t"
"leal 4092(%%edx), %%edi\n\t"
"rep; stosl\n\t"
"movl %%edx, %%eax\n"
"1:"
:"=a"(__res)
:""(0), "i"(LOW_MEM), "c"(PAGING_PAGES),
"D"(mem_map + PAGING_PAGES - 1)
:"di", "cx", "dx" );
return __res;
}
这段代码放在test.c文件中。
编译:
gcc -o test test.c
编译的结果如下:
test.c: In function `get_free_page':
test.c:13: warning: asm operand 1 probably doesn't match constraints
test.c:13: can't find a register in class `CREG' while reloading `asm'
不知道“can't find a register in class `CREG' while reloading `asm'”是什么错误
以及怎样才能使这段代码通过编译呢?
请大家指教!!
谢谢!!

作者: greek   发布时间: 2006-03-14

我取下来编译了:有两个错误:改为这样就好了:
代码:
#define MEM_SIZE 15
#define LOW_MEM 0x100000
#define PAGING_MEM (MEM_SIZE*1024*1024)
#define PAGING_PAGES (PAGING_MEM>>12)

static unsigned char mem_map[PAGING_PAGES] = {0};

unsigned long get_free_page()
{
 register unsigned long __res asm("eax");

 __asm__ ("std; repne; scasb\n\t"
 "jne 1f\n\t"
 "movb $1, 1(%%edi)\n\t"

 "sall $12, %%ecx\n\t"
 "addl %2, %%ecx\n\t"
 "movl %%ecx, %%edx\n\t"

 "movl $1024, %%ecx\n\t"
 "leal 4092(%%edx), %%edi\n\t"
 "rep; stosl\n\t"
 "movl %%edx, %%eax\n"
 "1:"
 :"=a"(__res)
 :"0"(0), "i"(LOW_MEM), "c"(PAGING_PAGES),
 "D"(mem_map + PAGING_PAGES - 1)
 : "edx"
 );
 return __res;
}
1. 输入操作数为 0 不能空缺。
2. "edi", "ecx" 已经用在了 input output 部分不需要再列入 clobbered register 中。

clobbered register 主要是用在一段汇编代码会以隐含的方式改变某寄存器时,应列入其中。

From: info gcc :: C Extensions :: Extended Asm
代码:
 You may not write a clobber description in a way that overlaps with
an input or output operand. For example, you may not have an operand
describing a register class with one member if you mention that register
in the clobber list. There is no way for you to specify that an input
operand is modified without also specifying it as an output operand.
Note that if all the output operands you specify are for this purpose
(and hence unused), you will then also need to specify `volatile' for
the `asm' construct, as described below, to prevent GCC from deleting
the `asm' statement as unused.

作者: crquan   发布时间: 2006-03-15