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

Ассемблер? Это просто! Учимся программировать (FAQ)


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Ассемблер? Это просто! Учимся программировать (FAQ)
______________________________________

Выпуск N 039

Вопросы, которые поступили от подписчиков рассылки
"Ассемблер? Это просто! Учимся программировать"

Дата выхода: 2001-07-19


Вопрос №327

Здравствуйте Эксперты!
Подскажите пожалуйста как вывести на экран содержимое кокого-либо регистра? И как сделать так чтобы выводил в разных системах счисления?

Ответ

Здравствуйте, Sirius!
ну значение регистра ты можешь получить так
mov bl,10; после чего регистр bl = 10 или как-то иначе
если это флаговый регистр, или там ip например
можно вытащить через стек
ну это не важно

дальше тебе нужно преобразовать из числова в строку,
положим тотже BL

для 16 ричной системы логика перевода примерно такая
Делаешь строковую переменную в которой храниш

hexstr db '0123456789ABCDEF'

Дальше каждые 4 бита числа = 0..15, так-как у нас 16 символов, то берем оттуда один символ и добавляем его в строку.

4 бита получаем примерно таким образом
Пример перевода BX в строковой число 16 ричной системы изчисления.

strhex db ' h',0; делаем строку из 2 пробелов, буквы h и 0 на конце
{тут я могу быть не прав}

...
mov si,offset hexstr; отсюда будем брать символы
mov di,offsert strhex; получаем в es указатель на строку
xor ah,ah; а вдруг там что-то есть, делаем ah=0
mov al,bl; сохраним bl для будующих покалений
anf al,$F; получаем первые 4 бита числа
add si,ax; интересно пройдет такой фокус или нет :)
mov al,[si]; так или иначе в AL у нас ASCII символ первых 4 байт
stosb; кладем его в строку и переходим на следующий символ
mov si,offset hexstr; отсюда будем брать символы
shr al,4; получаем последние 4 бита
add si,ax; интересно пройдет такой фокус или нет :)
mov al,[si]; так или иначе в AL у нас ASCII символ первых 4 байт
stosb; кладем его в строку и переходим на следующий символ
....
далее через биос ты можешь спакойно вывести строку strhex

Для других систем счисления думай сам, хотя мой способ не идеале тоже, главное обяснгить как это делается



Отправил эксперт: VD (vdragon-pas.chat.ru - Программирование графики на Пакаль со вставками на)
Эксперт отправил ответов (всего): 6

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №335

Есть вопрос к уважаемым экспертам.
Имеем два компа. На расстоянии 70-80 метров
друг от друга. Один комп имеет соединение с интернетом,
второй нет. Как лучше их объединить в сеть, и можно ли со второго компа(не имеющего выход в инет) включать первый и соединяться с интернетом.Как это осуществить? Какие
сетевые карты лучше подходят для такого расстояния?
Какой кабель? И.т.д...
Спасибо за подробный(!) ответ.

Ответ

Здравствуйте, Oleg!
Лучше всего соеденить их кабелем :)
коаксиальным, т.к. у вас 2 машины и я думаю вам 10 мб хватит выше крыши, и по этому вы можете купить любую сетевуху (2 шт.) хотя лучше 3com.
Интернет можно распредилить при помощи установки PROXY (WINGATE)


Отправил эксперт: VD (vdragon-pas.chat.ru - Программирование графики на Пакаль со вставками на)
Эксперт отправил ответов (всего): 8

Экспертная группа: Модели, виды и типы компьютеров (hard)

Вопрос №341

Привет, товарищи эксперты.
Прочитал я прошлый номер рассылки и захотелось мне написать свой первый резидент. Который бы банально запрещал удалять файлы с определенного диска.
Написал. Запустил. Не работает. :)
Просто зависает и все. Хотел было отладить, да как его отладишь, если он резидент?
Ошибок вроде и нет, а не работает.
Заранее спасибо,

Ответ

