来自于《Intel汇编语言程序设计》(第四版)第10章-----结构和宏。
首先,链表大家都不陌生,每个节点包含了一个data和一个link,其中Link指向了下一个节点的开始地址。最后一个节点的link保存的是一个空指针(NULL)。
另外本章是关于宏的,宏在汇编中的角色是非常重要的。不过以下的程序只是一个循环遍历链表的程序:
TITLE Creating a Linked List (List.asm)
INCLUDE Irvine32.inc
ListNode STRUCT
NodeData DWORD ?
NextPtr DWORD ?
ListNode ENDS
TotalNodeCount = 15
NULL = 0
Counter = 0
.data
LinkedList LABEL DWORD
REPEAT TotalNodeCount
Counter = Counter + 1
ListNode < Counter, ( $ + Counter * SIZEOF ListNode)>
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.
mov eax , ( ListNode PTR [esi]).NextPtr
cmp eax , NULL
je quit
; Display the node data.
mov eax , ( ListNode PTR [esi]).NodeData
call WriteDec
call Crlf
; Get pointer to next node.
mov esi , ( ListNode PTR [esi]).NextPtr
jmp NextNode
quit:
exit
main ENDP
END main
还是用代码注释来代替分析:
TITLE Creating a Linked List (List.asm)
INCLUDE Irvine32.inc
ListNode STRUCT ; 定义链表节点结构体
NodeData DWORD ? ; 节点中用来保存值的成员
NextPtr DWORD ? ; 节点中用来保存下一个节点地址的成员
ListNode ENDS
TotalNodeCount = 15 ; 用来测试的数据,以便为节点中的NodeData赋值
NULL = 0
Counter = 0
.data
LinkedList LABEL DWORD
REPEAT TotalNodeCount ; 初始化15个节点
Counter = Counter + 1
ListNode < Counter, ( $ + Counter * SIZEOF ListNode)> ; $代表此链表的第一个节点的地址值,再加上相应的Counter * SIZEOF ListNode,就得到了每个节点的偏移地址。
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.
mov eax , ( ListNode PTR [esi]).NextPtr ; 将此时(ESI所指向的)节点保存的下一个节点地址赋值到eax中
cmp eax , NULL ; 看看是否是最后一个节点
je quit ; 如果是,则退出
; Display the node data.
mov eax , ( ListNode PTR [esi]).NodeData ; 否则会执行这里,将此节点的数据成员赋值到eax中
call WriteDec ; 输出此时eax中的值
call Crlf
; Get pointer to next node.
mov esi , ( ListNode PTR [esi]).NextPtr ; 将下一个节点的地址保存到esi中
jmp NextNode ; 进入下一个节点
quit:
exit
main ENDP
END main
以上程序便循环遍历了一个链表。