Man Person
Man Person

Reputation: 1130

Pushing a linked list onto stack

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

Answers (1)

SeniorBleezy
SeniorBleezy

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

Related Questions