Здравствуйте, Stepan Yar!
Прости, глубоко уважаемый, но у тебя тут целых две логических ошибки в понимании механизма написания резидента. Пункт первый - оставляя резидент в памяти ты "забываешь" данные, которые находятся в памяти раньше, чем new_21H. Рецепт - перенеси их за iret. Пункт второй - когда ты переходишь на метку next: , то возникает такая вещь - из прерывания ты не выходишь. Рецепт - поставить iret, перед Init.
Если не будет работать все равно - пиши исправленный вариант, будем думать дальше...


Отправил эксперт: Александр
Эксперт отправил ответов (всего): 57

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №338

Где взять доку в электронном виде, для начинающего
асматика. желательно URL

Ответ

www.kalashnikoff.ru


Отправил эксперт: Nik
Эксперт отправил ответов (всего): 27

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №344

Привет, товарищи эксперты.
При попытки апдейта биоса столкнулся с проблемой:
Утилита awdflash.exe пишет ошибку - "Unknown Flash Type!"
Хотя флэш тайп у меня как был так и стоит, я его не трогал с момента покупки компьютера.

Award v4.51PG
580VPX-ITE8661-2A5LDL1CC
DATE: 08/28/97

Ответ

Здравствуйте, Space™!
Посмотри по документации, как надо расположить джампер для того чтобы разрешить запись в БИОС, по всей видимости по умалчанию там сейчас стоит запрет.


Отправил эксперт: Роман
Эксперт отправил ответов (всего): 7

Экспертная группа: Модели, виды и типы компьютеров (hard)

Вопрос №343

Такой вопрос:

MOV BX, 103h
MOV AX,4F02h
INT 10 h

Далее я получаю доступ только к одному сегменту памяти и
соответственно только к части экрана, а как найти адреса остальных сегментов ??????7
Заранее благодарю за ответ.

Ответ

Попробуй так

AX = 4F05h
BH = 00h; Установка видео окна
DX = (n) Адрес куска памяти размером 0xFFFF
BL = 0; номер окна (0-A, 1-B)

Это позволит тебе переключать видео банки.
После вывод все в тот-же сегмент 0A000h

P.S. Если еще не понял, вся память видео карты не влезает в 64Кб отведенные ей системой, поэтому ее разделили на видео банки к которым ты можешь обращаться переключая их по мере надобности. Более подробно можешь узнать из описания VESA например на моей страничке.

http://vdragon-pas.chat.ru
В разделе TEXT


Отправил эксперт: VD (vdragon-pas.chat.ru - Программирование графики на Пакаль со вставками на)
Эксперт отправил ответов (всего): 9

Экспертная группа: Пользовательская работа c DOS

Вопрос №349

Уважаемые эксперты,объясните как перевести монитор в "зеленый" режим ?

Ответ

Здравствуйте, Николай!
Монитор ПК можно перевести в одно из следующих состояний: ON,OFF,STANDBY,SUSPEND,REDUCED.
Делается это следующим образом:
- Проверка версии VBE:
mov ax, 4f10h
xor bx, bx
xor di, di
mov es, bx
int 10h
Теперь, если AL=4fh и AH=00h, то Power Manegement поддерживается.
- Установка режима:
mov ax, 4f10h
mov bx, 0xx01h
int 10h
Где, xx = 0x00(ON), 0x04(OFF),
0x01(STANDBY), 0x02(SUSPEND), 0x08(REDUCED).
Прошу прощения за краткость.


Отправил эксперт: AVC
Эксперт отправил ответов (всего): 3

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №350

Hi, Exprts!
Пытаюсь написать процедуру генерирования случайных чисел с помощью микросхемы таймера.
За основу взял алгоритм, описанный в книге Журдена. На всякий случай, опишу его.

