gpt4 book ai didi

linux汇编反转一个字符串

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:13 26 4
gpt4 key购买 nike

所以我正在用 c 编写一个内联汇编函数,它反转字符串的内容并将反转的字符串放入一个新的字符数组中,但是我在反转字符串的末尾添加了额外的字符。

int main(int argc, char **argv) {
char *new_str;
char old_str[20] = "Hello, World!";
mystrrev(new_str, old_str, strlen(old_str));
printf("New string: %s\n", &new_str);
return 0;
}

汇编函数

char *mystrrev(char *dest, const char *src, int size) {
int d0, d1, d2, d3;
__asm__ (
"add %%ebx, %%esi\n\t" /*Move to end of string*/
"std\n\t" /*Decrement esi after load*/
"lodsb\n\t" /*Load esi into al*/
"sub $1, %%ebx\n\t"
"mov %%al, %%cl\n\t" /*mov contents of al to cl*/
"1:\tstd\n\t" /*Begin loop, decrement esi after load*/
"lodsb\n\t" /*Load esi into al*/
"cld\n\t" /*Clear flg*/
"stosb\n\t" /*Store al in edi*/
"sub $1, %%ebx\n\t" /*subtract 1 from strlenght counter*/
"cmp $0, %%ebx\n\t" /*Compare ebx to 0*/
"jne 1b\n\t"
"mov %%ecx, %%edi\n\t" /*Add null terminating char to new str*/
: "=&S"(d0), "=&D"(d1), "=&a"(d2), "=&b" (d3) /*output*/
/*** &S --> ESI, &D --> EDI, &a --> eax ***/
: "0" (src), "1" (dest), "3" (size) /*input*/
: "memory"); /*clobber registers*/
return dest;
}

在这种情况下,你好,世界!被打印出来 [!dlroW, olleH] 但最后添加了额外的字符,我不知道为什么。有什么想法吗??

最佳答案

mov %ecx, %edi       /*Add null terminating char to new str*/

指令不会向内存写入任何内容;它只是将一个零复制到寄存器 %edi 本身。如果我没记错的话,内存写入的正确语法是这样的

movb %cl, (%edi)

但是在复制过程中将零终止符小心地存储在 %cl 中确实没有意义,因为您知道它无论如何都会是零。所以只是

movb $0, (%edi)

应该也能正常工作。

(此外,但无关紧要的是,字符串指令实际上比单独加载/存储和递增/递减操作的等效组合要慢。至少在 486 或奔腾时代早期就是这种情况,这会让我感到惊讶如果它仍然不是真的——特别是如果你每次都需要操纵方向标志)。

((另外,为您无论如何都不使用的所有内容声明输出变量似乎毫无意义。这有什么意义。即使您需要对 eax 的使用进行硬编码> 对于字符串指令,简单地在 clobber 列表中列出 "eax" 比将它强制到一个虚拟输出变量中要清晰得多))。

关于linux汇编反转一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7423816/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com