首页 > 解决方案 > 在汇编中计算字符串中的“0”

问题描述

我有一个用 c 和汇编编写的小程序。原理很简单:“计算 main.c 给出的 aa 字符串中的‘0’

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

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

// 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 $0, %eax           # cleans eax with 0
                    
    # loop start
    loop_beginning:
        cmp $0, (%ecx)
        je end
        
        # compare to 'o'
        cmp $48, %ecx       # 48 is "0" in the asci table
        je if_0
        
        increment_pointer:
            addl $1, %ecx
            jmp loop_beginning
        
        if_0:
            addl $1, %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

我提前为使用全局变量道歉,我知道这不好但我仍在学习使用堆栈

标签: cstringassemblyx86att

解决方案


通过将 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 $0, %eax           # cleans eax with 0
                    
    # loop start
    loop_beginning:
        cmpb $0, (%ecx)
        je end
        
        # compare to 'o'
        cmpb $48, (%ecx)        # 48 is "0" in the asci table
        je if_0
        
        increment_pointer:
            addl $1, %ecx
            jmp loop_beginning
        
        if_0:
            addl $1, %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

推荐阅读