在汇编中计算字符串中的“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
我有一个用 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