Assembly 将链表推到堆栈上
这是在y86(类似于x86的汇编体系结构,但缺少很多指令)中,但这应该是有意义的。我试图将一个完整的链表推到堆栈上,链表如下所示Assembly 将链表推到堆栈上,assembly,x86,y86,Assembly,X86,Y86,这是在y86(类似于x86的汇编体系结构,但缺少很多指令)中,但这应该是有意义的。我试图将一个完整的链表推到堆栈上,链表如下所示 .align 4 ele1: .long 0x00a .long ele2 ele2: .long 0x0b0 .long ele3 ele3: .long 0xc00 .long 0 我想知道我该如何把它推到堆栈上,我很确定这可以做到 .pos 0 in
.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是下一个元素的内存位置,对吗?如何获得该值,我是说irmovlele1,%eax不是只移动长0x00a值,还是移动整个列表?我很困惑。在我看来,您假设列表中的第二个长字符是下一个列表的内存地址(字节位置)是正确的。但是,要小心,就像你在表演时一样 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
这可能不能完全满足您的需要,但可以调整它来创建任意大小的链接列表。我对它进行了测试,它使用原始数据(从高地址到低地址,即堆栈从下到上)将以下内容存储到堆栈中:
地址:Value
0x01fc:18是否希望它在按下后仍作为链接列表工作?还是只想按值推送任意结构,而不修复指针?