Помещение связанного списка в стек

Это в 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 ответ

Мне кажется, что вы правы, предполагая, что второй длинный список - это адрес памяти (местоположение байта) следующего списка. Однако будьте осторожны, так как при выполнении 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: a

0x01ec: 20

0x01e8: b0

0x01e4: 28

0x01e0: c00

0x01dc: 0 <--- вершина стека

Я надеюсь, что это помогло. Удачи!

Другие вопросы по тегам