2016-03-10 34 views
2

我實際上試圖理解英特爾x64語法中NASM程序集的基本概念,但在嘗試製作相當於strchr時遇到問題...如何比較一個字符串中的字符與NASM x86_64中的另一個字符Linux組裝

我一直在航行網絡獲取最大的信息,但我不明白如何比較一個字符串(如str [i])的當前字符與簡單的字符。

下面是測試主:

#include <stdio.h> 

extern char* my_strchr(char*, char); 

int  main(void) 
{ 
    char* str; 

    str = my_strchr("foobar", 'b'); 
    printf("%s\n", str); 
    return 0; 
} 

這裏是我的彙編代碼:

我認爲RDI是我的字符串和RSI我的一個字節的數據。

my_strchr: 
    push rcx     ;Save our counter 
    xor  rcx, rcx    ;Set it to 0 
loop: 
    cmp  rdi, byte 0   ;Check the end of string 
    jz  end 
    cmp  rsi, [byte rdi+rcx] ;Here is the point ... 
    jz  end 
    inc  rcx     ;increment our counter 
    jmp  loop 
end: 
    mov  rax, [rdi+rcx]  ;Are the brackets needed ? Is it equivalent to '&' in C ? 
    pop  rcx 
    ret 

GDB給了我這個輸出C語言編寫,所以strchr函數分解:

.... 
cmp al,BYTE PTR [rbp-0x1c] 
.... 

但礦實際上是這樣做的:

0x400550 <my_strchr>   push rcx 
0x400551 <my_strchr+1>   xor rcx,rcx 
0x400554 <loop>     cmp rdi,0x0 
0x400558 <loop+4>    je  0x400566 <end> 
0x40055a <loop+6>    cmp rsi,QWORD PTR [rdi+rcx*1+0x0] 

預先感謝您,希望有人會知道

回答

1

rdi是一個指針,所以cmp rdi, 0檢查一個空指針。你的意思是cmp byte [rdi + rcx], 0檢查字符串的結尾。請注意,您需要檢查當前字符,因此必須明顯添加索引。

至於cmp rsi, [byte rdi+rcx]byte沒有任何意義,因爲你是比較整個rsi這是8字節。那應該是cmp sil, [rdi + rcx]

最後,strchr應該返回一個指針,因此您應該將mov rax, [rdi+rcx]更改爲lea rax, [rdi + rcx]

+0

謝謝!經過你的解釋,從現在起,一切似乎都很清楚 我剛剛發現了「lea」指令和sil(操作數?)我應該如何知道何時適當地使用它們以適應未來? – Cegree

+0

您可以處理較小部分的寄存器,請參閱手冊以獲取名稱。只要你需要更小的單位,你就可以使用它們。 'lea'對尋址或一些簡單的算術很有用。你可以用'mov rax,rdi;添加rax,rcx'。 – Jester

相關問題