有 [] 操作類似于高級語言中的取消參考。那么這是否意味著每個變數和暫存器名稱都只是一個指標,或者指標是高級語言的想法并且在匯編中沒有用處?
uj5u.com熱心網友回復:
指標在 asm 中是一個有用的概念,但我不會說符號名稱是真正的指標。它們是地址,但它們不是指標,因為沒有存盤它們(元資料除外,并嵌入到機器代碼中),因此您無法修改它們。指標可以遞增。
變數是一個高級概念,在匯編中并不真正存在。Asm 有標簽,您可以將它們放在任何部分的任何位元組位置,包括.data、.text或其他。除了諸如 之類的指令dd外,您還可以為全域變數保留空間并為其附加符號。(但是變數的值可以暫時在暫存器中,或者如果它是區域變數,則可以在其整個生命周期中。變數的高級概念不必映射到帶有標簽的靜態存盤。)
像整數和指標這樣的型別在匯編中也不存在。一切都只是可以加載到整數、XMM 甚至 x87 FP 暫存器中的位元組。eax(如果您使用將 a 的位元組從一個記憶體位置復制到另一個記憶體位置,您實際上不必將其視為型別雙關語到整數并回傳float,您只是在加載和存盤以復制位元組。)
但另一方面,指標是一個足夠低級的概念,在匯編中仍然具有高度相關性。我們有堆疊指標(RSP),它通常保存一個有效地址,指向我們用作堆疊空間的一些記憶體。(不過,您可以使用 RSP 暫存器來保存不是有效地址的值。在這種情況下,您不會將其用作指標。但在任何時候您都可以執行push指令或mov eax, [rsp],并導致無效地址。)
指標是保存另一個物件地址的物件。 (我在這里使用 C 術語中的“物件”:您可以訪問的任何 byte[s] 存盤,包括類似int. Not objected as in面向物件編程。)所以指標基本上是一種整數資料,尤其是在沒有多個組件的平面記憶體模型的組裝中。對于分段記憶體模型,seg:off far 指標是一對整數。
因此,存盤在暫存器或記憶體中任何位置的任何有效地址都可以有效地被視為指標。
但是不,由標簽定義的符號不是指標。從概念上講,我認為將其視為一個標簽很重要。 指標本身就是一個物件(一些存盤位元組),因此可以修改。例如增加一個指標。但是符號只是參考某個固定位置的一種方式。
在 C 語言中,符號類似于 achar symbol[],而不是 achar *symbol = NULL; 如果您使用 bare symbol,您將獲得地址。就像mov edi, symbol在 NASM 語法中一樣。(或mov edi, OFFSET symbol在 GNU .intel_syntax 或 MASM 中。另請參閱如何將函式或標簽的地址加載到暫存器中以了解實際考慮,例如如果 32 位絕對地址不起作用,則使用 RIP 相對 LEA。)
您可以取消參考 asm 中的任何符號來訪問那里的位元組,無論是mov eax, [main]加載該函式的前 4 個位元組的機器代碼,還是mov eax, [global_arr rdi*8]索引到陣列,或任何其他 x86 尋址模式。(警告:x86-64 Linux 中不再允許使用 32 位絕對地址?對于最后一個示例)。
但你不能這樣做arr ;這是沒有意義的。任何地方都沒有存盤該地址的存盤空間。它嵌入到每個使用它的站點的程式的機器代碼中。它不是一個指標。(請注意,Carr[4] = 1根據char *arr;vs.編譯為不同的 asm char arr[],但在 asm 中,您必須從存盤指標的任何位置手動加載指標值,然后用一些偏移量取消參考它。)
如果您在 asm 中有一個要在 C 中使用其地址的標簽,但它沒有附加到 storage 的某些位元組,您通常希望將其宣告為extern const char end_of_data_section[];或其他。
因此,例如size_t data_size = data_end - data_start;,如果您將這些符號安排在.data部分的結尾/開頭,您可以將位元組大小作為鏈接時間常數。使用聯結器腳本或在您的 NASM 源代碼中使用global data_end/ 。data_end:一開始可能與其他符號位于同一地址。
uj5u.com熱心網友回復:
匯編語言沒有變數、指標或型別檢查。它有地址和暫存器(沒有型別檢查)。
變數(例如在 C 中)是一種更高層次的東西——一種抽象資料塊位置的方法,這樣您就不必關心編譯器是否想將其放入暫存器或記憶體中。變數也有型別;它用于檢測某些型別的錯誤,并用于允許編譯器自動為您將資料轉換為不同的型別。
指標(例如在 C 中)是一個變數(見上文)。指標和“非指標”之間的主要區別在于它包含的資料型別 - 對于指標,變數通常包含地址,但指標不僅僅是地址,它是具有型別的東西的地址。這很重要——如果它只是一個地址,那么編譯器就不會知道它有多大,無法檢測到某些型別的錯誤,也無法自動轉換資料(例如,考慮int foo = *pointer_to_char;如果編譯器不這樣做會發生什么”不知道指標指向什么型別的資料)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/446146.html
上一篇:預期'constGLchar*const*'{aka'constchar*const*'}但引數的型別是'char**'
下一篇:宣告指向結構的指標
