我最近开始研究汇编代码,我试图重新编写一些基本的系统功能来掌握它,目前我在strchr上遇到了0x0的分段错误。
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来测试
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);
}发布于 2018-03-18 11:16:28
问题
紧跟在good标签后面的指令:
mov rax, [rdi + rcx]实际上应该是:
lea rax, [rdi + rax]您根本没有使用rcx,而是rax,您需要的是该位置的地址,而不是该位置的值(即lea而不是mov)。
一些建议
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结束
rax寄存器的典型的rax既不是mov rax, 0也不是xor rax, rax,而是xor eax, eax,因为它没有直接零的编码,并且保存了一个字节。有了上面的更正和建议,代码如下所示:
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
rethttps://stackoverflow.com/questions/49346921
复制相似问题