0

这是 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

我想知道的是如何推送任何大小的链表。我知道每个元素中的第二个 long 是下一个元素的内存位置,对吗?我如何获得该值,我的意思是 irmovl ele1, %eax 不只是移动长 0x00a 值,还是移动整个列表?我很困惑。

4

1 回答 1

1

在我看来,假设列表中的第二个 long 是下一个列表的内存地址(字节位置)是正确的。但是,要小心,因为当您执行 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 <--- 堆栈底部 (0x01fc-0x0200)

0x01f8: 15

0x01f4: 200

0x01f0:一个

0x01ec: 20

0x01e8: b0

0x01e4:28

0x01e0: c00

0x01dc: 0 <--- 堆栈顶部

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

于 2013-10-30T05:08:46.270 回答