【问题标题】:LinkedList in Assembly x86 IrvineAssembly x86 Irvine 中的 LinkedList
【发布时间】:2017-10-05 01:31:23
【问题描述】:

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

(a) 谁能解释一下?它是如何工作的,它是什么意思?

(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

【问题讨论】:

    标签: assembly struct linked-list x86 masm


    【解决方案1】:

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

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

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

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

    有人能解释一下&lt; Counter, ($ + Counter * SIZEOF ListNode) &gt;吗?它是如何工作的,它是什么意思?

    不,老实说我不能。好吧,对不起,这是一个非常糟糕的答案。 :-)

    不过,我可以告诉你我将如何解决。首先我会去the documentation for MASM 看看我是否能发现任何看起来相关的东西。我会发现(或者,实际上,我已经知道)$ 表示the current value of the location counter,而SIZEOF 是an operator that returns the number of bytes in the specified type。

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

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

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

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

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

    更新:我的付出得到了回报,我遇到了an old manual for MASM 6.1 online。我无法在 Microsoft 的在线文档中找到它,但在本手册中,它在 pg 上清楚地说明了这一点。 98:

    定义结构和联合变量

    一旦您声明了结构或联合类型,您就可以定义该类型的变量。对于定义的每个变量,内存以类型声明的格式在当前段中分配。定义结构或联合变量的语法是:

    [[name]] typename < [[initializer [[,initializer]]...]] >
    [[name]] typename { [[initializer [[,initializer]]...]] }
    [[name]] typename constant DUP ({ [[initializer [[,initializer]]...]] })
    

    名称是分配给变量的标签。如果不提供名称,汇编器会为变量分配空间,但不会给它一个符号名称。 typename 是先前声明的结构或联合类型的名称。

    您可以为每个字段指定一个初始值设定项。每个初始值设定项的类型必须与类型声明中定义的字段相对应。对于联合,初始化程序的类型必须与第一个字段的类型相同。初始化列表也可以使用DUP 运算符。

    所以看起来这声明了一个 ListNode 类型的未命名变量,括号中的内容是 ListNode 结构的 initializer,有点像 C 代码:

    struct ListNode { ... } = { Counter, ($ + Counter * sizeof(ListNode)) };
    

    这与解释性评论的微弱尝试相吻合:

    ; struct variables Counter, and ($+Counter*SIZEOF ListNode) being declared
    

    因为它使用这些值初始化ListNode 结构的前两个字段NodeData 和NextPtr。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多