最近两天开始学习linux内核,看了赵炯博士的《linux内核完全注释》感觉受益匪浅。今天看到第三章 嵌入汇编部分,于是写了一个小程序试验了一下,用gcc编译通过。代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h> typedef struct Array{
char* chlist;
int size;
}array; char* StrCopy(array *a1,array *a2){
//int i;
register char* _res;
printf("字符串1: %s \n",a1->chlist);
printf("字符串2: %s \n",a2->chlist);
if(a1->size>a2->size){
a2->chlist=(char*)malloc(a1->size*sizeof(char));
a2->size=a1->size;
}
/*for(i=0;i<a1->size;i++){
a2->chlist[i]=a1->chlist[i];
}
return a2->chlist;*/
asm(
"cld\n" // 清除方向位
"\tmovl %%esi,%%ebx\n\t" //保存a2->chlist首地址
"1: decl %3\n\t " //size--
"js 4f\n\t" //if(size<0)跳转到4继续执行
"lodsb\n\t" //ds:[esi]->al esi++
"stosb\n\t" //al->es[edi] edi++
"jmp 1b\n\t" //跳转到1执行
"4:\n\t"
"movl %%ebx,%%esi\n\t" //恢复esi
:"=S"(_res)\
:"D"(a2->chlist),"S"(a1->chlist),"c"(a1->size)\
:"ebx"
);
return _res;
} int main(void){
array l1;
array l2;
char* str;
l1.chlist=l2.chlist=NULL;
l1.size=l2.size=;
l1.chlist="hello World!";
l1.size=strlen(l1.chlist)+;
//**************************
str=StrCopy(&l1,&l2);
printf("处理后字符串2:%s\n",str); return ;
}
实现了字符串的拷贝。
开始的时候汇编部分最后一行写法如下:
:"edi","esi","ecx","ebx"
编译出错:
StrCopy.c::: 错误: can’t find a register in class ‘CREG’ while reloading ‘asm’
StrCopy.c::: 错误: ‘asm’操作数中有不可能的约束
在网上查了一下原因,从一篇博文中得知:"edi","esi","ecx" 已经在输入列表中给出,会被修改寄存器列表再次给出,gcc就会报错。修改后编译通过。