2017-06-27 22 views
1

我目前正在按照Kip Irvine的「彙編語言x86編程」一書學習彙編編程。以零結尾的字符串和在x86彙編語言中不以null結尾的字符串之間有什麼區別

在該書中,作者指出

串的最常見的類型與(含0)一個空字節結束。 叫了個空值終止字符串

在本書的後續部分,筆者有一個字符串,例如沒有空字節

greeting1 \ 
BYTE "Welcome to the Encryption Demo program " 

所以我只是想知道,什麼是之間的不同null終止的字符串和在x86彙編語言中不以null結尾的字符串?它們可以互換嗎?或者他們不是彼此等同?

+2

如何獲得'greeting2'的長度?使用'greeting1',您可以查找第一個空字節。例1類似於C,例2類似於Java(Java'String'存儲長度)。 –

+0

@ElliottFrisch感謝您的評論。糾正我,如果我錯了,但我對x86彙編語言字符串的理解是:字符串可以定義有或沒有null在最後,我們可以確定字符串的長度在最後null,但同樣不能爲沒有null的字符串完成。我的理解是否正確?還有其他的區別嗎? – Thor

+1

考慮還存儲可能包含多個'\ 0'(s)的字符串。我真的不能想到另一個。但也許你可以。祝你好運。 –

回答

3

這裏沒有什麼特別的asm;這與C中的問題是一樣的。關於如何將字符串存儲在內存中並跟蹤它們結束的位置。

以空結尾的字符串和不以null結尾的字符串之間有什麼不同?

一個空結束的字符串有後一個0字節,所以你可以找到與strlen結束。 (或rep scasb)。這可以用作隱式長度字符串,就像C用法一樣。

它們是可以互換的嗎?

如果您知道空終止字符串的長度,您可以將指針+長度傳遞給需要顯式長度字符串的函數。該函數永遠不會查看0字節,因爲您將傳遞一個不包含0字節的長度。這不是字符串數據的一部分。

但是,如果你有一個沒有終結符的字符串,你不能將它傳遞給一個函數或系統調用,它需要一個以空字符結尾的字符串。 (如果內存是可寫的,你可以在字符串後存儲0,使之變成一個空結尾的字符串。)


在Linux中,許多系統調用需要字符串作爲C風格的隱含長度空值終止字符串。 (即只是一個char*而不通過一段長度)。

例如,open(2)需要一個字符串作爲路徑:int open(const char *pathname, int flags);您必須將一個以空字符結尾的字符串傳遞給系統調用。在Linux中創建一個名稱包含'\0'的文件是不可能的(與其他大多數Unix系統一樣),因爲處理文件的所有系統調用都使用以空字符結尾的字符串。

OTOH,write(2)需要一個內存緩衝區,它不一定是一個字符串。它有簽名ssize_t write(int fd, const void *buf, size_t count);。它不關心在buf+count0,因爲它只查看從bufbuf+count-1的字節。

可以將字符串傳遞給write()。它不關心。它基本上只是內核頁面緩存的一個memcpy(或者到一個管道緩衝區或任何非常規文件)。但就像我說的,你不能通過一個任意的非終止緩衝區作爲路徑參數爲open()

或者它們並不相等?

隱式長度和顯式長度是跟蹤內存中字符串數據/常量並傳遞它們的兩種主要方式。他們解決同樣的問題,但方式相反。

如果您有時需要在穿過它們之前找到它們的長度,那麼長的隱式長度字符串是一個不錯的選擇。通過字符串循環比讀取整數要慢很多。查找隱式長度字符串的長度爲O(n),但顯式長度的字符串當然是O(1)時間來查找長度。 (這是已知的!)。至少以字節爲單位的長度是已知的,但如果使用UTF-8或UTF-16等可變長度編碼,則Unicode字符的長度可能不知道。

2

字符串如何終止與程序集無關。從歷史上看,'$',CRLF [10,13]或[0A,0D]在Linux下與GEDIT有時相反。約定取決於系統如何與自身或其他系統進行交互。舉個例子,我的應用程序嚴格圍繞着ASCII,因此,如果我讀取的是UTF-8或16的文件,我的應用程序就會失敗。 NULL或任何類型的終止都可以是可選的。

考慮這個例子

Title: db 'Proto_Sys 1.00.0', 0, 0xc4, 0xdc, 0xdf, 'CPUID', 0, 'A20', 0 
     db 'AXCXDXBXSPBPSIDIESDSCSSSFSGS' 
Err00: db 'Retry [Y/N]', 0 

我實現了,如果CX = 0,那麼它假設一個NULL結尾的字符串是要顯示其中一個套路,否則只有一個字符被讀取並重復CX次。這就是爲什麼0xc4 0xdc 0xdf未終止。同樣,'重試[Y/N]'之前沒有終止符,因爲我的算法的設計方式不需要。

你需要關心的唯一事情是數據的來源是什麼,或者你的應用程序需要與其他東西兼容。然後你只需簡單地實現你需要的任何工具。

相關問題