Работаем со вторым каналом микросхемы таймера. В регистр ввода-вывода посылаем максимальное значение требуемого
диапазона случайных чисел. Из этого регистра это значение попадает в регстр-защелку, и там хранится пока туда не будет
положено какое-либо другое значение. Из регистра-защелки это значение
попадает в регистр-счетчик и там уменьшаеся до тех пор, пока не обнулится. Когда обнулится, в регистр-счетчик опять попадает значение из защелки. Стало быть, в любой момент времени в счетчике должно находиться произвольное значение от 0 до значения, хранимого в защелке. Для того, чтобы в ходе работы программы получить случайное число, нужно значение из счетчика забросить в задвижку (это позволяет сделать сброс 4, и 5 битов слова состояния регистра управления). Теперь из канала закидываем его в регистр общего назначения (al) и сохраняем в переменной.
Затем восстанавливаем значение в задвижке, изменяем значения 4 и 5 битов в слове состоянии, чтобы процессор мог читать из задвижки. И так продолжается дальше...

Для визуального контроля того, как отрабатывает мой генератор случ.чисел состряпал простенькую программку, которую, собственно, и прилагаю. В ней в цикле на экран выдаются "рожицы", а цвет для них задается случайным числом в диапазоне от 0 до 15.
Но у меня выходит так, что все символы выводятся в желтом цвете. Т.е. получается, что мой генератор выдает только максимальное значение задаваемого диапазона.

Просьба подсказать, где ошибка...

Thankx in advance

Ответ

Здравствуйте, Vano!
- В вашей программе:
Вызывать SetRange надо только один раз, в самом начале. После установки диапазона желательно немного подождать, иначе первое число всегда будет равно range. Следующие строки следует закомментировать:

mov al,word_out ; Перенести слово состояния в
out reg_command,al ; регистр управления ч/з al
;;; ; Теперь в рег.-задвижке находится
;;; ; значение из рег.-счетчика
;;; mov al,word_in ; Восстановим 5-ый бит слова состояния,
;;; out reg_command,al ; чтобы процессор мог читать из ре-
;;; ; истра-задвижки
in al,reg_in_out ; Забрать в al значение из рег.ввода/вывода
mov random,al ; В переменную занести случ.число
;;; call setRange ; Восстановить диапазон случ.чисел


Отправил эксперт: AVC
Эксперт отправил ответов (всего): 4

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №350

Hi, Exprts!
Пытаюсь написать процедуру генерирования случайных чисел с помощью микросхемы таймера.
За основу взял алгоритм, описанный в книге Журдена. На всякий случай, опишу его.

Работаем со вторым каналом микросхемы таймера. В регистр ввода-вывода посылаем максимальное значение требуемого
диапазона случайных чисел. Из этого регистра это значение попадает в регстр-защелку, и там хранится пока туда не будет
положено какое-либо другое значение. Из регистра-защелки это значение
попадает в регистр-счетчик и там уменьшаеся до тех пор, пока не обнулится. Когда обнулится, в регистр-счетчик опять попадает значение из защелки. Стало быть, в любой момент времени в счетчике должно находиться произвольное значение от 0 до значения, хранимого в защелке. Для того, чтобы в ходе работы программы получить случайное число, нужно значение из счетчика забросить в задвижку (это позволяет сделать сброс 4, и 5 битов слова состояния регистра управления). Теперь из канала закидываем его в регистр общего назначения (al) и сохраняем в переменной.
Затем восстанавливаем значение в задвижке, изменяем значения 4 и 5 битов в слове состоянии, чтобы процессор мог читать из задвижки. И так продолжается дальше...

Для визуального контроля того, как отрабатывает мой генератор случ.чисел состряпал простенькую программку, которую, собственно, и прилагаю. В ней в цикле на экран выдаются "рожицы", а цвет для них задается случайным числом в диапазоне от 0 до 15.
Но у меня выходит так, что все символы выводятся в желтом цвете. Т.е. получается, что мой генератор выдает только максимальное значение задаваемого диапазона.

Просьба подсказать, где ошибка...

