我编写了一个代码,用gcc内联汇编获取字符串的子字符串。但是当我想得到长度为8的子字符串时总是会遇到问题。这是代码
static inline char * asm_sub_str(char *dest, char *src, int s_idx, int edix)
{
__asm__ __volatile__("cld\n\t"
"rep\n\t"
"movsb"
:
:"S"(src + s_idx), "D"(dest), "c"(edix - s_idx + 1)
);
return dest;
}
int main(int argc, char *argv[])
{
char my_string[STRINGSIZE] = "abc defghij";
char asm_my_sub_string[STRINGSIZE];
int sidx,eidx;
sidx = 0;
eidx = 5;
char *d1 = asm_sub_str(asm_my_sub_string, my_string, sidx, eidx);
printf("d1[%d-%d]: %s\n",sidx, eidx, d1);
sidx = 0;
eidx = 7;
d1 = asm_sub_str(asm_my_sub_string, my_string, sidx, eidx);
printf("d1[%d-%d]: %s\n",sidx, eidx, d1);
sidx = 0;
eidx = 9;
d1 = asm_sub_str(asm_my_sub_string, my_string, sidx, eidx);
printf("d1[%d-%d]: %s\n",sidx, eidx, d1);
}
这是输出
d1[0-5]: abc de
d1[0-7]: abc defg?
d1[0-9]: abc defghi
任何想法?????
感谢您的回复。这是子串的c代码,我忘了null终止字符串。感谢cactus和bbonev!希望其他人可以从这个帖子中学习。
static inline char * sub_str(char *dest, char *src, int s_idx, int edix)
{
int length = edix - s_idx + 1;
int i;
for(i = 0; i < length; i++)
{
*(dest + i) = *(src + s_idx + i);
}
*(dest + length) = '\0';
return dest;
}
答案 0 :(得分:0)
我认为它不起作用,因为汇编代码不会终止结果缓冲区。
我总是更喜欢带有起始位置和计数的子串语义,而不是两个位置。人们认为这样的话会更容易。
无需从此函数返回任何值。
static inline void asm_sub_str(char *dest, char *src, int s_idx, int count)
{
__asm__ __volatile__("cld\n"
"rep\n"
"movsb\n"
"xor %%al,%%al\n"
"stosb\n"
:
:"S"(src + s_idx), "D"(dest), "c"(count)
);
}
编辑:请注意,尽管使用汇编编写,但这种实现还不是很理想。对于特定的体系结构,内存对齐和字大小对于速度很重要,并且执行复制的最佳方法可能是通过对齐的机器大小字。首先一个一个地复制到字大小为1个字节,然后用字复制字符串的大部分,最后完成最后一个字大小为1个字节。
我将问题视为内联汇编和传递参数的excersize,而不是复制字符串的最佳方法。使用现代C编译器,预计会生成更快的代码。