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

RusFAQ.ru: программирование на языке Assembler


Информационный Канал Subscribe.Ru

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

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Assembler

Выпуск № 195
от 24.07.2005, 20:20

Администратор:Калашников О.А.
В рассылке:Подписчиков: 253, Экспертов: 14
В номере:Вопросов: 6, Ответов: 14


Вопрос № 23684: Вопрос такой : какой ассеблер поддерживает ключевое слово LOCALS и он же поддерживает конструкции вида move byte ptr [bx], offset @@1 - offset labelN? Мне чтобы скомпилировать понадобилось move byte ptr [bx], byte ptr [offset @@1 - ...
Вопрос № 23687: Приношу извенения за предыдущие вопросы, которые задовал по несколько раз. :-) Уважаемые эксперты не могли бы вы объяснить мне словестно, как устроена 32-ух разрядная организация памяти. Можно ли 32-ух разрядную адресацию использо...
Вопрос № 23696: Здравствуйте! У меня такой вопрос. Делею несколько объектных модулей. В одном делаю PUPLIC процедуру. Хочу вызвать ее с другого. Компилируется, ругается: Calll1.obj(calll1.asm) : warning L4004: possible fixup overflow at 8 in segment...
Вопрос № 23698: Здравствуйте! Еще вопрос: программа не более 1 кб. Хочу оставить резидентой в младших адрессах. Пробовал копировать, по случайному адрессу, но затер что-то важное. Как узнать, куда можно скопировать? Если бы еще и пометить, что даный участок пренадле...
Вопрос № 23730: Добрый день. У меня вопрос относительно всем известной рассылки Калашникова. В 23-ем выпуске, где рассматривается резидент, записывающий нажимаемые пользователем клавиши, обработчик 9-го прерывания содержит следующие строки: 1 cli ;Запрещаем ...
Вопрос № 23734: Добрый день! Я изучаю 17 урок. Там следующий текс: Обратите внимание, как мы просто вычисляем длину строки. Но это только в том случае, если длина строки известна: Mess_quit db 'Ассемблер',0 Mess_quitl equ $-Mess_quit Причем, последн...

Вопрос № 23.684
Вопрос такой : какой ассеблер поддерживает ключевое слово LOCALS и он же
поддерживает конструкции вида
move byte ptr [bx], offset @@1 - offset labelN?
Мне чтобы скомпилировать понадобилось
move byte ptr [bx], byte ptr [offset @@1 - offset labelN] делать
на ml.exe 6.14.xxxx
Тогда все работало замечательно...
Отправлен: 18.07.2005, 20:00
Вопрос задал: Some Stupid Guy (статус: Посетитель)
Всего ответов отправлено: 2

Отвечает: Евгений Иванов
Здравствуйте, Some Stupid Guy!
LOCAL поддерживает TASM, MASM.

proc Edge_add
ARG @@ei: dword, @@type :dword, @@pos :dword
USES esi, edi, ebx, ecx, edx, eax
LOCAL @@z :dword

---------
Что имеем - не храним, потерявши - плачем
Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 18.07.2005, 21:37
Оценка за ответ: 3

Отвечает: DSota
Здравствуйте, Some Stupid Guy!

Ключевое слово LOCALS в его виде с буквой "S" поддерживает только TASM.
Правда и он не скомпилит эту строку, но он точно скомпилит:
"mov byte ptr [bx], offset @@1 - offset labelN"
(там буквы "e" в слове "move" нет).

---------
Открыть глаза навстречу солнцу.
Ответ отправил: DSota (статус: Практикант)
Отправлен: 19.07.2005, 10:39
Оценка за ответ: 5


Вопрос № 23.687
Приношу извенения за предыдущие вопросы, которые задовал по
несколько раз. :-)
Уважаемые эксперты не могли бы вы
объяснить мне словестно, как устроена 32-ух
разрядная организация памяти.
Можно ли 32-ух разрядную адресацию использовать
в чистом DOS-е.
Я врде читал, что можно 32-ух разрядные регистры использовать,
только нужно следить, чтобы они не превыщали объем 16-го.
Отправлен: 18.07.2005, 20:46
Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель)
Всего ответов отправлено: 2

Отвечает: Евгений Иванов
Здравствуйте, Терсков Алексей Николаевич!
можно использовать, но опять же сегменты.
и действительно будет только младшие 16 бит.
но старшие нужно обязательно обнулять!

sub eax,eax
mov ax, 17h

push 4
pop ds
mov bl, [eax]
вот так вот можно.

удачи!


---------
Что имеем - не храним, потерявши - плачем
Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 18.07.2005, 21:34

