Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты в разделе

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 541
∙ повысить рейтинг »
Evgen aka Chuma
Статус: 6-й класс
Рейтинг: 52
∙ повысить рейтинг »
quirck
Статус: 1-й класс
Рейтинг: 0
∙ повысить рейтинг »

∙ Assembler

Номер выпуска:1675
Дата выхода:14.12.2017, 19:15
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:49 / 18
Вопросов / ответов:1 / 1

Консультация # 192051: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующие вопросы: Даю сначала код программы, а вопросы (под номерами) по ходу листинга, под комментариями. Прилагаю файл, с тем же кодом и вопросами, - выглядит более наглядно! ;1. вопрос. Как оформляется код в ассемблере, вот по этим параметрам: голова, тело и хвост (конец) про...

Консультация # 192051:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующие вопросы:

Даю сначала код программы, а вопросы (под номерами) по ходу листинга, под комментариями. Прилагаю файл, с тем же кодом и вопросами, - выглядит более наглядно!

;1. вопрос. Как оформляется код в ассемблере, вот по этим параметрам: голова, тело и хвост (конец) программы, если можно на примере prog09.asm.? Нижний листинг.
(01) CSEG segment
(02) assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
(03) org 100h

(04) Begin:
; Открываем файл с помощью спецпроцедуры (см. ниже).
(05) mov dx, offset File_name
(06) call Open_file ; Открываем файл с именем Prog09.com
(07) jc Error_file ; Переход на метку Error_file при неудаче.
(08) mov bx, ax ; Сохраняем идентификатор файла.

; Чтение файла
(09) mov ah, 3Fh
; Загружаем длину нашей программы (количество читаемых байт) в регистр cx …
(10) mov cx, offset Finish-100h
(11) mov dx, offset Begin ; И читае м файл в память, начиная с метки Begin.
(12) int 21h ; читаем файл, начиная с метки Begin
(13) call Close_file ; Закрываем файл с помощью спецпроцедуры

; Выводим сообщение об удачном завершении
(14) mov ah, 9
(15) mov dx, offset Mess_ok
(16) int 21h
(17) ret
; Если файл с указанным именем не нашли (File_name db ‘Prog09.com’,0), то выдаем звуковой сигнал и выходим.
(18) Error_file:
(19) mov ah, 2
(20) mov dl, 7

(21) int 21h
(22) ret

; Процедуры
; Процедура открытия файла для чтения
; 2. вопрос. Дана процедура (любая), возьмем эту для примера. Выполняются ли все команды процедуры, перед возвратом из процедуры, следующие после оператора "ret", но стоящие перед закрытием процедуры, т.е. перед оператором "endp". По данной процедуре, будут ли выполнены, противоречащие друг другу команды "stc, ret" и "Handle dw 0FFFFh".
; 3. вопрос. Почему объявление переменной Hand le – в коде программы, как объявляются переменные (или данные) в начале программы или в конце? Опять же про оформление (какой есть стандартный порядок) – голова, тело, хвост?
; 4. вопрос. Как применяется оператор "ret"? В Интернете, только и говорится – "в паре с командой call". Почему здесь оператор "ret" встречается в "свободном парении" (получается – куда захочу, туда и поставлю)? Есть ли еще, какие-то другие способы применения (может быть в паре с другими командами) оператора "ret"?
(23) Open_file proc
(24) cmp Handle, 0FFFFh ; Выясняем, отрыт ли файл
(25) jne Quit_open ; И если не открыт – открываем его;
(26) mov ax, 3D00h
(27) int 21h
28) mov Handle, ax
(29) ret
(30) Quit_open:
(31) stc ; Устанавливаем флаг переноса в 1, необходимый
; для подтверждения факта открытия файла (для jc).
; 5. вопрос. Может быть правильнее было бы сказать: "для подтверждения "не открытия" файла (для jc)"? Флаг переноса (CF), устанавливается в 1, в случае ошибки, правильно?
(32) ret


(33) Handle dw 0FFFFh
(34) Open_file endp
; Процедура закрытия файла
(35) Close_file proc

(36) mov ah, 3Eh
(37) mov bx, Handle
(38) int 21h
(39) ret
(40) Close_file endp

(41) File_name db ‘prog09.com’,0
; 0Ah, 0Dh – переход в начало следующей строки.
(42) Mess_ok db ‘Все нормально!’, 0Ah, 0Dh,’$’
(43) Finish equ $ ; Признак (адрес) конца кода программы.

(44) CSEG ends
(45) end Begin

