@Oghuzkhan2020
Никто

Почему 2 раза используется команда «push ax»?

Добрый день.Прошу помочь. Изучаю Assembler. В книге "Ассемблер? Это просто! Учимся программировать" в коде 2 раза используется команда push ax. Почему именно 2 раза ? А нельзя ли просто 1 раз указать команду push ax?

В целом же, программа делает следующее:  ждет от пользователя нажатия любой клавиши;
- если это расширенный код ASCII (F1—F12, кнопки со стрелками), то игно-рирует ее;
- если это не расширенный ASCII (A—Z, 0—9 и т.п.) — заполняет эк-ран данным символом;
- если нажимаем клавишу (27 или 1Bh), то заполняет экран пробелами (mov al,32) и выходит.

CSEG segment 
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG 
org 100h 
Begin: 
 call Wait_key 
 cmp al,27 
 je Quit_prog 
 cmp al,0 
 je Begin 
 
 call Out_char 
 jmp Begin 
 
Quit_prog: 
 mov al,32 
call Out_char 
 int 20h 
 
; === Подпрограммы === 
; --- Wait_key --- 
Wait_key proc 
 mov ah,10h 
 int 16h 
 ret 
Wait_key endp 
 
; --- Out_char --- 
Out_char proc 
 push cx 
 push ax ; 1 раз
 push es 
 
 push ax ; 2 раз
 mov ax,0B800h 
 mov es,ax 
 mov di,0 
 mov cx,2000 
 pop ax 
 mov ah,31 
Next_sym: 
 mov es:[di],ax 
 inc di 
 inc di 
 loop Next_sym 
 
 pop es 
 pop ax 
 pop cx 
 ret 
Out_char endp 
 
CSEG ends 
end Begin

603a4ed397329085340661.jpeg
603a4ef3838d5624095397.jpeg
  • Вопрос задан
  • 376 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Первый раз - сохранение регистров при входе в подпрограмму Out_char.
Второй раз - сохранение регистра перед использованием его для изменения ES.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Vindicar
@Vindicar
RTFM!
Обрати внимание, что двум вызовам push ax соответствуют два вызова pop ax.
Push сохраняет регистр на стеке, смещая вершину стека. Pop выталкивает значение с вершины стека в регистр и смещает вершину назад. Поэтому паттерн push-use-pop встречается довольно часто, если нам нужен регистр, но мы не хотим терять его предыдущее значение.
В твоем случае этот паттерн встретился дважды, один внутри другого. Внешний сохраняет регистр при входе в подпрограмму, и восстанавливает при выходе (чтобы поменьше мешать вызывающей подпрограмме). Внутренний - сохраняет регистр AX перед пересылкой, так как мы не можем напрямую писать в ES, только через другой регистр.
Ответ написан
Комментировать
ematveev
@ematveev
PHP разработчик / руководитель / писатель
push ax ; 2 раз
 mov ax,0B800h 
 mov es,ax 
 mov di,0 
 mov cx,2000 
 pop ax

здесь регистр ax используется временно, для загрузки в значения в регистр es
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы