如何使用NASM找到字符串的长度?

时间:2011-06-24 13:28:57

标签: linux string assembly x86 nasm

我正在尝试使用从命令行参数获取输入的NASM来创建程序。由于没有提供字符串长度,我正在尝试创建一个计算我自己的函数。这是我的尝试,它获取指向ebx寄存器中字符串的指针,并返回ecx中字符串的长度:

len:
    push ebx
    mov ecx,0
    dec ebx
    count:
        inc ecx
        inc ebx
        cmp ebx,0
        jnz count
    dec ecx
    pop ebx
    ret

我的方法是逐个字符地检查字符串,并检查它是否为空。如果不是,我递增ecx并转到下一个字符。我认为问题是cmp ebx,0对于我正在尝试做的事情是不正确的。我如何正确地检查字符是否为空?另外,还有其他我可以做得更好的事情吗?

3 个答案:

答案 0 :(得分:4)

您正在将ebx中的值与0进行比较,这不是您想要的。 ebx中的值是内存中字符的地址,因此应该取消引用,如下所示:

cmp byte[ebx], 0

此外,最后push ebx应为pop ebx

答案 1 :(得分:1)

以下是我在检查argv[1]的64位Linux可执行文件中的操作方法。内核在堆栈上启动了一个argcargv[]的新进程,如x86-64 System V ABI中所述。

_start:
    pop    rsi              ; number of arguments (argc)
    pop    rsi              ; argv[0] the command itself (or program name)
    pop    rsi              ; rsi = argv[1], a pointer to a string
    mov    ecx, 0           ; counter
.repeat:
    lodsb                   ; byte in AL
    test   al,al            ; check if zero
    jz     .done            ; if zero then we're done
    inc    ecx              ; increment counter
    jmp    .repeat          ; repeat until zero
.done:
    ; string is unchanged, ecx contains the length of the string


; unused, we look at command line args instead
section .rodata
    asciiz:    db    "This is a string with 36 characters.", 0

这是缓慢而低效的,但很容易理解。

为了提高效率,你需要

当然SSE2总是在x86-64中可用,所以我们应该使用它来检查16个字节的块(在到达对齐边界之后)。请参阅glibc中优化的手写strlen实现。 (https://code.woboq.org/userspace/glibc/sysdeps/x86_64/strlen.S.html)。

答案 2 :(得分:0)

这是我如何编码的

len:
      push ebx
      mov  eax, ebx
lp:
        cmp byte [eax], 0
        jz  lpend
        inc eax
        jmp lp
lpend:
        sub eax, ebx

      pop ebx
      ret

(结果在eax中)。可能有更好的方法。