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

时间:2015-10-04 18:55:41

标签: c linux nasm

我的目标是做到以下几点:

1)编写一个nasm代码,通过从C

调用strlen来计算字符串的长度

2)在C中调用此函数以打印提供的字符串的长度

Nasm代码:

    ;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代码:

#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;
}

我尝试编译,链接和运行如下:

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

我得到的错误:

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

2 个答案:

答案 0 :(得分:4)

您使用getLength.o覆盖NASM中的gcc -c length.c -o getLength.o -m32。只需为GCC的输出取另一个名称:

  1. nasm -f elf32 getLength.asm -o getLength.o
  2. gcc -c length.c -o length.o -m32
  3. gcc length.o getLength.o -o length -m32
  4. GCC足够聪明,你可以崩溃第2步和第3步:

    2 + 3。 gcc length.c getLength.o -o length -m32

    您忘记将参数传递给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
    

    还有一些多余的指示。如果你确实需要,请检查。

答案 1 :(得分:3)

从您得到的错误判断,您似乎在ASM文件之前编译了C文件,而不是在您描述之后。

要使事情复杂化,生成的目标文件将具有相同的文件名。由于您最后编译了ASM文件,因此getLength.o是已编译的ASM文件。

结果是您尝试链接多个名为getLength的函数(来自ASM文件),而您根本没有main函数可以链接。< / p>

您可以通过为目标文件使用不同的名称来修复它(例如,对于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

顺便说一下,您的getLength功能似乎不正确:

  1. 您忘记将参数移至strlen到堆栈上。在致电push eax之前strlen
  2. 您在致电eax后将返回值从edx移至strlen。这不应该是必要的,因为eax已经具有正确的值。
  3. 因为您需要push eax,所以还需要在strlen返回后恢复堆栈指针。您可以使用add esp, 4mov esp, ebp来完成此操作,但必须在pop ebp之前完成。