首页 > 解决方案 > 尝试在 x86 GAS 中实现 strlen

问题描述

所以我对汇编编程非常陌生(非常新),并且正在尝试编写一个可以计算字符串长度的函数。

我觉得我在清除寄存器中的值或指针的增量时遇到了一些问题,因为返回的值对我来说始终是“4571 + 长度”。

基本上,如果我的字符串长度为 0,我会得到 4571 作为返回值。如果我的字符串长度为 6,我会得到 4577 作为返回值,等等。

这是我的代码,任何帮助将不胜感激:

.globl my_strlen
    my_strlen:
        pushq %rbp
        movq %rsp, %rbp
        pushq %r12
        pushq %r13

        movq $0, %rax
        cmp $0, (%rdi)
        jne my_strlen_loop
        ret

    my_strlen_loop:
        inc %rax
        inc %rdi
        cmp $0, (%rdi)
        jne my_strlen_loop

        popq %r13
        popq %r12
        popq %rbp
        ret

标签: x86x86-64gnu-assembler

解决方案


这段代码有两个问题。

首先,cmp指令没有指定大小,并且操作数都不是寄存器,所以它是模棱两可的。对于大多数指令(如mov $0, (%rdi)),GAS 会拒绝组装它,但cmp由于某种原因组装到cmpl,比较一个 dword。将助记符更改为cmpb显式。

其次,在第一次 ret 之前,它不会弹出被推送的寄存器。最好跳到最后(并有一个 ret)。


推荐阅读