Thankx in advance

Ответ

Здравствуйте, Vano!
У тебя то ли программа не дописана, то ли это кусок
После строк
start:
call setRange ; Установить диапазон
call dispScr ; Заполнить экран рожицами
надо закончить прогу, чтоли...
Если же это кусок
то все равно в начале проги надо поставить
csg segment para
assume cs:csg
org 100h
begin:
mov ax, cs;!!!
mov ds, ax;!!!
assume ds:csg;!!!
jmp start
либо вписать строчку
.model tiny


Отправил эксперт: Sensey
Эксперт отправил ответов (всего): 24

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №351

здравствуйте!
вопрос такой:
при попытке скомпилировать программу на TASM5 в (командной строке пишу tlink.exe /v fail.obj), получаю сообщение: Loader error (0001): out of memory
при запуске tlink.exe тоже самое.
Что не так?

Ответ

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

Без /v ты тоже пробовал?
может у тебя что-то с размерами сегментов не так?


Отправил эксперт: Dron
Эксперт отправил ответов (всего): 36

Экспертная группа: Работа с MASM/TASM

Вопрос №345

Здравсвуйте, ув. эксперты.
У меня возникла проблема с моей прогой.
Я написал процедуру копирования файлов.
Имена файлов для этой процедуры я передаю через стек.И в самой процедуре использовал 21h прерывание.
В результате после того, как я вызываю int 21h, параметры в стеки изменяются и проседура возвращается на другой адресс.
(программу прилагаю)

Ответ

Здравствуйте, Дима!
1. Командой push offset from(to) вы помещаете в стек число, чего 8086 делать не умеет, поэтому лучше использовать директиву .286. Хотя в данном случае TASM сам сгенерировал нормальный код, но этот код медленный и более громоздкий.
2. Вы расположили буфер var в файле edit.asm, т. е. перед основной программой, поэтому при чтении в него некоторого кол-ва байт прежний код затирается, поэтому надо перенести буфер в конец основной программы.
3. Вы пытаетесь прочитать FFFF байт в буфер, не учитывая размера программы и размера стека, поэтому может произойти переполнение стека. Нужно читать поменьше байт в буфер.
Прилагаю работающий вариант программы.

С уважением, Basfer.

Приложение:


Отправил эксперт: Basfer
Эксперт отправил ответов (всего): 5

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №341

Привет, товарищи эксперты.
Прочитал я прошлый номер рассылки и захотелось мне написать свой первый резидент. Который бы банально запрещал удалять файлы с определенного диска.
Написал. Запустил. Не работает. :)
Просто зависает и все. Хотел было отладить, да как его отладишь, если он резидент?
Ошибок вроде и нет, а не работает.
Заранее спасибо,

Ответ

Здравствуйте, Stepan Yar!
Вы неправильно сохраняете адрес первичного обработчика 21h прерывания. Для того, чтобы переходить по jmp надо, чтобы сначала было сохранено смещение и потом сегмент, а у Вас наоборот. Для этого просто меняем местами строчки old_cs dw ? и old_ip dw ?. Соответственно надо переделать и адрес перехода: jmp dword ptr cs:old_ip.
Еще надо выделить проге хотя бы на 1 параграф памяти больше: mov dx, (...)/16 + 1.
С уважением, Basfer.


Отправил эксперт: Basfer
Эксперт отправил ответов (всего): 6

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №350

Hi, Exprts!
Пытаюсь написать процедуру генерирования случайных чисел с помощью микросхемы таймера.
За основу взял алгоритм, описанный в книге Журдена. На всякий случай, опишу его.

