Используя регистр RDTSC необходимо в программном варианте реализовать следующее: Всё довольно просто - суть задачи такова: если программу трассируют под отладчиком, то естественно количество тактов увеличивается. Поэтому необходимо поймать время которое без отладчика, сравниваем его с текущим и если больше, значит отладчик есть . То есть сравнение времени до попадания отладчика в работу системы, и текущего времени( допустим отладчик уже в системе). + реализовать необходимо так, чтобы шла своеобразная проверка - если есть отладчик в системе, писалось бы сообщение , нападобие * меня атакуют* , если же все тихо - то * система работает нормально*, или что-то в этом роде. В теории как будет все выглядеть мне понятно, а код никак не получается сваять. Вот и ищу помощи извне. Всё еще рассмотрю платный вариант работы под заказ.( имеется некая модель операционной системы и идеальным будет вариант вклинивания туда этого момента).
Пример, чтобы вы поняли как работать с RDTSC и сделать простейшее профилирование кусочка кода. Пример консольный для DOS. [test4]
Код:
masm model small .stack 256 .486 bin_dec_fpu macro string_bin_qword:REQ, string_pack:REQ, adr_string_pack:REQ, len_string_pack:REQ, adr_string:REQ, len_string:REQ local cycl ;---------------------------------------------------------------------------- ;макрокоманда вывода на консоль десятичного числа: ;на входе: ;string_bin_qword - адрес 64-битной ячейки (описанной dt) с преобразуемым двоичным целым числом ;string_pack - адрес 80-битной ячейки (описанной dt), в которую сохраняется упакованное 10-е значение ;adr_string_pack - ячейка с адресом string_pack (описанной dd) ;len_string_pack - длина string_pack ;adr_string - ячейка с адресом string (описанной dd). В string помещаются символы десятичных цифр для вывода. ;len_string - размер string (18 байт) ;---------------------------------------------------------------------------- ;---------преобразуем bin->dec --------------------------------------------- finit fild string_bin_qword ;заносим в сопроцессор двоичное целое число fbstp string_pack ;извлекаем упакованное десятичное ;---------распакуем---------------------------------------------------------- lds si,adr_string_pack add si,len_string_pack-2 ;на конец string_pack (18 упак. дес. цифр) les di,adr_string mov cx,9 ;9 пар упакованных десятичных цифр xor ax,ax cycl: xor ax,ax std ;string_pack обрабатываем с конца lodsb ;в аl очередные 2 упакованные десятичные цифры ;распаковываем - ah=младшая, al=старшая shl ax,4 rol al,4 or ax,3030h ;преобразуем в символьное представление xchg ah,al ;ah=младшая, al=старшая cld ;в string записываем с начала stosw loop cycl ;---------выводим на консоль---------------------------------------------------------- mov bx,1 ;стандартный дескриптор - экран mov cx,len_string lds dx,adr_string ;формируем указатель на строку string mov ah,40h ;номер функции DOS int 21h ;выводим jc exit ;переход в случае ошибки endm profiler_in macro val_1:REQ ;------------------------------------------------------------------------------------- ;val_1 - ячейка памяти 64 бита (2ґ32) для сохранения момента начала профилирования ("грязного") ;------------------------------------------------------------------------------------- pushad ;сохранение всех регистров общего назначения в стеке db 0fh,31h ;RDTSC mov val_1+4,edx mov val_1,eax popad ;восстановление всех регистров общего назначения из стека endm profiler_out macro val_1:REQ, val_2:REQ ;------------------------------------------------------------------------------------- ;val_1 - ячейка памяти 64 бита (2ґ32), в которой при входе в макрос сохранен момент начала профилирования командой profiler_in. Далее в макросе эта ячейка содержит результат профилирования - число тактов процессора ;val_2 -ячейка памяти 64 бита (2ґ32), в которой сохраняется момент ("грязный") окончания профилирования ;------------------------------------------------------------------------------------- pushad ;сохранение всех регистров общего назначения в стеке db 0fh,31h ;RDTSC - окончание профилирования mov val_2+4,edx mov val_2,eax ;профилируем pushad и popad с учетом двух shrd pushad ;2 popad ;2 db 0fh,31h ;RDTSC ;------------------------------------------------------------------------------------- ;теперь необходимо получить чистое время профилирования, для чего результат необходимо скорректировать (уменьшить) на количество тактов процессора, потребное для выполнения пар команд pushad\popad и mov ;------------------------------------------------------------------------------------- sub eax, val_2 jnc $+4 ;учет заема из старшего разряда dec edx sub edx, val_2+4 ; в edx:eax кол-ва тактов для выполнения 2-х команд pushad\popad и 2-х shrd mov eax,val_1 sub val_2,eax mov eax,val_1+4 jnc $+7 ;учет заема из старшего разряда при выполнении предыдущего вычитания dec val_2+4 sub val_2+4,eax ;в val_2:val_2+4 - чистое количество тактов процессора для выполнения профилируемого участка popad ;восстановление всех регистров общего назначения из стека ;выводим bin_dec_fpu val_2_q, string_pack, adr_string_pack, len_string_pack, adr_string, len_string endm .data val_2 label dword val_2_q dq 0 ; val_1 label dword dq 0 ; ;в string_pack исходное значение из val_2_q в упакованном десятичном формате string_pack dt 0 len_string_pack=$-string_pack adr_string_pack dd string_pack string db 18 dup (0) ;максимальный результат состоит из 18 десятичных цифр len_string=$-string adr_string dd string .code main: mov ax,@data ;адрес сегмента данных в регистр ax mov ds,ax ;ax в ds ;профилируем выполнение команд работы со стеком profiler_in val_1 push eax pop eax profiler_out val_1, val_2 exit: ;выход из программы mov ax,4c00h ;пересылка 4c00h в регистр ax int 21h ;вызов прерывания с номером 21h end main ;конец программы с точкой входа main
[/test4]
PS: пример взят из книги Assembler: Практикум (+дискета) 1 изд. Изд. Питер, автор В. Юров
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения