Страница 1 из 1
программа на ассемблере x86
Добавлено: Сб мар 29, 2008 09:41:54
Dexa
Начал изучать в универе "основы микропроцессорной техники" и не могу написть простую программу для стековой памяти. Цель: Составить программу на ассемблере, которая содержит следующую последовательность действий:
— назначает новое основание стека Ао=E800 в текущем сегменте стековой памяти, сохранив при этом адрес текущей вершины в незадействованном регистре;
— загружает в стек содержимое регистров микропроцессора в последова-тельности: dx,ax,bx,cx с использованием команды "mov";
— возвращает из стека с использованием команды "pop" данные в регистры в соответствии с заданным порядком перестановки: <bx>-ax, <ax>-dx, <dx>-cx, <cx>-bx;
—восстанавливает старую вершину стека.
Я написал но она не работает((.
mov si,sp; сохранил старую вершину стека
mov sp,E800; назначил основание
mov dx,1122; загрузил данные в регистр dx
mov ax,3344; ......
mov bx,5566; ......
mov cx,7788; ......
mov [E7FE],dx; здесь вроде (как я думаю) загружаю в стек по адресу E7FE данные из dx
mov [E7FC],ax; .....
mov [E7FA],bx; .....
mov [E7F8],cx; .....
pop bx; читаю из стека в соответствии с заданным порядком
pop ax; ......
pop dx; ......
pop cx; ......
mov sp,si; вернул старую вершину стека
int 20
Адреса выбрал такие так как стековая память организована по принципу LIFO и при загрузке в стек указываем младший адрес для МБ а старший байт пойдет по следущему адресу(вроде так). Выполняю прогу по шагам, в регистры все загружаю нормально,а когда читаю из стека они принимают 0000, а должны bx=7788 ax=5566 и т.д. В чем я ошибья?
Re: программа на ассемблере
Добавлено: Сб мар 29, 2008 11:17:09
Rokl
Dexa писал(а):
Я написал но она не работает((.
mov si,sp; сохранил старую вершину стека
mov sp,E800; назначил основание
mov dx,1122; загрузил данные в регистр dx
mov ax,3344; ......
mov bx,5566; ......
mov cx,7788; ......
mov [E7FE],dx; здесь вроде (как я думаю) загружаю в стек по адресу E7FE данные из dx
mov [E7FC],ax; .....
mov [E7FA],bx; .....
mov [E7F8],cx; .....
pop bx; читаю из стека в соответствии с заданным порядком
pop ax; ......
pop dx; ......
pop cx; ......
mov sp,si; вернул старую вершину стека
int 20
...Выполняю прогу по шагам, в регистры все загружаю нормально,а когда читаю из стека они принимают 0000, а должны bx=7788 ax=5566 и т.д. В чем я ошибья?
Так адрес основания стека должен меняться в зависимости от записаных в него слов. А ты используешь команду POP не изменив содержимое основания стека SP. Вот он и читает из Е802, Е804...а там у тебя нули.
Добавлено: Сб мар 29, 2008 12:02:15
Dexa
правильно ли я понял: перед чтением стека необходимо указать вершину стека, т.е. откуда начинать читать? значит надо добавить перед первой строчкой "pop" команду mov bp,sp??? или нет? пожалуйста подскажите как будет правильно и поясните почему так:)
Добавлено: Сб мар 29, 2008 12:25:51
Dexa
хм...когда выполняю команды mov [E7FC],ax мне прога говорит что я работаю с Data Segment a должен Stack Segment может в этом проблема? как обратиться к SS когда загружаю в стэк?я знаю команду push при ее выполнении данные точно попадут в стэк, но здесь отправить надо именно командой mov...
Добавлено: Сб мар 29, 2008 19:04:52
ARV
давненько я ассемблером х86 не занимался
если надо обратиться по индексному регистру но в другом сегменте, надо просто указать префикс сегмента:
mov ss:[1234], 0x2345
если я не ошибаюсь, то и без квадратных скобок будет то же самое.
индексные регистры
SI,
DI по умолчанию работают в сегменте
DS, а в стековом сегменте по умолчанию работает регистр
BP - именно он используется для обращения к сегменту стека командами
MOV
в вашей программе логично выглядят команды типа
mov [bp+KK], 0x1234, где КК - это смещение относительно базы
BP. У вас ведь точно известно СКОЛЬКО чисел и КАКОГО размера в стек заносятся... значит, первое пишется с КК=0, второе КК=2 и т.д. (для двухбайтных слов, естественно)
Добавлено: Сб мар 29, 2008 20:40:49
Brutaller
Dexa, если честно, то вы немного не по адресу. Здесь всё-таки про микроконтроллеры по большей части. А что касается x86 процессоров, то намного быстрее вам помогут, да и сами много инфы найдете на
wasm.ru
Добавлено: Вс мар 30, 2008 11:21:40
Dexa
там молчат(((
я вот понять не могу: когда пишу в стек адресация должна уменьшаться FFFF FFFE FFFD и т.д. Значит по идее командой
mov BP,SP ----- SP=E800
mov [BP-02],dx
я отправляю данные из dx в стек по адресу E8FE пральна? при этом dx=1122 значит 22 пойдет в E8FE, а 11 в E8FF
Добавлено: Вс мар 30, 2008 20:02:13
ARV
не понял, в чем проблема?
кстати, вспомните вот что: в х86 при извлечении из стека командой POP как себя процессор ведет - сначала уменьшает SP, а потом извлекает из [SP] данные или сначала извлекает, а потом уменьшает SP? может, ваши беды из-за недопонимания этой ситуации?

Добавлено: Пн мар 31, 2008 07:33:58
UA3MQJ
а вы отладчике не видите куда он пишет?
Добавлено: Пн мар 31, 2008 11:55:49
Rokl
ARV писал(а):не понял, в чем проблема?
кстати, вспомните вот что: в х86 при извлечении из стека командой POP как себя процессор ведет - сначала уменьшает SP, а потом извлекает из [SP] данные или сначала извлекает, а потом уменьшает SP? может, ваши беды из-за недопонимания этой ситуации?

Сначала извлекает, а потом увеличивает адрес вершины SР.
Добавлено: Вт апр 01, 2008 05:25:03
Dexa
Вижу - пишет в DS...все перепробывал не получается. Выше опечатка: "при этом dx=1122 значит 22 пойдет в E8FE" - E7FE ну и т.д.
после этих команд:
mov BP,SP ----- SP=E800
mov [BP-02],dx
он начал писать в SS но при извлечении все равно обнуляет регистры....

Добавлено: Вт апр 01, 2008 07:16:37
ARV
Rokl писал(а):ARV писал(а):не понял, в чем проблема?
кстати, вспомните вот что: в х86 при извлечении из стека командой POP как себя процессор ведет - сначала уменьшает SP, а потом извлекает из [SP] данные или сначала извлекает, а потом уменьшает SP? может, ваши беды из-за недопонимания этой ситуации?

Сначала извлекает, а потом увеличивает адрес вершины SР.
я не спрашивал, я намекал на путь решения проблемы

Добавлено: Вт апр 01, 2008 07:18:34
ARV
Dexa писал(а):Вижу - пишет в DS...все перепробывал не получается. Выше опечатка: "при этом dx=1122 значит 22 пойдет в E8FE" - E7FE ну и т.д.
после этих команд:
mov BP,SP ----- SP=E800
mov [BP-02],dx
он начал писать в SS но при извлечении все равно обнуляет регистры....

да в чем проблема-то?! возьми старый добрый TurboDebugger (есть и под Windows) да и посмотри, куда на самом деле ты пишешь и что извлекаешь! по твоим отрывочным сообщениям все едино ничего не понятно, и посоветовать сложно что-либо...
Добавлено: Вт апр 01, 2008 11:10:09
Rokl
Dexa писал(а):
после этих команд:
mov BP,SP ----- SP=E800
mov [BP-02],dx
он начал писать в SS но при извлечении все равно обнуляет регистры....

А записать в SP новый адрес вершины стека перед командою РОР, не судьба?
MOV SP, E7F8
а уж потом пользовать команду POP
Добавлено: Вт апр 01, 2008 18:48:02
Dexa
Rokl писал(а):Dexa писал(а):
А записать в SP новый адрес вершины стека перед командою РОР, не судьба?
MOV SP, E7F8
а уж потом пользовать команду POP
хм...эт чет новенькое)) а зачем? команда POP должна сама знать вершину стэка и автоматически вытаскивать то что было записано последним в стэк.
ARV спасибо за советы. А что вам не понятно? есть прога - она не работает)))ткните меня носом туда где и что надо исправить и написать)))
Добавлено: Вт апр 01, 2008 20:09:30
ARV
эх... попробую все же подсказать.
итак, мы имеем SP=E800. Надо в стек запхнуть командами MOV какие-то числа, а потом командами POP их оттуда извлечь, так?
вы делаете так: запихиваете в сегмент стека данные по базе BP, которую приравниваете значению SP. причем смещение относительно BP у вас отрицательное, т.е. данные пишутся вглубь стека. это нормально и пока верно. но потом вы извлекаете из стек командой POP, так? к этому моменту SP у вас все еще указует на E800. А есть ли в этой ячейке ваше число? И потом: первая команда POP вытащит из ss:[E800] число, после чего увеличит SP на 2, т.е. SP станет равно E802, но ведь второе число вы писали в E800-2, т.е. в E7FD!!!
потому вам и было сказано, что перед извлечением из стека командами POP надо SP сделать таким, чтобы он указывал на последнее занесенное в стек число.
теперь просветлело?
P.S. Нормальная практика работы со стеком командами MOV и последующим POP заключается в следующем:
1. вначале загружаем в BP содержимое SP
2. затем устанавливаем новое значение SP, выделяя в стеке участок для наших "локальных переменных" (т.е. тех, к которым обращаемся MOV-ами)
3. работаем как обычно
4. извлекаем POP-ами все, что нужно и, если все сделано верно, последняя команда RET возвращает нас в место, откуда был вызов подпрограммы.
Если вы поглядите дизассемблерный код Сишной функции или Паскалевской процедуры, то за небольшими нюансами именно по этому алгоритму они будут работать.
Добавлено: Вт апр 01, 2008 20:57:37
Rokl
ARV писал(а):эх... попробую все же подсказать.
итак, мы имеем SP=E800. Надо в стек запхнуть командами MOV какие-то числа, а потом командами POP их оттуда извлечь, так?
........
потому вам и было сказано, что перед извлечением из стека командами POP надо SP сделать таким, чтобы он указывал на последнее занесенное в стек число.
теперь просветлело?...
Именно об этом я ему
в самом первом посте написал.
Может с 3 раза дойдет?