Отвечает: Стас
Здравствуйте, Терсков Алексей Николаевич!
в дополнение:
1)Используй 32 регистры для арифметики и с осторожностью для адресации.
2)В чистом DOS-е можно также перейти и в защищенный режим, тогда вообще никаких ограничений в использовании 32 разрядных регистров.
Ответ отправил: Стас (статус: Практикант)
Отправлен: 19.07.2005, 00:53


Вопрос № 23.696
Здравствуйте!
У меня такой вопрос. Делею несколько объектных модулей. В одном делаю PUPLIC процедуру. Хочу вызвать ее с другого.
Компилируется, ругается:

Calll1.obj(calll1.asm) : warning L4004: possible fixup overflow at 8 in segment T1
target external 'Beep'
Calll1.obj(calll1.asm) : error L2002: fixup overflow at 8 in segment T1
target external 'Beep'
Calll1.obj(calll1.asm) : warning L4004: possible fixup overflow at B in segment T1
target external 'Quit'
Calll1.obj(calll1.asm) : error L2002: fixup overflow at B in segment T1
target external 'Quit'

Но файл запускается.
Привожу два ассемблерных файла
Командная строка линковки.

D:masm61inlink.exe Calll1.obj+L_1.obj, Cal_1.com,,, /t /nologo
Пробовал и ехе файлы - ругается, но файл запускается
Подскажиту, где ошибка. Пожалуйста, испрате asm файлы, если есть ошибка, и укажите параметры линковки и компилирования, если где-то ошибка.

Приложение:

Отправлен: 19.07.2005, 00:12
Вопрос задал: Igor Vlad. (статус: Посетитель)
Всего ответов отправлено: 2

Отвечает: Евгений Иванов
Здравствуйте, Igor Vlad.!

model поставь. TINY

и ты ret забыл в конце подпрограммы quit.

удачи.
---------
Что имеем - не храним, потерявши - плачем
Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 19.07.2005, 00:28
Оценка за ответ: 2
Комментарий оценки:
НЕ РАБОТАЕТ. А может просто нужно сегменты назвать одним именем?

Отвечает: Ayl
Здравствуйте, Igor Vlad.!

Ты определил 2 разных сегмента: t1 и text, но при этом внешнии ссылки указываешь через near. Вот в этом и причина - у тебя дальний вызов должен быть либо объявляй кодовый сегмент с одним именем.


---------
Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени
Ответ отправил: Ayl (статус: Профессор)
Отправлен: 19.07.2005, 11:38
Оценка за ответ: 5
Комментарий оценки:
Спасибо, я понял. Я так уже и пробовал.


Вопрос № 23.698
Здравствуйте! Еще вопрос: программа не более 1 кб. Хочу оставить резидентой в младших адрессах. Пробовал копировать, по случайному адрессу, но затер что-то важное. Как узнать, куда можно скопировать? Если бы еще и пометить, что даный участок пренадлежит DOS или еще какому-нибудь системному драйверу было бы просто замечательно!
Заранее благодарен!
Отправлен: 19.07.2005, 00:28
Вопрос задал: Igor Vlad. (статус: Посетитель)
Всего ответов отправлено: 4

Отвечает: Стас
Здравствуйте, Igor Vlad.!
Нельзя копировать куда угодно. Даже если не затрешь что нибудь важное - тебя кто нибудь затрет :).
Выделяй память DOS функцией (ah=48; int 21h). Либо нужно хорошо знать архитектуру DOS, этапы загрузки и т.п. Для того чтобы переместить что-то или даже затереть.
Ответ отправил: Стас (статус: Практикант)
Отправлен: 19.07.2005, 00:58

Отвечает: Евгений Иванов
Здравствуйте, Igor Vlad.!
смотри исходник, там технология записи в окружение и psp.

вот кусочек :))
это когда ищутся переменные окружения.

mov bx,88
push cx si
m162a:
mov cx,bx
m172a:
lodsb
cmp al,'='
jz m202a
loop m172a
jmp m142a
m212a:
pop bx ds
push dx
jmp m162a
m202a:
pushf
push si
std
sub si,2
mov di,ofs d1+5
mov bx,cx
mov cx,6
repz cmpsb
lahf
pop si
popf
sahf
jnz m162a
pop dx

всего хорошего!

Прикреплённый файл: Загрузить >>
Срок хранения файла на сервере RusFAQ.ru составляет 30 суток с момента отправки ответа.
---------
Что имеем - не храним, потерявши - плачем

Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 19.07.2005, 08:30

Отвечает: Котиев Зураб
Здравствуйте, Igor Vlad.!
можно использовать MSB (memory control block)

