x86程序集链接列表的结尾

时间:2014-03-08 12:27:26

标签: assembly linked-list x86 nasm

假设我有一个链表,每个节点都有一个整数。我能够遍历链表并获取每个节点的值;但是,我不知道如何检测到我已经到达链表的末尾。我知道最后一个节点保存null,所以我尝试了cmp [ebx+ecx*4],0,其中ebx是指向函数第一个参数的堆栈指针,ecx是每个节点的增量1。问题是链表中的节点也可以保存值0.如何区分0和null

更新:

所以我尝试了类似的东西,但它最终成了无穷无尽的循环。

List:
    add eax, [ebx] //add the value at the address of ebx to eax
    lea ebx, [ebx+4] //update the address of ebx to the next field
    cmp ebx, 0 //check if this address is null
    jne List //if so, then stop

如果我使用mov ebx, [ebx+4]代替它会是不正确的,因为ebx现在持有第二个元素的值而不是地址吗?

2 个答案:

答案 0 :(得分:2)

那应该是一个mov,而不是一个lea:

        mov     ebx,[ebx+4]

使用masm结构的示例代码。有一个h2inc.exe程序将.h文件转换为masm .inc文件。它包含在masm和ml的microsoft中,但在Visual Studio 2003之后停止包含。如果感兴趣,你应该能够找到h2inc的副本。

        .model FLAT
node    struct
value   dd      ?
next    dd      ?
node    ends

        .data
list0   node    {1, list1}
list1   node    {2, list2}
list2   node    {3, list3}
list3   node    {4, 0}

        .code
_main   proc    near
;       ...
        push    ebx
        xor     eax,eax
        lea     ebx,list0
        jmp     for1   ;jmp used to start off with null ptr check
for0:   add     eax,node.value[ebx]
        mov     ebx,node.next[ebx]
for1:   or      ebx,ebx
        jnz     for0
        pop     ebx
;       ...

答案 1 :(得分:1)

1)ListNode包含值字段和链接字段(指针),这些是不同的字段。 为了测试元素是否是最后一个元素,您应该检查 link 变量。

struct ListNode {
   int val;
   ListNode* pNext;  // link to the next element
};
//...
if (pNext == nullptr) { // found last element

如果你在程序集中写了相同的 - 只需检查pNext字段的值 在汇编中你没有类型,因此你无法区分0表示int和0表示 空指针。 如果对下一个节点的访问不是通过链接字段,那么它实际上不是链表。

2)在具有类型系统的语言中,例如C ++ 98/03,“空指针”和0完全相同,但C ++ 11引入了nullptr值,其类型为{ {1}},不同于整数类型。