Assembly x86 Irvine中的LinkedList

时间:2017-05-06 18:35:39

标签: assembly struct linked-list x86 masm

以下是Kip Irvine的汇编语言x86书中的链表汇编程序。在main中,循环遍历列表并显示所有节点值。程序不是使用固定计数器进行循环,而是检查尾节点中的空指针,并在找到它时停止循环。我的问题如下:

(a)有人可以解释<计数器,($ +计数器* 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

1 个答案:

答案 0 :(得分:2)

  

有人可以解释(ListNode PTR [esi]).NextPtr吗?这是什么意思?

这意味着指向ListNode寄存器中ESI结构的开头的指针。它取消引用该指针,并计算到NextPtr字段。

基本上就像你在C中有以下内容:

ListNode* esi;
...
return esi->NextPtr;
  

有人可以解释< Counter, ($ + Counter * SIZEOF ListNode) >吗?它是如何工作的,它意味着什么?

不,老实说,我做不到。嗯,对不起,这结果是一个非常糟糕的答案。 : - )

但我可以告诉你我怎么想的。首先,我去the documentation for MASM,看看我是否能发现任何看似相关的东西。我会发现(或者,实际上,我已经知道)$表示the current value of the location counter,而SIZEOFan operator that returns the number of bytes in the specified type

所以这个gobbledygook看起来像是将Counter的值乘以ListNode结构的大小,然后添加位置计数器的当前值。

但我仍然不知道尖括号是什么意思。所以我尝试了Google搜索,比如“尖括号MASM”。我得到this question,这不是很有用,因为它没有答案。在MASM32帮助文件中,我看到:

  

视为单个文字字符串。尖括号通常用于宏调用,并使用FOR指令确保参数列表中的值被视为单个参数。 。 。每次将参数插入宏扩展时,汇编器都会删除一组尖括号。

但这对我来说也没有太大的帮助。

从哪里开始?好吧,假设代码工作,我会组装它并要求MASM生成一个列表文件(/Fl)。然后我会检查这个列表文件,看看它实际上对生成的代码产生了什么影响。

更新:我的奉献得到了回报,我遇到了an old manual for MASM 6.1 online。我无法在微软的在线文档中找到这个,但是在本手册中,它清楚地说明了这一点。 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结构的前两个字段NodeDataNextPtr