将链表推送到堆栈上

时间:2013-10-20 21:21:41

标签: assembly x86 y86

这是在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值,还是移动整个列表?我很困惑。

1 个答案:

答案 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

我希望这有帮助。祝你好运!