Работаем со вторым каналом микросхемы таймера. В регистр ввода-вывода посылаем максимальное значение требуемого
диапазона случайных чисел. Из этого регистра это значение попадает в регстр-защелку, и там хранится пока туда не будет
положено какое-либо другое значение. Из регистра-защелки это значение
попадает в регистр-счетчик и там уменьшаеся до тех пор, пока не обнулится. Когда обнулится, в регистр-счетчик опять попадает значение из защелки. Стало быть, в любой момент времени в счетчике должно находиться произвольное значение от 0 до значения, хранимого в защелке. Для того, чтобы в ходе работы программы получить случайное число, нужно значение из счетчика забросить в задвижку (это позволяет сделать сброс 4, и 5 битов слова состояния регистра управления). Теперь из канала закидываем его в регистр общего назначения (al) и сохраняем в переменной.
Затем восстанавливаем значение в задвижке, изменяем значения 4 и 5 битов в слове состоянии, чтобы процессор мог читать из задвижки. И так продолжается дальше...

Для визуального контроля того, как отрабатывает мой генератор случ.чисел состряпал простенькую программку, которую, собственно, и прилагаю. В ней в цикле на экран выдаются "рожицы", а цвет для них задается случайным числом в диапазоне от 0 до 15.
Но у меня выходит так, что все символы выводятся в желтом цвете. Т.е. получается, что мой генератор выдает только максимальное значение задаваемого диапазона.

Просьба подсказать, где ошибка...

Thankx in advance

Ответ

Здравствуйте, Vano!
Вы не разрешили работу 2-ого канала. Для этого нужно установить в 1 0-й бит 61h порта. Т.е. перед ret функции SetRange вставляем:

in al, 61h
or al, 1
out 61h, al
И все должно заработать. Однако чаще всего будут появляться черные и желтые рожицы, так как таймер вызывается 18.2 раза в секунду, а значений генератора всего 15(0-E).

С уважением, Basfer.


Отправил эксперт: Basfer
Эксперт отправил ответов (всего): 7

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №355

Помогите пожалуйста!!! Как можно изменить код проги *.exe весом в 590 кБ, если IDA создает *.asm из нее длиной в 3,8 мега!!!!
(около 20 000 страниц текста, сами понимаете...) я этот *.asm всеже открыл каким то образом в ворде (грузился минуты 2) и поменял таки строки нужные мне... но вот новая беда: ТАСМ -у не хватает памяти для ассемблирования... Помогите кто чем может!!!!

Ответ

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

Можно попробовать следующее:
1) Если уж компилировать asm-файл, то можно попробовать разбить его на несколько модулей. Таким образом TASM-у не прийдется компилировать большой текст, а компоновщик должен справиться, т.к. объектные файлы уже такими большими не будут. Недостаток этого метода - большая трудоёмкость.
2) Можно вообще не дизассемблировать код. Т.е. так как Вы уже знаете, что менять, можно это сделать утилитой вроде Hiew. Есть конечно проблема, если Вы будете менять размер кода.
3) Можно компилировать не TASM-ом. Достать более современный компилятор, который может работать в защищенном режиме.
4) В данном варианте я не очень компетентен, но наверняка в IDA есть опции указывающие ему выдавать более удобоваримые исходники.
Надеюсь, что поможет.

С Уважением, AVC.


Отправил эксперт: AVC
Эксперт отправил ответов (всего): 5

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Вопрос №352

В одной программы (для скорости) мне понадобилось знать, где лежит то слово, в котором ДОС хранит позицию курсора.

Вопрос 1: По какой формуле можно найти его адрес...

Вопрос 2: Ну и раз уж я спросил про формулу, то где лежит тот байт, в котором записана текущая страница, (или, может быть, активна та страница, в поле которой курсор?)

Для того чтоб узнать ответы на данные вопросы, я залез в ДОС? И нашел вместо ответов еще три вопроса?

Вопрос 3: AfdPro дизассемблировал кусок 21h прерывания так: 36FE060203 INC B/SS:[0302]. Я не въехал, что есть "B/". Вот все остальное понял, а это?

Вопрос 4: Вот, как одну и туже последовательность байт (из Int 21h) видят:

Hiew 6.40:

