assembly - Assembly x86 Irvine 中的链表

标签 assembly struct linked-list x86 masm

以下是在 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

最佳答案

Can someone explain (ListNode PTR [esi]).NextPtr? What does that mean?

表示有一个指针指向一个ListNode的开头ESI 中的结构登记。它取消引用该指针,并评估为 NextPtr字段。

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

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

Can someone explain < Counter, ($ + Counter * SIZEOF ListNode) >? How does it work and what does it mean?

不,老实说我不能。好吧,抱歉,结果证明这是一个非常糟糕的答案。 :-)

不过,我可以告诉您我会如何解决这个问题。首先我会去 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 的大小结构,然后加上位置计数器的当前值。

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

Treats as a single literal string. Angle brackets are often used in macro calls and with the FOR directive to ensure that values in a parameter list are treated as a single parameter . . . The assembler removes one set of angle brackets each time it inserts an argument into a macro expansion.

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

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

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

Defining Structure and Union Variables

Once you have declared a structure or union type, you can define variables of that type. For each variable defined, memory is allocated in the current segment in the format declared by the type. The syntax for defining a structure or union variable is:

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

The name is the label assigned to the variable. If you do not provide a name, the assembler allocates space for the variable but does not give it a symbolic name. The typename is the name of a previously declared structure or union type.

You can give an initializer for each field. Each initializer must correspond in type with the field defined in the type declaration. For unions, the type of the initializer must be the same as the type for the first field. An initialization list can also use the DUP operator.

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

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

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

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

因为它正在初始化 ListNode 的前两个字段结构,NodeDataNextPtr , 具有这些值。

关于assembly - Assembly x86 Irvine 中的链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43824054/

相关文章:

assembly - 分支指令和带有链接指令的分支之间的主要区别是什么? ARM ?

c - 使用链表将字符串插入堆栈

c++ - 为什么段错误是由类变量顺序引起的?

c - 如何理解 xv6 Bootstrap 代码中的以下代码?

c - 指针和typedef结构,在C中调用函数时该怎么做

C++将文件读入结构

java - 子类化集合并使用泛型

c - 随机变化的链表指针

linux - 浮点异常错误(核心转储)

c - 结构体作为全局变量