我最近开始研究汇编代码,我正在尝试重新编码一些基本的系统函数来控制它,我目前在我strchr
上的0x0处遇到了分段错误。< / p>
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中使用以下主要测试
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);
}
答案 0 :(得分:5)
紧跟good
标签后的说明:
mov rax, [rdi + rcx]
实际应该是:
lea rax, [rdi + rax]
您根本没有使用rcx
,但是rax
,您需要的是该位置的地址,而不是该位置的值(即lea
而不是mov
)。
请注意,典型的idiom for comparing sil
against zero实际上是test sil, sil
而不是cmp sil, 0
。那就是:
test sil, sil
jz end
但是,如果我们查看strchr(3)
man page,我们可以找到以下内容:
char *strchr(const char *s, int c);
终止 null字节被认为是字符串的一部分,因此如果将
c
指定为&#39;\0'
,这些函数将返回指向终结符的指针。
因此,如果我们希望此strchr()
实现的行为与手册页中所述相同,则必须删除以下代码:
cmp sil, 0
jz end
rax
注册表的典型zeroing idiom既不是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
ret
编码为立即零,并为后者保存一个字节。
通过上述更正和建议,代码如下所示:
select json_query ('{"name":"' + lookupvalue + '"}') as 'disk'
from tblDataInfo
where lookupkey = 'diskname'
for json path;