|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
02.12.2008, 18:36 | #1 |
Новичок
Джуниор
Регистрация: 02.12.2008
Сообщений: 2
|
Нужно закоментировать
Поскольку нам ассемблер не препдовали я в нем почти 0. Сказли на курсовую закоментируюте прогу и раскажите. Вобшем надо закоменитровать программу буквально каждую строчку.
use16 org 100h ;Программа типа COM jmp Begin ;********************************** *************** ********* ;Вывод ASCII строки ;********************************** *************** ********* outstring: push ax push si pushf .OutStringLoop: lodsb or al,al jz .OutStringExit mov ah,0eh int 10h jmp .OutStringLoop .OutStringExit: popf pop si pop ax ret ;********************************** *************** ********** ;Вывод десятичного числа ;********************************** *************** ********** outdec: pushad pushf mov ebx,1000000000 xor cx,cx .loop: xor edx,edx div ebx or cl,cl jnz .out or al,al jz .noout mov cl,1 .out: add al,'0' mov ah,0eh int 10h .noout: push edx mov eax,ebx xor edx,edx mov ebx,10 div ebx mov ebx,eax pop eax test ebx,ebx jnz .loop popf popad ret ;********************************** *************** ********** ;Процедура ожидания очередного изменения значения таймера ;********************************** *************** ********** WaitTimerStateChange: mov eax,[Time] .wtscl: cmp eax,[es:046Ch] je .wtscl mov eax,[es:046Ch] mov [Time],eax ret ;********************************** *************** ********* ;Данные ;********************************** *************** ********** Cpufreq dd 0 Time dd 0 Mes1 db 'CPU frequency: ',0 Mes2 db ' MHz, press any key',0 TimeCounter rd 17 DeltaT rd 16 AverageTime dd 0 ;********************************** *************** ********** ;Код ;********************************** *************** ************ Begin: push cs pop ds mov ax,0 mov es,ax mov eax,[es:046Ch] mov [Time],eax call WaitTimerStateChange mov bx,17 mov di,TimeCounter @@t0: call WaitTimerStateChange rdtsc mov [di],eax add di,4 dec bx jnz @@t0 mov bx,16 mov di,TimeCounter mov si,DeltaT mov edx,0 @@t1: mov eax,[di+4] sub eax,[di] mov [si],eax add edx,eax add di,4 add si,4 dec bx jnz @@t1 shr edx,4 mov [AverageTime],edx mov eax,[AverageTime] mov edx,1193180 mul edx shrd eax,edx,16 xor edx,edx mov ebx,1000000 div ebx mov bx,cs mov es,bx mov [Cpufreq],eax mov si,Mes1 call outstring call outdec mov si,Mes2 call outstring xor ax,ax int 16h mov ax,4C01h int 21h end Begin Все что мне известно про программу Что она показывает частоту процессора |
02.12.2008, 18:36 | #2 |
Новичок
Джуниор
Регистрация: 02.12.2008
Сообщений: 2
|
вот еше
Используемые переменные: Cpufreq – значение частоты процессора; Time – значение системного таймера; TimeCounter – массив для сохранения значений отсчетов счетчика тактов в моменты срабатывания системного таймера; DeltaT – разность между соседними замерами; AverageTime – среднее значение длительности интервала. В начале файла программы следует описание используемых далее процедур. Это процедура вывода ASCII-строки на экран – Outstring, процедура вывода десятичного числа – Outdec и процедура ожидания очередного изменения значения таймера – WaitTimerStateChange. Опишем данные процедуры подробнее. Процедура Outstring: выводит строку, находящуюся по адресу DS:SI, на экран, используя функцию BIOS 0Eh – вывод символа в режиме телетайпа. В начале функции идет сохранение в стеке регистров AX, SI и регистра флагов. Далее следует цикл вывода символов на экран: используется команда LODSB – загрузка байта из DS:SI в регистр AL и функция 0Eh прерывания 10h. В конце функции следует восстановление состояния сохраненных регистров. Процедура Outdec: выводит преобразованное в строку число, находящееся в регистре EAX, используя функцию BIOS 0Eh – вывод символа в режиме телетайпа. В начале функции идет сохранение в стеке всех регистров общего назначения(PUSHAD) и регистра флагов(PUSHF). Далее следует несложный для понимания цикл преобразования числа в строку. Сначала в регистр EBX заносится какое-нибудь большое число – в данном случае это 1000000000, на которое будет делиться необходимое нам число. Пока наше число меньше чем находящееся в EBX в регистре AL будет находится ноль и на печать выводится ничего не будет. При этом число, находящееся в регистре EBX будет постепенно уменьшаться путем деления на 10. Когда же наше число станет меньше или будет равно числу, находящемуся в EBX, в регистр AL занесется результат деления этих двух чисел. Далее к числу находящемуся в AL прибавляется код символа 0 (ADD AL, ‘0’), что эквивалентно прибавлению числа 30h, т.е. в регистре AL мы получили ASCII-код символа, который необходимо вывести на печать. А далее уже знакомой функцией 0Eh прерывания 10h мы собственно и выводим данный символ на экран. В конце функции следует восстановление состояния сохраненных регистров. Процедура WaitTimerStateChange: состоит из цикла, который выполняется до тех пор пока не изменится текущее значение таймера. Определение того, что таймер изменил свое значение достигается путем считывания состояния 32-битного счетчика, который располагается в памяти по адресу 0000h:046Ch. BIOS автоматически отслеживает каждый отсчет системного таймера с помощью своего обработчика прерывания IRQ0 (INT 8h) и увеличивает значение счетчика на 1. Далее в программе следует описание переменных, после которого располагается основная программа. В начале в переменной Time сохраняется текущее значение счетчика тактов. Далее вызывается процедура WaitTimerStateChange, которая возвращает увеличенное на единицу значение счетчика тактов, сохраненного в переменной Time. После этого в цикле вычисляются начальные моменты для 17 интервалов. При этом в цикле используется такая команда как RDTSC (используется в процессорах начиная с Pentium). Ее назначение – это помещение в регистровую пару EDX:EAX текущего значения счетчика тактов процессора – 64-битного машинно-специфичного регистра TSC, значение которого увеличивается на 1 такт процессора с момента его последней перезагрузки. Далее вычисляется длительность 16 интервалов в тактах. Для этого организуется цикл в котором из значения счетчика тактов в момент времени t+1 вычитается значение счетчика в момент времени t. В результате в регистре EDX мы получили длительность 16 интервалов в тактах. Теперь для того чтобы получить среднюю длительность одного интервала необходимо разделить значение, находящееся в регистре EDX, на 16 (SHR EDX, 4). Полученное значение сохраняем в переменной AverageTime. Далее среднее значение длительности одного интервала необходимо умножить на частоту генератора системного таймера равную 1193180. Полученное значение сохраняем в регистре EAX. После этого операцией сдвига повышенной точности вправо делим значение в EAX на коэффициент пересчета системного таймера равный 65536 (SHRD EAX, EDX, 16). Мы получили значение частоты процессора в Гц. Теперь осталось только перевести его в МГц. Несложно догадаться, что для этого достаточно разделить значение в EAX на 1000000. Полученное значение сохраняем в переменной Cpufreq. В конце программы следует вывод значения частоты процессора на экран функцией Outdec. |
03.12.2008, 14:28 | #3 |
Форумчанин
Регистрация: 22.11.2007
Сообщений: 664
|
Не знаю в таком ли виде.
;********************************** *************** ********** ;Код ;********************************** *************** ************ Begin: ;Начало программы push cs ;Сохранение в стеке содержимого регистра cs pop ds ;Извлечение из стека содержимого в регистр ds mov ax,0 ;Загрузка в регистр ах нуля mov es,ax ;Загрузка содержимого ах в регистр es
Неприятности приходят и уходят, а жизнь продолжается!
|
03.12.2008, 14:44 | #4 |
Форумчанин
Регистрация: 22.11.2007
Сообщений: 664
|
У Вас ведь все описано.
;********************************** *************** ********* ;Вывод ASCII строки ;********************************** *************** ********* ;Процедура оutstring: выводит строку, находящуюся по адресу DS:SI, на экран, используя функцию BIOS 0Eh – вывод символа в режиме телетайпа. outstring: ; Имя процедуры push ax ; Сохранение в стеке ах push si ; Сохранение в стеке si pushf ; Сохранение в стеке регистра флагов .OutStringLoop: ;цикл вывода символов на экран lodsb or al,al ;(Логическое или ) Проверка регистра al на нуль jz .OutStringExit ; Переход на метку .OutStringExit , если содержимое ; al==0, если нет то следующая операция mov ah,0eh ;Загрузка в регистр ah функции 0eh BIOS int 10h ; Вывод символа на экран по прерыванию 10h jmp .OutStringLoop ; Переход на продолжение анализа выведенных ;символов .OutStringExit: ; Выход из процедуры, если вывелены все символы popf ; Восстановление из стека Рг флагов pop si ; Восстановление из стека Рг si pop ax ; Восстановление из стека Рг ax ret ; Возврат из процедуры
Неприятности приходят и уходят, а жизнь продолжается!
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Очень нужно | Nurbo | Свободное общение | 2 | 03.09.2007 14:41 |
Нужно влезть. | Xandr | Общие вопросы Delphi | 2 | 26.08.2007 22:03 |
Нужно разработать ПО | atreus | Фриланс | 4 | 29.05.2007 09:37 |
зачем вообще изучать assembler? | rpy3uH | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 7 | 31.10.2006 20:36 |