[英]LinkedList in Assembly x86 Irvine
以下是Kip Irvine的匯編語言x86書中的鏈表匯編程序。 在main中,循環遍歷列表並顯示所有節點值。 程序不是使用固定計數器進行循環,而是檢查尾節點中的空指針,並在找到它時停止循環。 我的問題如下:
(a)有人可以解釋<Counter,($ + Counter * SIZEOF ListNode)>? 它是如何工作的,它意味着什么?
(b)有人可以解釋(ListNode PTR [esi])。NextPtr? 這意味着什么?
INCLUDE Irvine32.inc
ListNode STRUCT
NodeData DWORD ?
NextPtr DWORD ?
ListNode ENDS
TotalNodeCount = 15
NULL = 0
Counter = 0
.data
putc macro ptr
push eax
mov al, ptr
call writechar
pop eax
endm
;to use:
;putc 'a'
LinkedList LABEL PTR ListNode
REPEAT TotalNodeCount
Counter = Counter + 1
ListNode <Counter, ($ + Counter * SIZEOF ListNode)>
;struct variables Counter, and ($+Counter*SIZEOF ListNode) being declared
;
ENDM
ListNode <0,0> ; tail node
.code
main PROC
mov esi,OFFSET LinkedList
; Display the integers in the NodeData fields.
NextNode:
; Check for the tail node.
putc 'a'; ->first node, then third node
mov eax,(ListNode PTR [esi]).NextPtr
cmp eax,NULL
je quit
; Display the node data.
putc 'b' ;->fourth node
mov eax,(ListNode PTR [esi]).NodeData
call WriteDec
call Crlf
; Get pointer to next node.
putc 'c' ;->first node
putc 'd' ;->second node
mov esi,(ListNode PTR [esi]).NextPtr
;references a struct using [esi]
jmp NextNode
quit:
exit
main ENDP
END main
有人可以解釋
(ListNode PTR [esi]).NextPtr
? 這意味着什么?
這意味着有一個指向ESI
寄存器中ListNode
結構開頭的指針。 它取消引用該指針,並計算NextPtr
字段。
它基本上就像你在C中有以下內容:
ListNode* esi;
...
return esi->NextPtr;
有人可以解釋
< Counter, ($ + Counter * SIZEOF ListNode) >
? 它是如何工作的,它意味着什么?
不,老實說,我做不到。 嗯,對不起,這結果是一個非常糟糕的答案。 :-)
不過,我可以告訴你我該如何解決這個問題。 首先,我將轉到MASM的文檔 ,看看我是否能發現任何看起來相關的內容。 我會發現(或者,實際上,我已經知道) $
表示位置計數器的當前值 ,而SIZEOF
是一個返回指定類型的字節數的運算符 。
所以這個gobbledygook看起來像是將Counter
的值乘以ListNode
結構的大小,然后添加位置計數器的當前值。
但我仍然不知道尖括號是什么意思。 所以我嘗試了Google搜索,比如“尖括號MASM”。 我得到了這個問題 , 這個問題不是很有用,因為它沒有答案。 在MASM32幫助文件中,我看到:
視為單個文字字符串。 尖括號通常用於宏調用,並使用FOR指令確保參數列表中的值被視為單個參數。 。 。 每次將參數插入宏擴展時,匯編器都會刪除一組尖括號。
但這對我來說也沒有太大的幫助。
然后去哪兒? 好吧,假設代碼有效 ,我會組裝它並要求MASM生成一個列表文件( /Fl
)。 然后我會檢查這個列表文件,看看它實際上對生成的代碼產生了什么影響。
更新:我的奉獻得到了回報,我在網上看到了MASM 6.1的舊手冊 。 我無法在微軟的在線文檔中找到這個,但是在本手冊中,它清楚地說明了這一點。 98:
定義結構和聯合變量
聲明結構或聯合類型后,可以定義該類型的變量。 對於定義的每個變量,內存以當前段以類型聲明的格式分配。 定義結構或聯合變量的語法是:
[[name]] typename < [[initializer [[,initializer]]...]] > [[name]] typename { [[initializer [[,initializer]]...]] } [[name]] typename constant DUP ({ [[initializer [[,initializer]]...]] })
名稱是分配給變量的標簽。 如果未提供名稱,匯編程序將為變量分配空間,但不為其指定符號名稱。 typename是先前聲明的結構或聯合類型的名稱。
您可以為每個字段提供初始值設定項。 每個初始化程序必須在類型上與類型聲明中定義的字段對應。 對於聯合,初始化程序的類型必須與第一個字段的類型相同。 初始化列表也可以使用
DUP
運算符。
所以看起來它聲明了一個ListNode
類型的未命名變量,括號中的東西是ListNode
結構的初始化器 ,類似於C代碼:
struct ListNode { ... } = { Counter, ($ + Counter * sizeof(ListNode)) };
這符合對解釋性評論的微弱嘗試:
; struct variables Counter, and ($+Counter*SIZEOF ListNode) being declared
因為它正在使用這些值初始化ListNode
結構的前兩個字段NodeData
和NextPtr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.