c - 在汇编中计算字符串中的“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
我提前为使用全局变量道歉,我知道这不好但我仍在学习使用堆栈
解决方案
通过将 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
推荐阅读
- python - 用于在 Spark(Python)中过滤 RDD 的 Lambda 函数 - 检查元素是否不是空字符串
- oracle - 当人们以表格形式采取行动时,我触发了更新数据
- github - Github Desktop 说我自己的本地分支是“受保护的分支”,我无法提交。如何删除此保护?
- c# - 如何建议稍后自动添加的泛型类型?
- c# - DotNetCore SocketException“无法分配请求的地址”SmtpClient
- python - Python 多处理池打开新窗口
- perl - 如何获取值小于 n 的哈希中的条目数?
- python - 如何在 x 轴上绘制带有日期的折线图?错误:“Plotly Express 无法处理具有不同类型列的宽格式数据。”
- c# - 使用 Azure Active Directory 的 Blazor Sever 聊天应用程序在 Program.cs 中产生异常
- python - Ubuntu python Qt导入失败