LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1517|回复: 1

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

[复制链接]
发表于 2006-3-14 07:52:36 | 显示全部楼层 |阅读模式
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'”是什么错误
以及怎样才能使这段代码通过编译呢?
请大家指教!!
谢谢!!
发表于 2006-3-15 13:45:22 | 显示全部楼层
我取下来编译了:有两个错误:改为这样就好了:
  1. #define MEM_SIZE 15
  2. #define LOW_MEM 0x100000
  3. #define PAGING_MEM (MEM_SIZE*1024*1024)
  4. #define PAGING_PAGES (PAGING_MEM>>12)

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

  6. unsigned long get_free_page()
  7. {
  8.     register unsigned long __res asm("eax");

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

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

  15.             "movl $1024, %%ecx\n\t"
  16.             "leal 4092(%%edx), %%edi\n\t"
  17.             "rep; stosl\n\t"
  18.             "movl %%edx, %%eax\n"
  19.             "1:"
  20.             :"=a"(__res)
  21.             :"0"(0), "i"(LOW_MEM), "c"(PAGING_PAGES),
  22.             "D"(mem_map + PAGING_PAGES - 1)
  23.             : "edx"
  24.             );
  25.     return __res;
  26. }
复制代码

1. 输入操作数为 0 不能空缺。
2. "edi", "ecx" 已经用在了 input output 部分不需要再列入 clobbered register 中。

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

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

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表