Статьи по Assembler


         

Если все эти условия выполняются,


Если все эти условия выполняются, BIOS считает, что перед ним ПЗУ, оформленное по правилам, и совершает последний шаг - передает управление на смещение +3 (отсчет начинается с нуля) относительно найденного сегмента. Следовательно, там должна располагаться первая выполняемая команда нашей программы. Обычно это команда jmp. Совершив все необходимое, наша программа должна вернуть управление обратно в BIOS с тем, чтобы та продолжила поиск аналогичных ПЗУ. Следовательно, наша программа должна заканчиваться командой retf.

Для того, чтобы было более ясно, о чем шла речь, ниже приводятся фрагменты кода BIOS, реализующие необходимые проверки и передачу управления.

;#################################################################### ; Поиск дополнительной ROM в области памяти C800->E000 в блоках по 2K ; Модуль ROM должен иметь подпись '55AA' в первых двух байтах и ; индикатор размера ((размер в байтах)/512) в третьем байте. ; Исполняемый код должен начинаться с четвертого байта. ;//////////////////////////////////////////////////////////////////// ROM_SCAN: ;начало фрагмента кода BIOS STI ;разрешить прерывания MOV DX,0C800H ;начало сканирования ROM_SCAN2: MOV DS,DX ;ds - сегмент очередного ROM-модуля SUB BX,BX ;bx - указатель в ROM-модуле MOV AX,[BX] ;взять первое слово в модуле CMP AX,0AA55H ;подпись найдена? JNZ NEXT_ROM ; нет - перейти к следующему базовому адресу ROM CALL ROM_CHECK ; да - проверить контрольную сумму JMP ARE_WE_DONE ;перейти к проверке конца области дополнительной ROM NEXT_ROM: ;следующий ROM-модуль ADD DX,0080H ; позиционировать новый модуль через 2K байт (как сегмент) ARE_WE_DONE: ;проверка конца области дополнительной ROM CMP DX,0E000H ;достигнут адрес E0000? JL ROM_SCAN2 ; нет - перейти к новой проверке подписи ;//////////////////////////////////////////////////////////////////// ;Последующий код не относится к теме статьи ;... ;... ;... ;#################################################################### ;Эта подпрограмма вычисляет контрольную сумму дополнительных ;модулей ROM и, если она верна, вызывает программу из модуля ;(При входе регистр ES указывает на сегмент данных BIOS) ;//////////////////////////////////////////////////////////////////// ROM_CHECK PROC NEAR ;вычислить число байт для сканирования SUB AH,AH ;ax - индикатор размера модуля MOV AL,[BX+2] MOV CL,09H ;ax=ax*512 SHL AX,CL MOV CX,AX ;cx - счетчик байт для сканирования ;вычислить указатель на следующий модуль и поместить его в dx PUSH CX MOV CX,4 SHR AX,CL ADD DX,AX POP CX ;вычислить контрольную сумму модуля CALL ROM_CHECKSUM JZ ROM_CHECK_1 CALL ROM_ERR ;контрольная сумма на совпала! JMP ROM_CHECK_END ;---- Вызов программы, находящейся в ПЗУ ---------------- ROM_CHECK_1: PUSH DX ;сохранить текущее значение указателя MOV ES:IO_ROM_INIT,0003H ;подготовить смещение MOV ES:IO_ROM_SEG,DS ;подготовить сегмент CALL DWORD PTR ES:IO_ROM_INIT ;вызвать программу POP DX ;восстановить указатель ;---------------------------------------------------------- ROM_CHECK_END: RET ;завершить работу ROM_CHECK ENDP ;=========================================== ;Подпрограмма вычисления контрольной суммы ;=========================================== ROM_CHECKSUM PROC NEAR XOR AL,AL NEXT_BYTE: ADD AL,[BX] INC BX LOOP NEXT_BYTE OR AL,AL ;сумма равна нулю? RET ROM_CHECKSUM ENDP


Содержание  Назад  Вперед