2013-03-14 77 views
0

我試圖在NASM中編寫代碼來獲取給定字符串的長度。但是會給出一些垃圾值作爲長度。該代碼是以下之一:使用NASM的字符串的長度

section .data 
     a db "nitin",10,0 
     msg db "length = %d",10,0 
    section .text 
     global main 
     extern printf 
    main: 
     nop 
     xor eax,eax 
     mov eax, a 
     xor edx,edx 
    length: 
     mov dl, byte[eax] 
     cmp dl,0 
     je print 
     inc eax 
     jmp length 

    print: 
     pusha 
     push eax 
     push msg 
     call printf 
     add esp,8 
     popa 
    done: 
     nop 

結果顯示: 長度= 132445678

能否請你幫我理清我的錯誤?

謝謝

回答

6

EAX程式碼中有如下的字節,而不是字符串中的索引的地址。所以,而不是長度,你打印出終止空字符的地址。

要麼重新形成EAX從零開始讀取地址[a + eax]處的字節,要麼在打印出長度之前從EAX中減去a的地址。要麼會工作。

編輯:對於第一種方法,主循環是這樣的:

main: 
    nop 
    xor eax,eax ; removed the mov eax,a line - eax stays zero 
    xor edx,edx 
length: 
    mov dl, byte[a+eax]   ; eax is the index in the string 
    cmp dl,0 
    ;The rest stays the same 

對於第二種方法中,循環保持不變,但印刷部分得到一個額外的sub

print: 
    sub eax, offset b ; convert from address to index 
    pusha 
    push eax 
    push msg 
    ; The rest is the same 

然而,這將是最短途徑:

main: 
    nop 
    mov edi, a ; the string we're scanning 
    xor al, al ; That's what we're scanning the string for - a null valued byte 
    mov ecx, 0ffffffffh ; we bet on string being null terminated - no hard limit on string scanning 
    repne scasb ; Once this finishes, ECX is (0xffffffff - length - 1) (because the terminating null is counted too) 
    mov eax, 0fffffffeh 
    sub eax, ecx ; Now eax is (0xffffffff - 1 - ecx), which is string length 
print: 
    ; Same as before 

中查找scas命令以及如何將它與repxx前綴一起使用。這幾乎就像是在Intel CPU指令集中實現了一部分C RTL(strlen,strcpy等)。

在旁註中,片段有兩個完全無關的行 - xor eax, eaxxor edx, edx在函數的開頭。無論如何,兩個寄存器都將被覆蓋在下一行。

+0

謝謝你的回覆。我已經使用計數器寄存器ecx解決了它。然而,我想知道如何使用eax來解決這個問題,對不起,導師,我仍然沒有得到如何使用eax解決它。 – sabu 2013-03-14 15:12:40

+0

其實,最快的方法就是al rep = 0的'rep scasb'。讓你完全避免循環。 – 2013-03-14 18:27:27

+0

夢幻般的anaysis.A學生只需要這個.Fantastic,我的導師 – sabu 2013-03-15 07:47:52