[英]Getting length of string in NASM with strlen call
My aim is to do the following: 我的目标是执行以下操作:
1) Write a nasm code that calculates the length of a string by calling strlen from C 1)编写一个nasm代码,通过从C调用strlen来计算字符串的长度
2) Call this function in C to print the length of a supplied string 2)在C中调用此函数以打印提供的字符串的长度
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: C代码:
#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 1)nasm -f elf32 getLength.asm -o getLength.o
2) gcc -c length.c -o getLength.o -m32 2)gcc -c length.c -o getLength.o -m32
3)gcc getLength.o getLength.o -o length -m32 3)gcc getLength.o getLength.o -o长度-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
. 您覆盖getLength.o
从NASM与gcc -c length.c -o getLength.o -m32
。 Just take another name for the output of GCC: 只需为GCC的输出取另一个名字即可:
GCC is smart enough, that you can collapse step 2. and 3.: GCC非常聪明,您可以折叠第2步和第3步:
2+3. 2 + 3。 gcc length.c getLength.o -o length -m32 gcc length.c getLength.o -o length -m32
You forgot to pass an argument to strlen
and to clear the stack afterwards: 您忘记传递参数给strlen
然后再清除堆栈:
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. 从收到的错误来看,似乎您在ASM文件之前而不是您所描述的之后编译了C文件。
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. 由于您上次编译了ASM文件,因此getLength.o
是已编译的ASM文件。
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. 结果是您试图链接多个名为getLength
函数(来自ASM文件),而根本没有要链接的main
函数。
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): 您可以通过为目标文件使用不同的名称(例如,对于C文件为length.o
和对于ASM文件为getLength.o
)来解决此问题:
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: 顺便说一句,您的getLength
函数似乎不正确:
strlen
onto the stack. 你忘移动到参数strlen
到堆栈。 push eax
before calling strlen
. 在调用strlen
之前先push eax
。 eax
into edx
after calling strlen
. 您在调用strlen
之后将返回值从eax
移到了edx
。 This shouldn't be necessary since eax
will already have the correct value. 因为eax
已经具有正确的值,所以这不是必需的。 push eax
, you also need to restore the stack pointer after strlen
returns. 因为需要push eax
,所以还需要在strlen
返回之后恢复堆栈指针。 You can either use add esp, 4
or mov esp, ebp
to accomplish this, but it must be done before you pop ebp
. 您可以使用add esp, 4
或mov esp, ebp
来完成此操作,但是必须在pop ebp
之前完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.