1

我有一个关于计算字符串长度的问题。我总是得到一些像 2432 这样的数字,你传递一个像“abc”这样的字符串。

我认为问题出在这一行

mov bl, byte [esi]

但我不知道为什么。也许它是以位为单位的字符长度?

问题可能出在 64 位操作系统或双核处理器上吗?(我有点怀疑,因为我认为第一行“第 32 位”应该可以解决问题)。

PS.:这是一个练习,这就是为什么我需要像这样确定字符串的长度。

编码:

bits 32
extern _printf
extern _scanf
global _main

section .data
number_frmt db 10,"%d",10,0
enter_str db "Enter some string: ", 10,0
string_frmt db "%s", 0

section .bss
entered_string resb 100

section .text

_main:
    pushad

    push dword enter_str
    call _printf
    add esp, 4

    push dword entered_string
    push dword string_frmt
    call _scanf
    add esp, 4  ;leave the entered string in the stack

    call count  ; count it and put the result to eax

    push dword eax
    push dword number_frmt
    call _printf
    add esp, 12

    popad
    ret

count:
    push esi    ;save it
    push ebx    ;save it
    mov eax, 0  ;init eax=0
    mov esi, [esp+12] ;put the entered string to esi

.loop:
    mov bl, byte [esi]  ;get the first char
    inc eax             ;eax++
    add esi,1           ;point to next char
    cmp bl,10           ;is it new line?
    jne .loop           ;if not loop
    dec eax             ;eax-- (because of newline at the end)
    pop ebx             ;retrieve ebx
    pop esi             ;retrieve esi
    ret
4

2 回答 2

5
cmp bl,10           ;is it new line?

应该

cmp bl,0

因为 c/c++ 字符串每次都以 0 结尾/终止,所以实际上您已经在内存中搜索了下一个 10 所在的随机位置。

于 2010-07-17T16:25:35.697 回答
1

使用 scanf 可能不是一件好事,因为它会混淆问题,用gets切换,新行也是有效字符,应该算作计数的一部分。字符串被 NUL 终止(自动)

count:
    push esi    ;save it
    push ebx    ;save it
    xor eax, eax; initialize it to zero
    mov esi, [esp+12] ;put the entered string to esi

.loop:
    mov bl, byte [esi]  ;get the first char

    cmp bl, bl          ;set the flags
    jz  .out            ;nul character

    inc eax
    jmp .loop

    pop ebx             ;retrieve ebx
    pop esi             ;retrieve esi

    ret
于 2010-07-17T19:04:06.650 回答