在汇编中计算字符串中的“0”

counting the '0's in a string in assembly

我有一个用 c 和汇编编写的小程序。原理很简单:“计算 main.c

给出的字符串中的‘0’

所以对于 test0 str0ing 0 它应该 return 3 因为字符串中有 3 个'0' 该函数本身是使用 AT&T 语法在 x86 asm 中创建的,我通过 C 获得了一个指向字符串的指针。main.c 和 asm 都通过头文件链接。

到目前为止,这是我的代码,问题是它总是 returns 0。它永远不会达到条件跳转以递增 %eax(returned)

// C

#include "asm.h"

char string[] = "2a0 a0 ";
char *ptr1 = string;

int main(){
    
    printf("\nthere are : %d %s in :%s", zero_count(), "0s", string);
    printf("\nstring address is: %p\n", ptr1);
    
    return 0;
}

// x86asm

    .global ptr1

.section .text
    .global zero_count          #func()
    

zero_count:

    # prologue
    pushl %ebp              # save these previous stack frame pointer
    movl %esp, %ebp         # the stack frame pointer for function
    
    # save registers
    #pushl $ebx             # needs to be pushed out of stack when used
    #pushl %esi             # needs to be pushed out of stack when used
    #pushl %edi             # needs to be pushed out of stack when used
    
    # function body
    movl ptr1, %ecx         # moves the value of ptr1 to ecx
    movl [=11=], %eax           # cleans eax with 0
                    
    # loop start
    loop_beginning:
        cmp [=11=], (%ecx)
        je end
        
        # compare to 'o'
        cmp , %ecx       # 48 is "0" in the asci table
        je if_0
        
        increment_pointer:
            addl , %ecx
            jmp loop_beginning
        
        if_0:
            addl , %eax
            jmp increment_pointer
            
    end:
    #popl %edi              # needs to be popped when used
    #popl %esi              # needs to be popped when useds
    #popl %ebx              # needs to be popped when used
    
    # epilogue
    movl %ebp, %esp         # restore the previous stack pointer("cleaner" the stack)
    popl %ebp               # restore the previous stack frame pointer
    ret                     #w returns

提前使用全局变量表示歉意,我知道这不好,但我还在学习使用堆栈

通过将 cmp 切换为 cmpb 在此字符串中工作。但我仍然不知道为什么。如果这是一个 int[]?

,这个操作也会起作用吗?
    .global ptr1

.section .text
    .global zero_count          #func()
    

zero_count:

    # prologue
    pushl %ebp              # save these previous stack frame pointer
    movl %esp, %ebp         # the stack frame pointer for function
    
    # save registers
    #pushl $ebx             # needs to be pushed out of stack when used
    #pushl %esi             # needs to be pushed out of stack when used
    #pushl %edi             # needs to be pushed out of stack when used
    
    # function body
    mov ptr1, %ecx          # moves the value of ptr1 to ecx
    movl [=10=], %eax           # cleans eax with 0
                    
    # loop start
    loop_beginning:
        cmpb [=10=], (%ecx)
        je end
        
        # compare to 'o'
        cmpb , (%ecx)        # 48 is "0" in the asci table
        je if_0
        
        increment_pointer:
            addl , %ecx
            jmp loop_beginning
        
        if_0:
            addl , %eax
            jmp increment_pointer
            
    # movl (%ecx), %eax
    
    end:
    #popl %edi              # needs to be popped when used
    #popl %esi              # needs to be popped when useds
    #popl %ebx              # needs to be popped when used
    
    # epilogue
    movl %ebp, %esp         # restore the previous stack pointer("cleaner" the stack)
    popl %ebp               # restore the previous stack frame pointer
    ret                     #w returns