这是在y86(汇编架构类似于x86,但缺少很多指令),但这应该是有意义的。我正在尝试将整个链表推送到堆栈中,链表看起来像这样..
.align 4
ele1:
.long 0x00a
.long ele2
ele2:
.long 0x0b0
.long ele3
ele3:
.long 0xc00
.long 0
我想知道如何把它推到堆栈上,我很确定会这样做..
.pos 0
init:
irmovl Stack,%esp
rrmovl %esp,%ebp
irmovl ele1,%edx
pushl %edx
call Main
halt
.align 4
ele1:
.long 0x00a
.long ele2
ele2:
.long 0x0b0
.long ele3
ele3:
.long 0xc00
.long 0
Main:
pushl %ebp
rrmovl %esp,%ebp
irmovl ele1, %eax
pushl %eax
irmovl ele2, %eax
pushl %eax
irmovl ele3, %eax
pushl %eax
.pos 0x200
Stack:
#end of code
我想知道的是我如何推送任何大小的链表。我知道每个元素中的第二个长度是下一个元素的内存位置吗?我如何获得该值,我的意思是不是irmovl ele1,%eax只是移动长0x00a值,还是移动整个列表?我很困惑。
答案 0 :(得分:1)
在我看来,假设列表中的第二个长度是下一个列表的内存地址(字节位置),你是正确的。但是,要小心,就像你表演时一样 irmovl ele1,%eax
您没有将值从ele1移动到%eax(在这种情况下为0x00a),而是地址(24(基数10)或0x18) )并将其放在堆栈上。地址为24,因为指令采用以下字节:irmovl(6)+ rrmovl(2)+ irmovl(6)+ pushl(2)+ call(5)+ halt(1)= 22,对齐为4(最接近是24)作为ele1的起始地址。
如果你想移动ele1的值,你应该这样做:
mrmovl 0(ele1), %eax
pushl %eax
现在,为了对任何大小的链表执行检查。您可以利用链表的最后一个节点的辅助地址为0的事实。我将以下代码放在pushl%ebp之后的行之间:
irmovl $8, %edi # Value to increment addresses of 8 bytes for list nodes
irmovl ele1, %ebx # Save start memory address
listPusher: mrmovl 0(%ebx), %eax # Save node value
pushl %eax # Push the value
mrmovl 4(%ebx), %eax # Save the next address
pushl %eax # Push the next address
addl %edi, %ebx # Move forward the address reference
andl %eax, %eax # Check if address is 0
jne listPusher # Repeat if address != 0
这可能无法完全满足您的需求,但可以调整它以执行任何大小的链接列表。我测试了它并使用您的原始数据将其存储到堆栈中(从高地址到低地,也就是堆栈底部到顶部):
地址:价值
0x01fc:18< --- Stack Bottom(0x01fc-0x0200)
0x01f8:15
0x01f4:200
0x01f0:a
0x01ec:20
0x01e8:b0
0x01e4:28
0x01e0:c00
0x01dc:0< --- Stack Top
我希望这有帮助。祝你好运!