00000000: 7415 je 000000017
00000002: C4 ???
00000003: C442EB les ax,[bp][si][-0015]
00000006: 389080FC cmp [bx][si][0FC80],dl
0000000A: F0 lock
0000000B: C3 retn

TD:

cs:0100>7415 je 0117
cs:0102 C4C4 les ax,sp
cs:0104 42 inc dx
cs:0105 EB38 jmp 013F
cs:0107 90 nop
cs:0108 80FCF0 cmp ah,F0
cs:010B C3 ret

AfdPro:

0100 7415 JZ 0117
0102 C4 DB C4
0103 C442EB LES AX,[BP+SI-15]
0106 389080FC CMP [FC80+BX+SI],DL
010A F0 LOCK
010B C3 RET

Кто прав? Единственное что везде совпадает это Ret, да и тот я специально поставил, его в прерывании не было J

Вопрос 5: Почему в Int 10 после команды "C4" в Dx чудодейственным образом попадало положение курсора, да еще в виде X/Y, а не Y*80+X? При этом во всех остальных регистрах ничего похожего не было?

Ответ

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

1. позицию курсора хранит BIOS вообще-то.
хранится она вот где:
40:0050 16 байт... позиция курсора для 8 страниц парами по два байта - младший байт - x, старший байт - у. те: x1, y1, x2, y2, x3, y3...

2. 40:004e - смещение в видеосегменте (b800 или b000 для MDA) для активной страницы.

3. Я думаю это типа byte ptr... надо же указать с каким размером памяти работать!

4. Мне кажеться что правильнее всех сказал TD,
ибо lock перед ret не используется!!!


Отправил эксперт: Dron
Эксперт отправил ответов (всего): 37

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Подписаться на рассылки

Рассылки Subscribe.Ru
Ассемблер? Это просто! Учимся программировать
Ассемблер? Это просто! Учимся программировать (FAQ)

Форма подачи вопроса

ВНИМАНИЕ!!! Пожалуйста, НЕ высылайте один вопрос сразу нескольким подгруппам! Если Вы сомневаетесь, какой подгруппе следует отправить вопрос, то направляйте его в обычном текстовом виде по адресу Experts@Kalashnikoff.ru. Вопрос будет выслан соответствующей подгруппе с некоторой задержкой (от 1 до 3-х суток).
Дополнения к вопросам, на которые эксперт уже ответил НЕ следует направлять ведущему рассылки (я не успеваю!). Просто скомбинируйте первый вопрос и дополнение к нему, а затем заново отправьте его, используя приведенную ниже форму!

Нажимайте кнопку "Отправить" только ОДИН раз и дождитесь полной загрузки страницы, иначе вопрос будет продублирован!


Ваше имя *:

Ваш e-mail *:

Подгруппы:

Вопрос *:

Прилагаемая программа (если необходимо):


Регистрация в качестве эксперта

Архив выпусков


Ведущий рассылки,

Калашников Олег: Assembler@Kalashnikoff.ru
ICQ No.:
68951340
URL сайта подписчиков: http://www.Kalashnikoff.ru

______________

По вопросам сотрудничества, рекламы и спонсорства обращайтесь:

  1. Публичное размещение материала из рассылки: Cooperation@Kalashnikoff.ru
  2. Реклама на сайте, в книге и рассылках: http://www.Kalashnikoff.ru/Reklama.html, Reklama@Kalashnikoff.ru
  3. Издание книги (спонсорство): Sponsor@Kalashnikoff.ru

Рассылка 'Ассемблер? Это просто! Учимся программировать (FAQ)' Рассылка 'Ассемблер? Это просто! Учимся программировать'


(C) Москва, 2001. Авторское право принадлежит Калашникову О.А. Публичное размещение материала из рассылки, а также его использование полностью или частично в коммерческих или иных подобных целях без письменного согласия автора влечет ответственность за нарушение авторских прав.


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться Рейтингуется SpyLog

В избранное