简体   繁体   English

通过strlen调用获取NASM中的字符串长度

[英]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的输出取另一个名字即可:

  1. nasm -f elf32 getLength.asm -o getLength.o nasm -f elf32 getLength.asm -o getLength.o
  2. gcc -c length.c -o length.o -m32 gcc -c length.c -o length.o -m32
  3. gcc length.o getLength.o -o length -m32 gcc length.o getLength.o -o length -m32

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函数似乎不正确:

  1. You forgot to move the argument to strlen onto the stack. 你忘移动到参数strlen到堆栈。 push eax before calling strlen . 在调用strlen之前先push eax
  2. You moved the return value from eax into edx after calling strlen . 您在调用strlen之后将返回值从eax移到了edx This shouldn't be necessary since eax will already have the correct value. 因为eax已经具有正确的值,所以这不是必需的。
  3. Because you need to 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, 4mov esp, ebp来完成此操作,但是必须在pop ebp之前完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM