[英]Getting length of string in NASM with strlen call
我的目標是執行以下操作:
1)編寫一個nasm代碼,通過從C調用strlen來計算字符串的長度
2)在C中調用此函數以打印提供的字符串的長度
驗證碼:
;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長度-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
您覆蓋getLength.o
從NASM與gcc -c length.c -o getLength.o -m32
。 只需為GCC的輸出取另一個名字即可:
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
剩下一些多余的說明。 請檢查,如果您確實需要它們。
從收到的錯誤來看,似乎您在ASM文件之前而不是您所描述的之后編譯了C文件。
為了使事情復雜化,生成的目標文件將具有相同的文件名。 由於您上次編譯了ASM文件,因此getLength.o
是已編譯的ASM文件。
結果是您試圖鏈接多個名為getLength
函數(來自ASM文件),而根本沒有要鏈接的main
函數。
您可以通過為目標文件使用不同的名稱(例如,對於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
函數似乎不正確:
strlen
到堆棧。 在調用strlen
之前先push eax
。 strlen
之后將返回值從eax
移到了edx
。 因為eax
已經具有正確的值,所以這不是必需的。 push eax
,所以還需要在strlen
返回之后恢復堆棧指針。 您可以使用add esp, 4
或mov esp, ebp
來完成此操作,但是必須在pop ebp
之前完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.