2015-10-04 94 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 

有留下了一些多餘的說明。請檢查,如果你真的需要它們。