假设我有一个链表,每个节点都有一个整数。我能够遍历链表并获取每个节点的值;但是,我不知道如何检测到我已经到达链表的末尾。我知道最后一个节点保存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现在持有第二个元素的值而不是地址吗?
答案 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}},不同于整数类型。