Dos7book
.pdf
|
Глава 9: |
Примеры композиции исполняемых файлов |
||
xor |
CH,70 |
; 14B |
Инвертируем |
áèòû 0C, 0D, 0E |
push |
CX |
; 14E |
Перешлем измененные биты |
|
popf |
|
; 14F |
через |
стек в регистр |
pushf |
|
; 150 |
флагов, а потом снова |
|
pop |
AX |
; 151 |
через |
ñòåê â AX |
popf |
|
; 152 |
Вернем исходные состояния |
|
xor |
AH,CH |
; 153 |
Установим несовпавшие биты |
|
test |
AH,40 |
; 155 |
Наш процессор 16-битовый? |
|
jz |
0162 |
;*158 |
Если нет, проверим защиту |
|
mov |
AL,04 |
; 15A |
Åñëè äà, òî |
переход на |
mov |
DX,024F |
;*15C |
выход |
с индикацией |
jmp |
020A |
;*15F |
сообщения 024F |
|
test |
AH,30 |
;=162 |
Установлен защищенный режим? |
|
jz |
016F |
;*165 |
Если нет, следуем дальше |
|
mov |
AL,08 |
; 167 |
Åñëè äà, òî |
переход на |
mov |
DX,0271 |
;*169 |
выход |
с индикацией |
jmp |
020A |
;*16C |
сообщения 0271 |
|
|
;********* Секция 4: подготовка адресной линии A20 |
;16F - адрес перехода со строки 165
;18B - адрес перехода со строки 176
mov |
AX,4300 |
;=16F |
Проверим, установлен ли |
int |
2F |
; 172 |
драйвер Himem.sys |
cmp |
AL,80 |
; 174 |
Если нет, перейдем и |
jnz |
018B |
;*176 |
обратимся к A20 напрямую |
mov |
AX,4310 |
; 178 |
Если да, запросим адрес |
int |
2F |
; 17B |
вызова функций Himem.sys |
mov |
[0126],BX |
;*17D |
Сохраним в памяти |
mov |
[0128],ES |
;*181 |
полученный адрес вызова |
mov |
AH,05 |
; 185 |
Вызовем функцию активизации |
call far |
[0126] |
;*187 |
адресной линии A20 |
call |
021C |
;=18B |
Проверим A20 и перейдем, |
jnz |
01A7 |
;*18E |
если линия A20 активна |
mov word ptr |
[0128],0001 |
;*190 |
Метка: линия A20 не активна |
mov |
AL,FF |
; 196 |
Запросим активизацию линии |
call |
022F |
;*198 |
A20 у подпрограммы 022F |
call |
021C |
;*19B |
Проверим A20 и перейдем, |
jnz |
01A7 |
;*19E |
если линия A20 активна |
mov |
AL,02 |
; 1A0 |
Если линия A20 не активна, |
mov |
DX,029C |
;*1A2 |
то переход на выход с |
jmp |
020A |
;*1A5 |
индикацией сообщения 029C |
;*********** Секция 5: подготовка таблицы GDT |
|||
; 1A7 - адрес перехода со строк 18E, 19E |
|||
|
|
;=1A7 |
Префикс 32-битового операнда |
db |
66 |
|
|
|
|
|
– 553 – |
Глава 9: |
Примеры композиции исполняемых файлов |
|||
xor |
AX,AX |
|
; 1A8 |
Обнулим регистр EAX |
mov |
AX,CS |
|
; 1AA |
Запишем CS в AX |
mov |
CL,04 |
|
; 1AC |
Сдвиг на 4 бита превратит |
db |
66 |
|
|
|
shl |
AX,CL |
|
; 1AF |
сегментный адрес в линейный |
db |
66 |
|
|
|
add |
[012C],AX |
;*1B2 |
Вычислим линейный адрес GDT |
|
;******** Секция 6: подготовка селектора и прерываний |
||||
; 1C3 - адрес перехода со строки 1BE |
||||
mov |
CX,0008 |
; 1B6 |
0008 - 4-Гбайтный селектор |
|
cmp byte ptr |
[005E],46 |
; 1B9 |
Указан ли параметр "F" ? |
|
jz |
01C3 |
|
;*1BE |
Если да, оставим CX=0008 |
mov |
CX,0010 |
; 1C0 |
Если нет, пусть CX=0010 |
|
cli |
|
|
;=1C3 |
Запретим прерывания |
mov |
AL,80 |
|
; 1C4 |
Отсылка байта 80h |
out |
70,AL |
|
; 1C6 |
â ïîðò 70h |
in |
AL,71 |
|
; 1C8 |
запретит NMI |
;********** Секция 7: переходы к PM и обратно |
||||
|
|
|
; 1CA |
= Lgdt fword ptr [012A] |
db |
0F 01 |
16 2A 01 |
|
|
|
|
|
; 1CF |
= mov EAX,CR0 |
db |
0F 20 |
C0 |
|
|
or |
AL,01 |
|
; 1D2 |
Установим бит защищенного |
|
|
|
; 1D4 |
режима (= mov CR0,EAX) |
db |
0F 22 |
C0 |
|
|
|
|
|
; 1D7 |
Загрузим GS (=mov GS,CX) |
db |
8E E9 |
|
|
|
and |
AL,FE |
|
; 1D9 |
Сбросим бит защищенного |
|
|
|
; 1DB |
режима (= mov CR0,EAX) |
db |
0F 22 |
C0 |
|
|
;********** Секция 8: возврат к прежнему состоянию |
||||
; 1F5 - адрес перехода со строки 1EC |
||||
mov |
AL,7F |
|
; 1DE |
Посылка байта 7Fh |
out |
70,AL |
|
; 1E0 |
â ïîðò 70h |
in |
AL,71 |
|
; 1E2 |
снова разрешает NMI |
sti |
|
|
; 1E4 |
Разрешим прерывания |
cmp word ptr |
[0128],0001 |
;*1E5 |
Посмотрим метку линии A20 |
|
jb |
01FB |
|
;*1EA |
Если 0000, ничего не делаем |
ja |
01F5 |
|
;*1EC |
Если >, обратимся к Himem |
mov |
AL,FD |
|
; 1EE |
Если =0001, восстановим |
call |
022F |
|
;*1F0 |
состояние линии A20 с |
jmp |
01FB |
|
;*1F3 |
помощью подпрограммы 022F |
mov |
AH,06 |
|
;=1F5 |
Вызов функции драйвера Himem |
call far |
[0126] |
|
;*1F7 |
для перекрытия линии A20 |
|
|
|
|
– 554 – |
Глава 9: Примеры композиции исполняемых файлов
;********** Секция 9: вывод сообщения и возврат в DOS
;1FB - адрес перехода со строк 1EA, 1F3
;208 - адрес перехода со строки 203
;20A - адрес перехода со строк 123, 15F, 16C, 1A5
mov |
DX,02E9 |
;=1FB |
Сообщение "Предел поставлен" |
cmp byte ptr |
[005E],46 |
; 1FE |
Указан ли параметр "F" ? |
jnz |
0208 |
;*203 |
Если да, то заменить на |
mov |
DX,02B9 |
; 205 |
сообщение "Предел снят" |
mov |
AL,00 |
;=208 |
Нулевой уровень ошибки |
push |
AX |
;=20A |
Точка входа для выведения |
mov |
AH,40 |
; 20B |
сообщений на экран |
mov |
BX,DX |
; 20D |
Считаем в регистр CX |
mov |
CX,[BX-02] |
; 20F |
число выводимых знаков |
mov |
BX,0001 |
; 212 |
0001 = ссылка на STDOUT |
int |
21 |
; 215 |
Вывод сообщения в STDOUT |
pop |
AX |
; 217 |
Вернем уровень ошибки в AL |
mov |
AH,4C |
; 218 |
Вызов функции |
int |
21 |
; 21A |
завершения программы |
;******** Секция 10: подпрограмма проверки линии A20 |
|||
; 21C - адрес вызова из строк 18B, 19B |
|||
push |
DS |
;=21C |
Сохраним состояние DS |
xor |
SI,SI |
; 21D |
Обнулим регистр SI |
mov |
DS,SI |
; 21F |
Теперь DS:SI=0000:0000 |
mov |
DI,F0F1 |
; 221 |
Установим ES:DI=F0F1:F0F0 |
mov |
ES,DI |
; 224 |
чтобы получился адрес |
dec |
DI |
; 226 |
F0F10h + F0F0h = 100000h |
cld |
|
; 227 |
Зададим счет на увеличение |
mov |
CX,0010 |
; 228 |
Зададим предел 16 байт и |
repz |
|
; 22B |
повторение до несовпадения |
cmpsb |
|
; 22C |
Адреса "свернуты" ? |
pop |
DS |
; 22D |
Возврат результата через |
ret |
|
; 22E |
состояние флага ZF |
;****** Секция 11: подпрограмма управления линией A20 |
|||
; 22F - адрес вызова из строк 198, 1F0 |
|||
push |
AX |
;=22F |
Сохраним команду в стеке |
call |
0241 |
;*230 |
Ждем готовности контроллера |
mov |
AL,D1 |
; 233 |
D1 - первый байт команды, |
out |
64,AL |
; 235 |
посылаемый в порт 64h |
call |
0241 |
;*237 |
Ждем готовности контроллера |
pop |
AX |
; 23A |
Вернем команду в AX |
out |
60,AL |
; 23B |
и пошлем ее в порт 60h |
call |
0241 |
;*23D |
Подождем срабатывания |
ret |
|
; 240 |
контроллера и вернемся |
;******** Секция 12: подпрограмма ожидания готовности
– 555 –
Глава 9: Примеры композиции исполняемых файлов
;241 - адрес вызова из строк 230, 237, 23D
;245 - адрес цикла из строки 249
push |
CX |
|
|
;=241 Сохраним CX в стеке |
mov |
CX,FFFF |
; 242 Запишем в CX число циклов |
||
in |
AL,64 |
|
;=245 Считаем байт из порта 64h |
|
test |
AL,02 |
|
; 247 Проверим состояние 2-го бита |
|
loopnz |
0245 |
|
;*249 Повторим, если порт занят |
|
pop |
CX |
|
|
; 24B Восстановим состояние CX |
ret |
|
|
|
; 24C Возврат из подпрограммы |
|
;*********** Секция 13: сообщения |
|||
db |
20 |
00 |
|
|
|
; 24F - 1-е сообщение, вызываемое из строки 15C |
|||
db |
0D |
0A |
09 |
"16-bit processor" |
db |
20 |
"can" |
27 "t suit" 0D 0A |
|
db |
29 |
00 |
|
|
|
; 271 - 2-е сообщение, вызываемое из строки 169 |
|||
db |
0D |
0A |
09 |
"GS_limit can" 27 "t run" |
db |
20 |
"in protected mode" 0D 0A |
||
db |
1B |
00 |
|
|
|
; 29C - 3-е сообщение, вызываемое из строки 1A2 |
|||
db |
0D |
0A |
09 |
"Line A20 control error" 0D 0A |
db |
2E |
00 |
|
|
|
; 2B9 - 4-е сообщение, вызываемое из строки 205 |
|||
db |
0D |
0A |
09 |
"GS segment limit" |
db |
20 |
"protection is turned OFF" 0D 0A |
||
db |
2C |
00 |
|
|
|
; 2E9 - 5-е сообщение, вызываемое из строки 1FB |
|||
db |
0D |
0A |
09 |
"GS segment limit" |
db |
20 |
"protection is restored" 0D 0A |
||
db |
7F |
00 |
|
|
|
; 317 - 6-е сообщение, вызываемое из строки 11E |
|||
db |
0D |
0A |
"GS_limit.com removes the GS segment" |
|
db |
20 |
"limit protection or can restore it back" |
||
db |
0D |
0A |
"Usage examples:" 0A 0D 09 09 "GS_lim" |
|
db |
"it off" |
0A 0D 09 09 "GS_limit on" 0D 0A |
||
|
; 396 Конец программы |
n GS_limit.com rBX
0000 rCX 0296 w
q
– 556 –