2015-10-04 98 views
1

我的目标是要做到以下几点:获取字符串的长度在NASM与strlen的通话

1)编写调用由C

2的strlen计算字符串长度的NASM代码)调用此在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。 ø-m32

3)的gcc getLength.o getLength.o -o长度-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 

回答

3

从你得到的错误判断,你看起来是在ASM文件之前编译了C文件,而不是像你所描述的那样。

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

结果是,您尝试链接名为getLength(来自ASM文件)的多个函数,并且根本没有main函数进行链接。

您可以通过使用不同的名称为目标文件(例如,对于C文件length.ogetLength.o为ASM文件)修正:

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. 您忘记将参数移动到堆栈上的strlenpush eax,然后致电strlen
  2. 在拨打strlen之后,您将返回值从eax移至edx。这应该不是必需的,因为eax已经具有正确的值。
  3. 因为您需要push eax,您还需要在strlen返回后恢复堆栈指针。您可以使用add esp, 4mov esp, ebp来完成此操作,但它必须在pop ebp之前完成。
+0

是的。这是编译技巧!然而,在我的NASM代码中似乎有某种错误,因为我得到了0的结果。 – SpiderRico

+0

完美!非常感谢。 – SpiderRico

4

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

  1. nasm -f elf32 getLength.asm -o getLength。Ø
  2. GCC -c length.c -o length.o -m32
  3. GCC length.o getLength.o -o长度-m32

GCC是足够聪明,你可以折叠步2.和3 .:

2 + 3。 GCC length.c getLength.o -o长度-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 

有留下了一些多余的说明。请检查,如果你真的需要它们。