Добавлено: Ср апр 02, 2008 12:35:18
Dexa
mov [bp-02],dx;
mov [bp-04],ax;
mov [bp-06],bx;
mov [bp-08],cx;
mov sp,e7f8
pop bx;
pop ax;
pop dx;
pop cx;
Если вы об этом то еще 2-3 дня назад пробывал после 1 поста уважаемого Rokl, результат не нулевой что меня тогда порадовало))))))))))))))) НО ....результат работы команды POP:
bx: e800
ax: 011f
cx: 3302
dx: 096f
Добавлено: Ср апр 02, 2008 13:04:56
ARV
вот вам
однозначно рабочий код:
Код: Выделить всё
; начальное занесение чисел в регистры
MOV DX,1111
MOV CX,2222
MOV BX,3333
MOV AX,4444
; базу в сегменте стека
MOV BP,SP
; заносим регистры в стек относительно базы
MOV [BP],AX
MOV [BP-2],BX
MOV [BP-4],CX
MOV [BP-6],DX
; переставляем указатель стека на последнее число в стеке
SUB SP,6
; обнуляем числа, чтобы проверить извлечение
MOV DX,0
MOV CX,0
MOV BX,0
MOV AX,0
; теперь после команд POP в регистрах должно быть то же самое, что вначале
POP DX
POP CX
POP BX
POP AX
найдите
N отличий со своим вариантом и разберитесь наконец, в чем проблема!