Reputation: 1130
This is in y86(assembly architecture which resembles x86, but is missing a lot of instructions), but this should make sense. I'm trying to push a whole linked list onto the stack, the linked list looks like this..
.align 4
ele1:
.long 0x00a
.long ele2
ele2:
.long 0x0b0
.long ele3
ele3:
.long 0xc00
.long 0
I'm wondering how I would push this onto the stack, I'm pretty sure this would do it..
.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
What I'm wondering is how would I push a linked list of any size. I know that the second long in each element is the memory location for the next element right? How do I get that value, I mean doesn't irmovl ele1, %eax just move the long 0x00a value, or does it move the entire list? I'm very confused.
Upvotes: 0
Views: 1203
Reputation: 31
It seems to me that you are correct in assuming that the second long in the list is the memory address (the byte location) of the next list. However, be careful, as when you perform irmovl ele1, %eax
You are not moving the value from ele1 to %eax (which is 0x00a in this case), but the address (which is 24 (base 10) or 0x18) and placing it on the stack. The address is 24 since the instructions take the following bytes: irmovl (6) + rrmovl (2) + irmovl (6) + pushl (2) + call (5) + halt (1) = 22 with an align of 4 (closest is 24) as the starting address of ele1.
If you wanted to move the value of ele1, you should instead do:
mrmovl 0(ele1), %eax
pushl %eax
Now, in order to perform the check on a linked list of any size. You can take advantage of the fact that the last node of the linked list will have a secondary address of 0. I placed the following code between the lines directly following 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
This may not suite your needs fully, but it can be tweaked to do a linked list of any size. I tested it and it stored the following to the stack using your original data (from high address to low, aka. stack bottom to top):
Address: Value
0x01fc: 18 <--- Stack Bottom (0x01fc-0x0200)
0x01f8: 15
0x01f4: 200
0x01f0: a
0x01ec: 20
0x01e8: b0
0x01e4: 28
0x01e0: c00
0x01dc: 0 <--- Stack Top
I hope this helped. Good luck!
Upvotes: 1