Here is what I need to do.

I have a very small C program that takes user input and passes argv to a function written in GNU assembly language that will then count the number of characters in the string.

The function seems to work fine when I enter a string as a variable directly in the program, but when I try to pass it from C, it gives me an incorrect count.

Here is my C code:

#include <stdio.h>
#include <stdlib.h>

extern int my_strlen(char*);

main(int argc, char *argv[])
        printf("\nThe number of characters is %i\n\n.", my_strlen(argv[1]));

        return 0;

Here is my assembly code. Please note that I need to keep this as a loop.

.globl my_strlen          
.type my_strlen, @function


pushl %ebp             
movl %esp, %ebp        

movl 8(%ebp), %ebx
movl $0, %eax          


incl %ebx              

cmpl $0, (%ebx)        

je end_loop            

incl %eax              

jmp loop               


cmpl $0, %eax          

je empty               

jmp not_empty          

decl %eax              


movl %ebp, %esp       
popl %ebp              


If I run the application "./test test", it gives me a character count of 1188. It should be 4...


Recommended Answers

All 7 Replies

You don't need that loop at all -- just set up al, eax then call rep scasb to search for the string length

I give you an advice:
If your string is of type char (1 byte), why are you comparing double words (cmpl), may be you need cmpb (byte).
Another one:
You increment ebx before comparing the first character.
I hope that this can be useful.

you mean esp not ebx. ebx is a general purpose register which does not need to be restored.

Look at:
or look at:
or at:
Who is wrong?.
Another comment is that string opcodes are slower than a well optimized algoritm. Which is not the reference code.
The problem of restoring ebx can be solved using another register, maybe edx.


commented: Yes, I was incorrect +36

I doubt between two options, but I put the shortest one. Try the next code:

.global _my_strlen


pushl %ebp
movl %esp, %ebp

movl 8(%ebp), %edx
movl $0xFFFFFFFF, %eax


inc %eax
cmpb $0, (%edx , %eax)

jne loop

movl %ebp, %esp
popl %ebp

The other solution is increment edx and not to use eax in the comparison. It can be timed, but I think this code is not so important.


A correction to my code:
You can erase:
movl %ebp, %esp
We are not using stack local space. esp is not modified.


Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.