┌───┐ ┌──'M'(4dH) - за этим блоком есть еще блоки
+0 1 │Тип ├──┴──'Z'(5aH) - данный блок является последним
├───┴───┐
+1 2 │Владелец | параграф владельца (для FreeMem); 0 = владеет собой сам
├───┴───┤
+3 2 │Размер │ число параграфов в этом блоке распределения
├───┴───┴──────── ─ ────┐
+5 0bH│зарезервировано │
└───┴───┴───┴───┴ ─ ┴───┘

если ты пометишь владельца 0008h то владелец дос .сам mcb находится на один параграф ниже psp . тут те пара ссыл на тему
http://www.wasm.ru/article.php?article=1006005
http://www.wasm.ru/article.php?article=1006004
если есть вопросы залазь мне ко мне на форум
Ответ отправил: Котиев Зураб (статус: 5-ый класс)
Отправлен: 19.07.2005, 11:47

Отвечает: Ayl
Здравствуйте, Igor Vlad.!

Чую, чую, что вирусом пахнет!
В младших адресах... Хм... В младших адресах все занято...
Можно, конечно, попробовать прописаться в область векторов прерываний, начиная с адреса 0:200h (вторая половина таблицы, обычно неиспользуются), но при этом твоя программа должна быть не больше 512Кб.
Еще вариант - область видеопамяти, но это не младшие адреса.
Причем ты можешь часть кода прописать в область векторов (которая будет получать управление от прерывания), а основной код - в видеопамять.
Либо тебе нужно искать первый незанятый кусок памяти достаточного объема по цепочке MCB.

А для того, чтобы тебя не было видно, сам кусок памяти помечаешь как облать DOS (см. структуру MCB).

Приложение:

---------
Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени

Ответ отправил: Ayl (статус: Профессор)
Отправлен: 19.07.2005, 12:09
Оценка за ответ: 5
Комментарий оценки:
Спасибо за совет! Попробую.
Относительно вируса... Да. Но что я могу сделать под ДОСом?


Вопрос № 23.730
Добрый день.
У меня вопрос относительно всем известной рассылки Калашникова. В 23-ем выпуске, где рассматривается резидент, записывающий нажимаемые пользователем клавиши, обработчик 9-го прерывания содержит следующие строки:
1 cli ;Запрещаем все прерывания
2 pushf ;Дадим сперва управление...
3 call dword ptr cs:[0FCh] ;...оригинальному обработчику
4 pusha ;Сохраним регистры в стеке...
5 push es
6 push ds
7 cld ;Направление - вперед!
8 in al,60h ;Получим СКАН-КОД нажатой клавиши.
9 test al,10000000b ;(=80h) Это отпускание клавиши?
10 jnz Exit_09h ;Если так, то сохранять ее код не надо
11 mov ax,cs ;Сегментные регистры должны указывать на наш сегмент.
12 mov ds,ax
13 mov es,ax
14 mov ah,1 ;Получим ASCII-код нажатой клавиши.
15 int 16h
16 jz Ext_code ;Буфер клавиатуры пуст? Тогда на выход.
........................и так далее......................
Меня интересуют сроки 8-16. Что в частности делают строки 8 и 9? Почему в строке 9 проверяется именно число 80h? Что делают строки 14,15?
И еще один вопрос. При освобождении памяти функцией DOS 49h. Почему мы указываем только сегмент в регистре ES? Например, при выделении памяти мы еще указываем в регистре BX размер выделяемого участка. Здесь же почему-то только сегмент.

Заранее спасибо.
Отправлен: 19.07.2005, 18:45
Вопрос задал: AlexB (статус: Посетитель)
Всего ответов отправлено: 3

Отвечает: Евгений Иванов
Здравствуйте, AlexB!
1.
в строке 9 проверяется не число 80h, а там проверяется 7 бит - используется так называемая маска при операции И.
если бит проверяемый сброшен, то результат будет нулю и флаг ZF=1.
и наоборот.
2.
а ты посмотри, что там содержится по адресу
[ES - 1:0]
именно так. На 16 байт меньше.
там содержится блок управления памятью.
там тоже есть M и Z.
M - значит дальше есть блок
Z - последний блок.
ну и размеры там указываются блоков и кому он принадлежит - сегмент окружения по моему...
во вложении смотри программу, которая остаётся резидентной без каких либо функций доса ;)
она вклинивается в наиболее подходящий свободный блок памяти... потому что они не полностью заняты.. :)

удачи!!

Прикреплённый файл: Загрузить >>
Срок хранения файла на сервере RusFAQ.ru составляет 30 суток с момента отправки ответа.
---------
Что имеем - не храним, потерявши - плачем

Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 19.07.2005, 21:45

