首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与strchr()函数实现有关

与strchr()函数实现有关
EN

Stack Overflow用户
提问于 2018-03-18 10:39:18
回答 1查看 536关注 0票数 1

我最近开始研究汇编代码,我试图重新编写一些基本的系统功能来掌握它,目前我在strchr上遇到了0x0的分段错误。

代码语言:javascript
复制
section .text
global strchr

strchr:
    xor rax, rax

loop:
    cmp BYTE [rdi + rax], 0
    jz end

    cmp sil, 0
    jz end

    cmp BYTE [rdi + rax], sil
    jz good

    inc rax
    jmp loop

good:
    mov rax, [rdi + rcx]
    ret

end:
    mov rax, 0
    ret

我不知道如何使用GDB来调试它,而且我看到的文档非常有限,或者很难理解。

我在C中使用了下面的main来测试

代码语言:javascript
复制
extern char *strchr(const char *s, int c);

int main () {
   const char str[] = "random.string";
   const char ch = '.';
   char *ret;

   ret = strchr(str, ch);
   printf("%s\n", ret);
   printf("String after |%c| is - |%s|\n", ch, ret);

   return(0);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-18 11:16:28

问题

紧跟在good标签后面的指令:

代码语言:javascript
复制
mov rax, [rdi + rcx]

实际上应该是:

代码语言:javascript
复制
lea rax, [rdi + rax]

您根本没有使用rcx,而是rax,您需要的是该位置的地址,而不是该位置的值(即lea而不是mov)。

一些建议

  1. 注意,典型的 against zero实际上是test sil, sil而不是cmp sil, 0。届时将: sil,sil jz端 但是,如果我们查看 man page,我们可以发现以下内容: char *strchr(const char *s, int c); 终止空字节被认为是字符串的一部分,因此如果将c指定为'\0'‘,这些函数将返回指向终止符的指针。

因此,如果我们希望这个strchr()实现像手册页中所描述的那样运行,那么必须删除以下代码:

cmp sil,0 jz结束

  1. 用于rax寄存器的典型的rax既不是mov rax, 0也不是xor rax, rax,而是xor eax, eax,因为它没有直接零的编码,并且保存了一个字节。

有了上面的更正和建议,代码如下所示:

代码语言:javascript
复制
section .text
global strchr

strchr:
    xor eax, eax

loop:
    ; Is end of string?
    cmp BYTE [rdi + rax], 0
    jz end

    ; Is matched? 
    cmp BYTE [rdi + rax], sil
    jz good

    inc rax
    jmp loop

good:
    lea rax, [rdi + rax]
    ret

end:
    xor eax, eax
    ret
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49346921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档