My aim is to do the following:
1) Write a nasm code that calculates the length of a string by calling strlen from C
2) Call this function in C to print the length of a supplied string
Nasm code:
;nasm -f elf32 getLength.asm -o getLength.o
segment .text
extern strlen
global getLength
getLength:
push ebp ;save the old base pointer value
mov ebp,esp ;base pointer <- stack pointer
mov eax,[ebp+8] ;first argument
call strlen ; call our function to calculate the length of the string
mov edx, eax ; our function leaves the result in EAX
pop ebp
ret
C code:
#include <stdio.h>
#include <string.h>
int getLength(char *str);
int main(void)
{
char str[256];
int l;
printf("Enter string: ");
scanf("%s" , str) ;
//l = strlen(str);
l = getLength(str);
printf("The length is: %d\n", l);
return 0;
}
I try to compile, link and run as follows:
1) nasm -f elf32 getLength.asm -o getLength.o
2) gcc -c length.c -o getLength.o -m32
3)gcc getLength.o getLength.o -o length -m32
The error I get:
getLength.o: In function `getLength':
getLength.asm:(.text+0x0): multiple definition of `getLength'
getLength.o:getLength.asm:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib32/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
You overwrite the getLength.o
from NASM with gcc -c length.c -o getLength.o -m32
. Just take another name for the output of GCC:
GCC is smart enough, that you can collapse step 2. and 3.:
2+3. gcc length.c getLength.o -o length -m32
You forgot to pass an argument to strlen
and to clear the stack afterwards:
getLength:
push ebp ;save the old base pointer value
mov ebp,esp ;base pointer <- stack pointer
mov eax,[ebp+8] ;first argument
push eax ; first argument onto the stack
call strlen ; call our function to calculate the length of the string
add esp, 4 ; clear stack after C-call
mov edx, eax ; our function leaves the result in EAX
pop ebp
ret
There are left some superfluous instructions. Please check, if you really need them.
Judging from the error you get, it would seem you compiled the C file before the ASM file, not after as you described.
To complicate things, the resulting object files will have the same filename. Since you compiled the ASM file last, getLength.o
is the compiled ASM file.
The result is that you're trying to link multiple functions named getLength
(from the ASM file) and you don't have a main
function to link at all.
You can fix it by using different names for the object files (eg length.o
for the C file and getLength.o
for the ASM file):
gcc -c length.c -o length.o -m32
nasm -f elf32 getLength.asm -o getLength.o
gcc length.o getLength.o -o length -m32
By the way, your getLength
function appears to be incorrect:
strlen
onto the stack. push eax
before calling strlen
. eax
into edx
after calling strlen
. This shouldn't be necessary since eax
will already have the correct value. push eax
, you also need to restore the stack pointer after strlen
returns. You can either use add esp, 4
or mov esp, ebp
to accomplish this, but it must be done before you pop ebp
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.