Отвечает: Стас
Здравствуйте, AlexB!
Опять позволю себе расшифровать:
>Почему в строке 9 проверяется именно число 80h?
Как сказал Евгений Иванов проверяется старший бит.
Дело в том, что при нажатии на кнопку на клавиатуре на 60 порт приходит её "порядковый номер". А когда ты ее отпускаешь то на 60 порт опять идет её порядковый номер + 80h (128). Таким образом когда ты просто нажимашь(и отпускашь) на клаве кнопку "A" - Int 9 срабатывает ДВА раза на нажатие и на отпускание. Так вот - "9 test al,10000000b ;(=80h) Это отпускание клавиши?" фиксирует именно отпускание клавиши, игнорируя её нажатие.

Про память проще - когда выделяешь память - системе нужно знать сколько тебе нужно, когда высвобождаешь системе этого знать не надо - так как она сама хранит размер выделеного блока. Иначе как выделить следующий если не знаешь размеров всех блоков которые есть в системе в текущий момент?
Ответ отправил: Стас (статус: Практикант)
Отправлен: 20.07.2005, 00:37

Отвечает: Ayl
Здравствуйте, AlexB!

Строка 8 - получить значение из порта 60h. Порт 60h - это один из интерфейсных портов для работы с клавиатурой, в нем находится скен-код последней нажатой или отпушенной клавиши. Да-да, именно или нажатой, или отпущенной.
Когда пользователь работает с клавиатурой, то последняя отслеживает все изменения состояния клавиш. Когда пользователь нажимает клавишу, то контроллер клавиатуры помещает в 60-й порт ее скен-код (число от 1 до 127). То есть, байт, у которого старший бит равен 0. И выдает прерывание IRQ1. Когда пользователь отпускает клавишу, то КК помещает в 60-й порт скен-код, увеличенный на 128. То есть, байт, у которого старший бит равен 1.
С помощью команды в строке 8 мы считываем это код, а с помощью команды в строке 9 проверяем, установлен ли старший бит, т.е. нажата ли или отпущена клавиша.

Строки 14 и 15 проверяют, есть ли в буфере клавиатуры какая-либо клавиша.
Это вызов прерывания 16h BIOS. В области BIOS выделяется 32-байтная область, которая называется буфером клавиатуры. Эта область организована по принципу очереди (FIFO - First In, First Out; первым пришел - первым ушел). В нее помещается информация о нажатых клавишах (2 байта, старший байт - скен-код, младший - ASCII-код либо 0). Функция 1 прерывания 16h проверяет, есть ли что-то в буфере, и в зависимости от этой проверки устанавливает флаг ZF (ZF = 0 => буфер пуст, ZF = 1 => в буфере что-то есть).

При выделении памяти DOS предваряет выделенную область специальным 16-байтным заголовком, т.н. контрольным блоком памяти (MCB - Memory Control Block). В этом блоке содержится информация о расположении блока в цепочке (последний/непоследний), о владельце блока (адрес PSP владельца или 0 для нераспределенных блоках), о размере блока в параграфах и т.п.
При освобождении памяти нам достаточно указать только сегмент освобождаемого блока, т.к. информация о размере блока будет взята системой из соответствующего MCB.

---------
Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени
Ответ отправил: Ayl (статус: Профессор)
Отправлен: 20.07.2005, 12:42


Вопрос № 23.734
Добрый день! Я изучаю 17 урок. Там следующий текс:
Обратите внимание, как мы просто вычисляем длину строки. Но это только в том случае, если длина строки известна:
Mess_quit db 'Ассемблер',0
Mess_quitl equ $-Mess_quit
Причем, последняя строка занимать памяти не будет! В отладчике строка
mov dx,offset Mess_quitl
будет выглядеть как
mov dx,9.
Так как строка Mess_quitl equ $-Mess_quit не занимает памяти, то в строке mov dx,offset Mess_quitl я не понимаю “кого” мы заносим смещение в регистр dx? Зачем нужен offset?
Отправлен: 19.07.2005, 19:17
Вопрос задал: Programist (статус: Посетитель)
Всего ответов отправлено: 1

Отвечает: John Freeman
Здравствуйте, Programist!
Последняя строка в смысле
Mess_quitl equ $-Mess_quit
это константа, которая будет вычислена компилятором и подставлена везде где юзается $ - текущий адрес , $-mess_Quit - разность адресов начала и конца строки= длина строки
---------
You're trying to take me They trying to make me This is the only Gives me the only thing Tired of lying, I'm tired of lying The only thing I inderstand is what I feel...
Ответ отправил: John Freeman (статус: Профессор)
Отправлен: 19.07.2005, 19:55


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2005, RusFAQ.ru, Россия, Москва. Все права защищены.
Идея, дизайн, программирование, авторское право: Калашников О.А.

Яндекс


Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.faq
Отписаться
Вспомнить пароль

В избранное