::Главная страница :: Assembler :: Статьи ::

FAQ 1-10

1. Проблема в отладке программы (исходников нет, только exe). Программа перехватывает прерывание INT 3h. При отладке в td.exe перехвата INT 3 компьютер зависает. Отладчик конечно тоже использует это прерывание. Заменить INT 3 на другое не удаётся, т.к. занимает один байт. Как можно выйти из положения.
Замени на NOP (90h) (Эта команда ничего не делает, только отнимает такты процессора).
Nik


2. При написании программы типа "звездное небо" я столкнулся с одной трудностью. Как в ассемблере сгенерировать случайное число. Надо чтоб оно было полностью случайным. INT 2Ch не подходит, так как сотые доли секунд периодичны и точки на экране скапливаются в линииобразных промежутках.
Вот вроде как генератор сл. чисел.

.model tiny
 .code
 .286
 org 100h
 start:
  call del_old
  mov ax,60
  call rnd
        call    divide
        call    print_num
  mov ah,1
  int 16h
        je     start
        ret
 divide:
        mov     bx,10
        mov     bp,offset [num]+4
 cont_div:
        xor     dx,dx
        div     bx
        add     dl,'0'
        mov     [bp],dl
        dec     bp
        or      ax,ax
        jne     cont_div
        ret
 print_num:
        mov     dx,offset num
        mov     ah,9
        int     21h
        ret
 del_old:
  mov di,offset num
  mov al,32
  mov cx,5
  rep stosb
  ret
 r1 dw 10050
 r2 dw 30066
 r3 dw 45611
 rnd:
  mov bx,ax
  mov ax,r1
  add ax,r2
  mov r1,ax
  add ax,r3
  mov r2,ax
  ror ax,1
  mov r3,ax
  mul bx
  xchg ax,dx
  ret
 num     db '     ',0dh,0ah,'$'
 end start
 K.A. NiCK

3. Вопрос "чайника". Что есть порт? Где находяться порты - в отдельном чипе (проц, северный аль южный мосты) или разбросаны по разным микрухам компа. Если можно по подробнее, что есть номер порта (номер порта FFh и адрес ячейки памяти FFh - я знаю, суть разные вещи). И еще порт и адрес ввода/вывода - это одно и тоже?
Во первых, разберемся, какие порты нам нужны. COM, LPT - последовательный и параллельный соответственно:
это обыкновенные разъемы, к которым например подключаются мыша, принтер, момед(если внешний) и тд. тна практике обычно есть 2 COM и 1 LPT порт(как устройства.). хотя теоретически (тоесть для программ) могут быть доступны и COM4 и даже COM7.
Собственно же программа (втч твоя) работает с т.н. Портами ввода-вывода. вот их определение из книжки: "порт i/o - 8,16 или 32-разрядный аппаратный регистр(не путать с регистрами проца - прим. от меня), имеющий определенный адресв адресном пространстве ввода-вывода" Номер порта - ну как объяснить? вот десять портов (предположим) - так что им, каждому имя давать? зачем? когда их можно просто пронумеровать 0..9. на самом деле их количество ограничено размерностью адр. пр-ва ввода-вывода - FFFFh штук. например таймер имеет 4 порта - 40h..43h (для различных каналов. не буду я тут схему работы таймера разбирать.). фактически, обращаясь к портам i/o ты общаешся с устройствами почти напрямую. для этого используются команды in и out: in <аккумулятор - eax/ax/al>, из порта считывается байт/слово/дв.слово в аккумулятор.
out ,содержимое аккумулятора пересылается в порт N. Да. если номер порта <0FFh то можно задавать его непосредственно, иначе - через
dx:xor ax,ax
mov dx,100h ;порт с большим номером
out dx,ax ;выводим в этот порт нолик. кроме того, для вывода/ввода не по байтам, а строчками есть команды
ins,outs (вернее ins/insb/insw/insd и ан-но outs/...) перед вызовом их в dx вносим номер порта, в es:di - строку для вывода, а для ins - результат будет по адресу es:di.
Event


4. Вот хотел спросить: вроде как я прочитал, функция 0С 33h прерывания должна реагировать на прерывания поступающие от мыши и вызывать определенную мной процедуру, но делает она это только, когда ее в цикл запихиваешь. Так и должно быть?
Дело в том, что эта функция только опрашивает мышь, но не ждет действий от нее, как при работе с клавиатурой. Поэтому ее и надо помещать в цикл, чтобы "поймать" движение мыши (комп-то это делает мгновенно).
Старчиков Алексей

5. У меня к Вам вопрос по поводу динамического выделения памяти. При использовании ДОСовской функции 48h возникает ошибка 08h (недостаточно памяти). Хотя я пытаюсь выделить всего лишь один параграф. Может я чего не так делаю?
Прежде, чем отводить память функцией 48h, необходимо "урезать" память при помощи функции 4Ah. Зачем? Дело в том, что сразу после загрузки программы (причем, любой), DOS отводит ВСЮ память этой программе. Поэтому нам сперва нужно использовать функцию 4Ah, чтобы "урезать" память до размеров программы, а затем только отводить блоки.
Подробней можно посмотреть как мы делаем в оболочке в рассылке по Ассемблеру (28 выпуск).
Прилагаю кусок кода, который урезает память до размеров загруженной программы.


        mov bx,offset Finish
       shr bx,4
       inc bx
       mov ah,4Ah
       int 21h    ;Ужимаем размер отведенной памяти до метки Finish
 ....
 Finish equ $ ;Самая последняя строка в программе!
 Отправил: Олег Калашников  