Дата отправки: 09.12.2017, 09:30
Вопрос задал: kerenskyaf (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, kerenskyaf!

© Цитата:
Как оформляется код в ассемблере, вот по этим параметрам: голова, тело и хвост (конец) программы, если можно на примере prog09.asm.?

Деление достаточно условное. Можно считать, что
Код (Assembler) :: выделить код
CSEG	segment 
	assume 	CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
	org	100h
это голова. Сюда, при другом способе записи, еще пишут тип процессора, модель памяти.
Код (Assembler) :: выделить код
CSEG	ends
end	Begin
Это, понятное дело, хвост. Закрывается сегмент, код с указанием точки старта.
Все остальное - тело.
© Цитата:
Дана процедура (любая). Выполняются ли все команды процедуры, перед возвратом из процедуры, следующие после оператора "ret", но стоящие перед закрытием процедуры, т.е. перед оператором "endp". По данной процедуре, будут ли выполнены, противоречащие друг другу команды "stc, ret" и "Handle dw 0FFFFh".
Тут надо уяснить следующее: в ассемблерном тексте есть команды, которые превращаются в реальные команды в коде, а есть операторы, которые являются просто подсказкой для компилятора. Оператор endp является указанием компилятору, что программист закончил на этом месте подпрограмму. Для компилятора важно, чтобы proc и endp были парными, не более того. Реально, из подпрограммы мо жно легко сделать переход дальше endp. В принципе, можно вообще не использовать proc/endp.
Реально будет работать только код, полученный из команд первого типа. А как они будут оформлены - дело десятое. Оформление важно для человека, который будет читать этот код. Исключительно человеку важно видеть, где начало, а где конец подпрограммы...
Теперь по поводу того, какие команды будут отработаны... В каждый момент времени выполняется команда по текущему адресу. Этот адрес может меняться как последовательно от команды к команде, так и резким переходом на другую команды при помощи соответствующих команд. К последним относятся вызов подпрограмм и выход из них. Что происходим при вызове подпрограммы с помощью команды call? В стек заносится адрес следующей команды, в регистр текущего адреса заносится указанный адрес и происходит переход. Команда ret извлекает из вершины стека адрес и передает туда управление. Я говорю сейчас для случая корот кого вызова, т.е. вызова в пределах одного сегмента кода. Т.о., после отработки команды ret управление вернется на следующий адрес после вызова подпрограммы. Поэтому переменная handle за командой ret никоим образом не будет использована, как код. Если только не будет туда явный переход!
© Цитата:
Почему объявление переменной Handle – в коде программы, как объявляются переменные (или данные) в начале программы или в конце? Опять же про оформление (какой есть стандартный порядок) – голова, тело, хвост?
Данная программа написана под ДОС, для модели памяти TINY (и код, и данные, и стек - в одном сегменте)
Поэтому абсолютно неважно, где записать данные. Разумеется, можно оформить отдельным сегментом данных. В других моделях памяти обычно так и делают, но можно писать и в сегменте кода. Это можно делать потому, что под ДОС-ом можно ч итать/писать откуда/куда угодно, из любого сегмента.
Вот если будете писать под систему Windows/Linux, вот там уже такие фокусы просто так не пройдут. Там, если сегмент кода, то ОС не даст туда писать данные! А команду из сегмента данных нельзя будет выполнить! Можно, но необходимо будет принимать дополнительные меры... :)
Теперь о порядке сегментов. Да пишите, как угодно, хоть в начале код, потом - данные, стек. Хоть в любом другом порядке. Это абсолютно не важно! Как кому нравится! Главное, чтобы данные не интерпретировались, как код. И то (под ДОС-ом!) можно сформировать последовательность команд, как байты данных и их отработать! :)
© Цитата:
Как применяется оператор "ret"? В Интернете, только и говорится – "в паре с командой call". Почему здесь оператор "ret" встречается в "свободном парении" (получается – куда захочу, туда и поставлю)? Есть ли еще, какие-то другие способы применения (может быть в паре с другими командами) оператора "ret"
Во-первых, как я уже объяснил, команда ret передает управление по адресу, который находится в вершине стека. Во-вторых, при старте программы выделяется сегмент в памяти, в начало которого записывается 100h некоторой информации (называется программный префикс PSP), первыми байтами записана команда int 20h. Далее, файл программы загружается, начиная с адреса 100h, а в стек заносится величина 0. И вот эта команда ret извлекает из стека этот нуль и передает туда управление, а там, что? int 20h. Тем самым происходит выход из программы! Ничего просто так и само не делается! Если выполнить просто так ret, то можно легко "улететь" неизвестно куда!
В-третьих, да, чаще всего ret используется в паре с call. Одно заносит в стек адрес возврата, второе извлекает его оттуда. Но занести в стек некий адрес можно разными способами! Например:
Код (Assembler) :: выделить код
	lea	ax, next
	push	ax
	ret
;
next:
После команды ret мы попадем на адрес next :)
Кстати, возможны и такие конструкции:
Код (Assembler) :: выделить код
	call	prg
	dw	0
prg:	pop	bx
	mov	word ptr[bx], 1234h
;...
Или такие:
Код (Assembler) :: выделить код
	call	prg
;...
prg:	pop	ax
;...
	jmp	ax
Или такие:
Код (Assembler) :: выделить код
table	dw	prg1,prg2,prg3,prg4	
;...
	mov	bx, 2
	call	prg
;...
prg:	jmp	[bx+table]
;...
prg1:	ret
prg2:	ret
prg3:	ret
prg4:	ret
Что, по-Вашему, произойдет? smile smile

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 11.12.2017, 17:33
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное