Помещение связанного списка в стек
Это в 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 <--- вершина стека
Я надеюсь, что это помогло. Удачи!