Как работает регистр указателя стека

Ну как работает стек? Например инструкция:

push ax

равно:

sub sp, 4
mov sp, ax

где sp - указатель стека. Это правильно?

Мой вопрос - какой смысл вычитать 4 из регистра sp, если через мгновение я изменяю его на совершенно другое значение?

4 ответа

Решение

Я думаю, что это должно прочитать

mov [sp], ax

То есть поместите значение ax в память, на которую указывает sp.

Это не так push ax работает. Ваш пример кода того, чему он равен, должен быть:

sub sp, 4 
mov [ss:sp], ax

Вы не перезаписываете значение SP с помощью AX. Вместо этого вы копируете AX в адрес памяти, на который указывает SS:SP (используя сегмент стека, а не сегмент данных)... Но на самом деле это даже не точно. Что вам действительно нужно, это что-то вроде этого:

mov [tmp], sp
pushf ;push flags
sub [tmp], 4
popf
mov sp, [tmp]
mov [ss:sp], ax

Но на самом деле, даже это не совсем точно. mov sp, [tmp] приведет к неявному cli должно быть выполнено (в ожидании mov ss, foobar), что может быть нежелательным

В принципе, push делает что-то довольно простое, но подробности вокруг этой простой вещи делают ее очень полезной.

Разница в том, что sub esp, 4 установит флаги, но push не установит флаги. Кроме того, это должно быть mov [esp],eax, 16-разрядные версии, которые вы показываете, указывают на то, что вы используете очень старую книгу. Никто больше не программирует на 16-битной машине (кроме встроенных микроконтроллеров, возможно).

На x86 флаги OF, SF, ZF, ZF, PF и CF будут установлены вычитанием, но никакие флаги не будут затронуты PUSH,

Вы двигаете ценность ax в следующий доступный кадр стека. Указатель стека строится вниз (так что если у вас слишком много значений, он теряет значение ниже нуля и выдает ошибку, а не переполняется чем-то важным), поэтому следующее доступное расположение кадра стека - это одно слово (4 байта) перед текущим местоположением.

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