6. Как убрать задержку перед началом повтором вывода символа?(для игры)
Ответ1 (Ламерский): В документации напиать, что в Windows Панель Управления/Клавиатура надо настроить этот параметр. Не подходит, нужно ведь для DOS.
Ответ2 (Юзерский): Написать, как тот же параметр настроить через BIOS Setup.
Ответ3 (Программерский):
mov ax,0305h ;здесь не уверен, может 0300 ?
mov bx,0 ;bh=0 - 0,25 секунды
;bh=1 - 0,5 секунды
;bh=2 - 0,75 секунды
;bh=3 - 1,0 секунды
Int 16h
Ответ4 (наверно Хакерский:)): Написать свой обработчик прерывания int 9, отвечающего за обработку прерываний от клавиатуры
Александр


7. Что и в какой последовательности располагается в оперативной памяти компьютера после того, как мы его включаем? Конечно, при условии, что в нём есть DOS.:)) Т.е. хотелось бы уяснить себе структуру расположения данных в оперативной памяти (если это возможно, то с размерами).
Стандартная память(первые 640Кб)
00000-003FF Таблица векторов прерываний
00400-004FF BIOS DATA Area.
00500-00xxx DOS Area - Тут сидит злобный DOS.
00xxx-9FFFF User RAM - Память для пользовательских программ. (Не более 638Кб).
9FC00-9FFFF Расширение BIOS DATA Area для PS/2 мыши.
Верхняя память - UMA(384Кб)
A0000-BFFFF Video RAM - Видеопамять, 128Кб. полностью практически не используется.
С0000-DFFFF Adapter ROM или RAM - для устройств со своими модулями BIOS и специальная
область ОЗУ(?).
E0000-EFFFF свободная область, иногда System BIOS.
F0000-FFFFF System BIOS, 128Кб ROM(или flash ROM) на системной плате.
В XT используются только FE000-FFFFF.
Вот и весь первый мегабайт. Все что выше должно быть либо XMS либо EMS - памятью(под DOS само-собой разумеется) или вообще не быть.
Александр


8. Подскажите каким образом можно вывести на экран число из регистра или значение переменной. Пробовал выводить функцией 09h 21-го прерывания - выводится какая-то чепуха, а хотелось бы увидеть в более понятном виде, типа шестнадцатиричном. С выводом строк проблем нет, а вот как вывести число - непонятно.
Конечно ты увидел аброкадабру, потому что этой функцией ты выводишь СИМВОЛ, с соответствующим кодом, а не число. Вообще-то я не жадный -так что держи функцию. Хоть сам разберешься. После того как получишь СТРОКУ - ты сам знаешь, что делать


HexWord proc
 ;AX - нужное число
 ;DS:SI - куда писать результат
 push cx
 push ax
 and ax,0F000h
 mov cl,12
 shr ax,cl
 call hexasc
 pop ax
 push ax
 and ax,0F00h
 mov cl,8
 shr ax,cl
 inc si
 call hexasc
 pop ax
 push ax
 and ax,0F0h
 mov cl,4
 shr ax,cl
 inc si
 call hexasc
 pop ax
 push ax
 and ax,0Fh
 inc si
 call hexasc
 pop ax
 pop cx
 ret
 HexWord proc

 hexasc proc
  push BX
  mov BX, offset tblhex
  xlat
  mov [SI],AL
  pop BX
  ret
 tblhex db '0123456789ABCDEF'
 hexasc endp

 Александр  

9. Подскажите, пожалуйста, где хранится серийный номер винчестера. К чему лучше всего привязывать программу для защиты от записи на другие РС ?
Серийный номер винчестера хранится в Boot Sector'е, но читать его оттуда напрямую я не рекомендую. Есть более приятный способ: У сервиса прерывания 21h есть функция 69h - get/set disk serial number Вот как надо загружать регистры пр ииспользовании этой ф-ии:
AH=69h (естественно)
AL=0, если читаем серийный номер
AL=1, если пишем серийный номер
BL ->содержит диск, у которого берем или на который пишем сер. номер диски обозначаются так:
BL=0 - текущий диск
BL=1 - drive A
bl=2 - drive B
bl=3 - drive C
ну и так далее
DS:DX = адрес структуры, куда функция вернет/возьмет информацию
Формат структуры:
+00h word уровень информации (установите равным нулю)
+02h double word серийный номер диска
+06h 11 bytes метка тома или "NO NAME ",если нету
+11h 8 bytes файловая система - "FAT12","FAT16","FAT32"
Возврашает:
CF=0 - успех
CF=1,ошибка, AX=код ошибки.
Данная функция недокументирванна.
Я думаю, что привязываться к серийному номеру вполне разумно :)
Евгений


10. Подскажите, можно ли отлаживать программу в TurboDebugere, которая вызывается функцией 4B00 INT 21h. У меня не получается. Компьютер виснет при попытке пошаговой отладки процедуры прерывания.
П
рограмму которая вызывается можно. а вот процедуру прерывания можно, но, как вы это уже заметили, возможно все будет виснуть. просто не всегда можно остановить выполнение очередной команды процедуры прерывания, да еще что-то свое выполнить (т.е. то, что делает отладчик: сделать дамп памяти, показать все на экран и т.п.). это из-за того, что в процедурах прерываний используется самый низкоуровневый доступ, т.е. порты ввода/вывода, и поэтому послав на как-то порт команду, возможно мы должны сразу принять ответ, отладчик об этом не заботится. можете попробовать еще отладчик debug.exe, но скорее всего это тоже не поможет. если вам очень интересно/надо, то лучше сделайте дамп памяти того участка, который вас интересует и дизассеблируйте его.
BELTSY

 

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

Составитель: Софронов П.Н. (Lonely L)
Все права сохранены
19.11.2001
Харьков 2001
© Софронов П.Н. 2001

Тематические ссылки
Ваша ссылка Ваша ссылка

Обмен кнопками, ведение статистики, реклама.