Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: программирование на языке Assembler


Информационный Канал Subscribe.Ru

RusFAQ.ru: программирование на языке Assembler

Выпуск № 597
от 23.07.2003, 09:30

Администратор:
Имя: Калашников О.А.
URL: Информационный ресурс
ICQ: 68951340
Россия, Москва
О рассылке:
Задано вопросов: 3764
Отправлено ответов: 11034
Активность: 293.1 %
[Задать вопрос >>][Регистрация эксперта >>]
[Поиск в базе][Обсудить на форуме]


 Список экспертов, ответы которых опубликованы в данном выпуске

Евгений Иванов
Статус: Опытный
Общий рейтинг: 139.18
URL: Super Assembler Software
[Подробней >>]
Дмитрий
Статус: Профессиональный
Общий рейтинг: 127.4
[Подробней >>]
Ayl
Статус: Профессиональный
Общий рейтинг: 118.25
[Подробней >>]
 
Broken Sword
Статус: Профессиональный
Общий рейтинг: 121.55
URL: мой сайт
[Подробней >>]
Hangatyr
Статус: Опытный
Общий рейтинг: 115.07
[Подробней >>]
Bob Johnson
Статус: Профессиональный
Общий рейтинг: 152.29
URL: Программирование
[Подробней >>]
 
Gibbel
Статус: Профессиональный
Общий рейтинг: 107.67
URL: Savage Metal Club - жизнь в стиле рок-н-ролл
Телефон: +7 901 710 3146
[Подробней >>]
St
Статус: Профессиональный
Общий рейтинг: 107.27
[Подробней >>]
Tigran K. Kalaidjian
Статус: Профессиональный
Общий рейтинг: 122.38
URL: Методы оптимизации работы ПК
[Подробней >>]
 
Теоретик
Статус: Доверительный
Общий рейтинг: 116.81
[Подробней >>]


 Краткий перечень вопросов

Вопрос № 3723. Добрый день, уважаемые эксперты! У меня тут возникла проблемка с командной строкой... Не могл... (ответов: 3)
Вопрос № 3724. Здравствуйте, уважаемые эксперты! Расскажите, пожалуйста, как грамотно сесть на Ring0 под Win98SE, п... (ответов: 4)
Вопрос № 3725. Как из Си вызывать функцию, написанную на ассаблере. К примеру, из Си передаются два числа, ассембле... (ответов: 5)
Вопрос № 3727. Добрый день эксперты!!! Извините но Вы все заяб???ли. Че вы прицепились ко всяким резинкам(hubba) и ... (ответов: 2)
Вопрос № 3728. Здравствуйте, уважаемые эксперты. Вопрос касается быстрых алгоритмов и потому, кроме вас не знаю куд... (ответов: 2)
Вопрос № 3729. хайте;), ув. товарищи эксперты! возращаюсь к вопросу №3660 я, наверное, не так выразился,скорее всег... (ответов: 3)
Вопрос № 3730. хайте, эксперты! определился с компилятором, это будет fasm 1.44. инета небыло, всвязи с чем вознило... (ответов: 6)

Вопросов: 7, ответов: 25


 Вопрос № 3723

Добрый день, уважаемые эксперты!
У меня тут возникла проблемка с командной строкой... Не могли бы Вы дать пример как ее разбирать, чтобы потом подставить для открытия файла(ов) под ДОС (если не затруднит, то и для выни). А то у меня пишет при компиляции: 1) используете 32 регистр (хотя там его в помине нет); 2) ошибка по ... адресу. За ранее всем спасибо.



Вопрос отправлен: 18.07.2003, 10:15
Отправитель: glaxo (glaxo@mail.ru)

[Следующий вопрос >>] [Список вопросов]

Отвечает Евгений Иванов

Здравствуйте, glaxo!
AdrCmdLine = 128 ;начало командной строки
cmdstr1:
mov si,AdrCmdLine
lodsb
or al,al
jz help
mov cl,al
sub ch,ch
push si cx ;увеличиваем регистр букв (делаем одинаковыми)
mov bx,ofs tabl_small_big
mov di,si
m101a:
lodsb
xlat
stosb
dec cx
jnz m101a
pop cx si
mov ah,79
mov di,ofs name1
call get_name
jc help
cmp [w name1],'?/'
jz help
mov di,ofs name2
push di
mov ah,79
call get_name
pop di
jc help
;--------- working
;ЌЌЌ GET_NAME ЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌ
;IN:AH=максим.размер буфера,куда переписывать данные командной строки.
;DS:DI=адрес буфера.
;DS:SI=адрес начала участка командной строки.
;CX=размер оставшейся части командной строки.
;OUT:CF=1-ошибка,код ошибки в AL(0-нет символов,1-переполнение буфера)
;CF=0-все хорошо.
;AH=число символов скопированных.
proc get_name ;=1g
push bx ax
xor bx,bx
jcxz m171g
m151g:
lodsb
cmp al,33
jnc m201g
loop m151g
m171g:
pop ax
mov al,0
exit_g_n2:
push ax
stc
jmp exit_g_n
m161g:
pop ax
mov al,1
jmp exit_g_n2
m201g:
dec si
inc ah
m251g:
lodsb
cmp al,33
jc m271g
dec ah
jz m161g
dec cx
stosb
inc bx
jmp m251g
m271g:
dec si
pop ax
mov ah,bl
push ax
clc
exit_g_n:
mov al,0
stosb
pop ax bx
ret
endp
tabl_small_big:
db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
db 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
db 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47
db 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63
db 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79
db 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95
db 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79
db 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127
db 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143
db 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159
db 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143
c_1 = 176
rept 3*16
db c_1
c_1 = c_1+1
endm
db 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159
db 240,240,242,243,244,245,246,247,248,249,250,251,252,253,254,255



Ответ отправлен: 18.07.2003, 13:35
Отправитель: Евгений Иванов


Отвечает Дмитрий

Доброе время суток, glaxo!
После запуска EXE-проги регистр ES указывает на начало переменных окружения программы (PSP). По смещению 080h в этой области данных находится сама командная строка, причем первый ее байт - длина этой командной строки. Вот и делай с ней что хочешь. Если нужно узнать адрес PSP где-нибудь в середине проги, когда значение ES уже затерто, можно использовать функцию DOS номер 62h. В bx вернется начало сегмента PSP.

Ответ отправлен: 22.07.2003, 11:15
Отправитель: Дмитрий


Отвечает Ayl

Добрый день, glaxo!
сначала побурчу... Если ссылаешься на ошибки компилятора, то приводи код программы. А иначе начинается гадание на кофейной гуще. И компилятор неплохо бы указывать - от этого тоже много зависит.
Теперь по существу.
Командная строка под ДОС. Начинается по адресу PSP:80h.
Занимает 127 байт плюс байт с длиной строки.
Первый байт строки (PSP:80h) содержит длину строки. Если длина не равна 0, то тогда PSP:81h содержит пробел, а с PSP:82h идет собственно строка. Длина строки считается с учетом первого пробела.
Строка завершается символом с кодом 0dh.
В приложении - пример открытия файла, имя которого задано в командной строке. Проверок на неправильный ввод нет. Вызывать программу нужно так:
open filename


Приложение:

Ответ отправлен: 18.07.2003, 10:52
Отправитель: Ayl


 Вопрос № 3724

Здравствуйте, уважаемые эксперты!
Расскажите, пожалуйста, как грамотно сесть на Ring0 под Win98SE, причем так, чтобы не вылезал BSOD.
Спасибо всем ответившим!



Вопрос отправлен: 18.07.2003, 10:39
Отправитель: Aram Markaryan

[Следующий вопрос >>] [Список вопросов]

Отвечает Евгений Иванов

Добрый день, Aram Markaryan!
A S S E M B L Y P R O G R A M M I N G J O U R N A L
http://asmjournal.freeservers.com
вот кусочек из
Oct/Nov 98
Issue 1
;----
:::\_____:::::::::::...........................................FEATURE.ARTICLE
Going Ring0 in Windows 9x
by Halvar Flake

This article gives a short overview over two ways to go Ring0 in Windows 9x in
an undocumented way, exploiting the fact that none of the important system
tables in Win9x are on pages which are protected from low-privilege access.
A basic knowledge of Protected Mode and OS Internals are required, refer to
your Assembly Book for that :-) The techniques presented here are in no way a
good/clean way to get to a higher privilege level, but since they require only
a minimal coding effort, they are sometimes more desirable to implement than a
full-fledged VxD.
1. Introduction
---------------
Under all modern Operating Systems, the CPU runs in protected mode, taking
advantage of the special features of this mode to implementvirtual memory,
multitasking etc. To manage access to system-critical resources (and to thus
provide stability) a OS is in need of privilege levels, so that a program can't
just switch out of protected mode etc. These privilege levels are represented
on the x86 (I refer to x86 meaning 386 and following) CPU by 'Rings', with
Ring0 being the most privileged and Ring3 being the least privileged level.
Theoretically, the x86 is capable of 4 privilege levels, but Win32 uses only
two of them, Ring0 as 'Kernel Mode' and Ring3 as 'User Mode'.
Since Ring0 is not needed by 99% of all applications, the only documented way
to use Ring0 routines in Win9x is through VxDs. But VxDs, while being the only
stable and recommended way, are work to write and big, so in a couple of
specialized situations, other ways to go Ring0 are useful.
The CPU itself handles privilege level transitions in two ways: Through
Exceptions/Interrupts and through Callgates. Callgates can be put in the LDT or
GDT, Interrupt-Gates are found in the IDT.
We'll take advantage of the fact that these tables can be freely written to
from Ring3 in Win9x (NOT IN NT !).

2. The IDT method
-----------------
If an exception occurs (or is triggered), the CPU looks in the IDT to the
corresponding descriptor. This descriptor gives the CPU an Address and Segment
to transfer control to. An Interrupt Gate descriptor looks like this:
--------------------------------- ---------------------------------
D D
1.Offset (16-31) P P P 0 1 1 1 0 0 0 0 R R R R R +4
L L
--------------------------------- ---------------------------------
2.Segment Selector 3.Offset (0-15) 0
--------------------------------- ---------------------------------
DPL == Two bits containing the Descriptor Privilege Level
P == Present bit
R == Reserved bits
The first word (Nr.3) contains the lower word of the 32-bit address of the
Exception Handler. The word at +6 contains the high-order word. The word at +2
is the selector of the segment in which the handler resides.
The word at +4 identifies the descriptor as Interrupt Gate, contains its
privilege and the present bit. Now, to use the IDT to go Ring0, we'll create a
new Interrupt Gate which points to our Ring0 procedure, save an old one and
replace it with ours.
Then we'll trigger that exception. Instead of passing control to Window's own
handler, the CPU will now execute our Ring0 code. As soon as we're done, we'll
restore the old Interrupt Gate.
In Win9x, the selector 0028h always points to a Ring0-Code Segment, which spans
the entire 4 GB address range. We'll use this as our Segment selector.
The DPL has to be 3, as we're calling from Ring3, and the present bit must be
set. So the word at +4 will be 1110111000000000b => EE00h. These values can
be hardcoded into our program, we have to just add the offset of our Ring0
Procedure to the descriptor. As exception, you should preferrably use one that
rarely occurs, so do not use int 14h ;-)
I'll use int 9h, since it is (to my knowledge) not used on 486+.
Example code follows (to be compiled with TASM 5):
-------------------------------- bite here -----------------------------------
.386P
LOCALS
JUMPS
.MODEL FLAT, STDCALL
EXTRN ExitProcess : PROC
.data
IDTR df 0 ; This will receive the contents of the IDTR
; register
SavedGate dq 0 ; We save the gate we replace in here
OurGate dw 0 ; Offset low-order word
dw 028h ; Segment selector
dw 0EE00h ;
dw 0 ; Offset high-order word

.code
Start:
mov eax, offset Ring0Proc
mov [OurGate], ax ; Put the offset words
shr eax, 16 ; into our descriptor
mov [OurGate+6], ax
sidt fword ptr IDTR
mov ebx, dword ptr [IDTR+2] ; load IDT Base Address
add ebx, 8*9 ; Address of int9 descriptor in ebx
mov edi, offset SavedGate
mov esi, ebx
movsd ; Save the old descriptor
movsd ; into SavedGate
mov edi, ebx
mov esi, offset OurGate
movsd ; Replace the old handler
movsd ; with our new one
int 9h ; Trigger the exception, thus
; passing control to our Ring0
; procedure
mov edi, ebx
mov esi, offset SavedGate
movsd ; Restore the old handler
movsd
call ExitProcess, LARGE -1
Ring0Proc PROC
mov eax, CR0
iretd
Ring0Proc ENDP
end Start
-------------------------------- bite here -----------------------------------

3. The LDT Method
-----------------
Another possibility of executing Ring0-Code is to install a so- called callgate
in either the GDT or LDT. Under Win9x it is a little bit easier to use the LDT,
since the first 16 descriptors in it are always empty, so I will only give
source for that method here.
A Callgate is similar to a Interrupt Gate and is used in order to transfer
control from a low-privileged segment to a high-privileged segment using a CALL
instruction.
The format of a callgate is:
--------------------------------- ---------------------------------
D D D D D D
1.Offset (16-31) P P P 0 1 1 0 0 0 0 0 0 W W W W +4
L L C C C C
--------------------------------- ---------------------------------
2.Segment Selector 3.Offset (0-15) 0
--------------------------------- ---------------------------------
P == Present bit
DPL == Descriptor Privilege Level


Ответ отправлен: 18.07.2003, 13:36
Отправитель: Евгений Иванов


Отвечает Broken Sword

Здравствуйте, Aram Markaryan!
В Assembly programming journal есть статья по этому поводу. Могу выслать, давай мыло. Кроме того, имеются просто левые исходники по этому делу

Ответ отправлен: 18.07.2003, 23:59
Отправитель: Broken Sword


Отвечает Hangatyr

Добрый день, Aram Markaryan!
1. Написать VxD.
2. Через обработчик прерывания/исключения.
3. Через шлюз в GDT/LDT.
4. Модификация контекста потока.
и т.д.
Короче, в приложении фрагмент из CIH.

Приложение:

Ответ отправлен: 18.07.2003, 10:58
Отправитель: Hangatyr


Отвечает Bob Johnson

Добрый день, Aram Markaryan!
1. Написать vxd. Это наиболее "законный" и честный способ. О том, как см. на моей странице (в разделе "файлы" есть дока) http://bobjohnson.nm.ru
2. Использовать таблицу прерываний, подпатчить ее так, чтобы адрес обработчика указывал на твою процедуру. Затем вызвать его. Проблема в том, что надо будет самому описывать различные сервисы, которые хочешь вызвать (если конечно хочешь). Пример можно взять из wincih.

* EMan1.4: ---===*** Have your friend the way you would like him ... never mind, do anything that comes natural ***===---


Ответ отправлен: 18.07.2003, 15:00
Отправитель: Bob Johnson


 Вопрос № 3725

Как из Си вызывать функцию, написанную на ассаблере. К примеру, из Си передаются два числа, ассемблер их складывает и возвращает сумму. На Си пишется EXE, на ассемблере - DLL. Но как им обмениваться числами?



Вопрос отправлен: 18.07.2003, 17:38
Отправитель: inetcoder

[Следующий вопрос >>] [Список вопросов]

Отвечает Ayl

Добрый день, inetcoder!
Элементарно. Используя соглашения о передаче параметров.
Пусть на Си прототип функции описан так:
int _cdecl AddInt (int a, int b);
Параметры для функции передаются через стек. Там же сохраняется и точка возврата из функции. При использовании соглашения о передаче параметров в стиле Си (установка по умолчанию и при использовании в описании функции директивы _cdecl) параметры помещаются в стек, начиная с последнего. Т.е. при вызове функции стек будет иметь следующий вид (считаем, что модель памяти flat):
SP -> eip
-> a
-> b
Соответственно, в таком виде их и нужно использовать в ассемблерном коде.
Кроме этого, директива _cdecl предусматривает также соглашения об именовании. А именно, все ассемблерные функции должны предваряться знаком подчеркивания.
Результат выполнения функций возвращается через регистры. Причем значения типа int возвращаются в регистре eax.
В результате всего вышесказанного пишем на асме такую функцию:
PUBLIC _AddInt
_AddInt proc
push ebp ; сохраняем кадр стека
mov ebp, esp ; устанавливаем BP на вершину стека
mov eax, [ebp + 8] ; в EAX параметр a
add eax, [ebp + 12] ; а теперь - сумма
pop ebp ; восстанавливаем кадр стека
ret ; выходим
_AddInt endp


Ответ отправлен: 18.07.2003, 19:03
Отправитель: Ayl


Отвечает Gibbel

Доброе время суток, inetcoder!
Зависит от того, какого стандарта вызовов придерживается ваша процедура на ассемблере. Возможные варианты:
данные передаются через стек от последнего к первому
данные передаются через стек от первого к последнему
данные передаются через регистры (1й параметр eax, 2й - ecx и т.д...)
данные передаются каким-либо своим методом.

Ответ отправлен: 18.07.2003, 18:02
Отправитель: Gibbel


Отвечает St

Привет, inetcoder!
На ассемблере это делается так:
CALL LoadLibraryA, OFFSET DLL_NAME
MOV hinstDLL,EAX
CALL GetProcAddress, hinstDLL,
OFFSET SendDatafileName
;SendDatafileName - имя моей функции в DLL
CALL EAX, offset DATA_FILE_PATH_BUFFER
;EAX - адрес моей функции в DLL, которую вернула GetProcAddress
;DATA_FILE_PATH_BUFFER-переменная передаваемая в DLL-функцию
На Си думаю будет приблизительно также.
St

Ответ отправлен: 18.07.2003, 17:51
Отправитель: St


Отвечает Bob Johnson

Добрый день, inetcoder!
Когда ты пишешь dll, то описываешь там все экспортируемые процедуры. В них ты указываешь количество принимаемых параметров и способы их передачи. В виндах принят способ stdcall (все пар-ры передаются через стек в обратном порядке). Можно передавать через регистры или специальную область памяти.
Возврат результата обычно происходит через eax.
Пример (процедура):
myproc proc p1: DWORD, p2: DWORD
mov eax, [p1]
add eax, [p2]
ret
myproc endp
вызов:
push _число1_
push _число2_
call myproc
;eax = сумма

* EMan1.4: ---===*** Have your friend the way you would like him ... never mind, do anything that comes natural ***===---


Ответ отправлен: 19.07.2003, 01:07
Отправитель: Bob Johnson


Отвечает Евгений Иванов

Добрый день, inetcoder!
Как обычно, через стек передаются параметры.
Можно заполнять структурку, и передавать её адрес (указатель).
Также заполнять в подпрограмме её.


Ответ отправлен: 19.07.2003, 23:24
Отправитель: Евгений Иванов


 Вопрос № 3727

Добрый день эксперты!!!
Извините но Вы все заяб???ли. Че вы прицепились ко всяким резинкам(hubba) и наташе б...ля...
Занимайтесь своим делом?
А то вы как бабули которые торгуют семечками на рынке. Пиз,,,дя,,т о всякой херне.
Извините что так высказался. Но из рассылки сделали
то же самое как на работе- сплетни и вся такая ебот,,,ня. Если конечно кто работает.
Ответ от того на вопрос который ответили про оси и валы, и диоды тоже. Это к BJ



Вопрос отправлен: 18.07.2003, 22:16
Отправитель: reset

[Следующий вопрос >>] [Список вопросов]

Отвечает Tigran K. Kalaidjian

Приветствую Вас, reset!
Спам продолжается, друзья.
> Извините но Вы все заяб???ли.
Если начали ругаться, то оставили бы свой E-MAIL, чтобы можно было бы ответить, а то крикнуть, оскорбить и сбежать всяк горазд. Нехорошо это... Подло...
Мой же E-MAIL публикуется в каждой рассылке, поэтому милости просим...
Хочу напомнить, что Эксперт - лицо, добровольно принявшее на себя обязательство отвечать на вопросы. Каждый ответ - это желание помочь людям, стремящимся к познанию.
> Че вы прицепились к наташе б...ля...
НБ показала дыры Системы. И это правильно.
А Экспертам всё равно. Им, опять же, не платят за чистоту рассылки. Ежели Вам не нравится рассылка - отпишитесь.
> Занимайтесь своим делом?
Может быть и не своим, но это, пардон, не Ваше дело. Не Вам решать, на что отвечать экспертам, а на что - нет. Вот ежели бы Вы стали модератором - это другое дело.
> Пиз,,,дя,,т о всякой херне.
Ну, так и не читайте - Вас никто не принуждает.
> Извините что так высказался. Но из рассылки сделали
И Вы своим письмом внесли скромную лепту в этот котел.
> то же самое как на работе- сплетни и вся такая ебот,,,ня.
Мне жаль за Вашу работу...
> Если конечно кто работает.
А что такое ? У Вас может поменяться впечатление о человеке в зависимости от его занятости? Я, например, учусь. И зарабатывать не имею права (читайте законы).
> Ответ от того на вопрос который ответили про оси и валы, и диоды тоже.
Вы сперва научИтесь языком владеть, а потом пишите критику.

Ответ отправлен: 19.07.2003, 12:35
Отправитель: Tigran K. Kalaidjian


Отвечает Bob Johnson

Доброе время суток, reset!
> Это к BJ
Раз ко мне, то и задавай личный вопрос. Или еще лучше - пиши на мыло и не засоряй рассылку, раз так об этом беспокоишься.
> Извините но Вы все заяб???ли.
Если ты такой "аристократичный", что "всякая херня" не подходит для твоего высокоинтелектуального уровня развития и "Вы" ты пишешь с большой буквы, то должен по идее знать, что слово "заебали", или "заебли" пишется через "е", а не "я". Деревенщина хренова.
> Че вы прицепились ко всяким резинкам(hubba)
А что, ты хуба? Тогда я скажу, что твое умственное развитие за последние две недели просто поражает - от "лохи" до такого большого письма...
> Ответ от того на вопрос который ответили про оси и валы, и диоды тоже.
Вначале русский язык выучи.
> Занимайтесь своим делом?
Имелся ввиду восклицательный знак в конце? Тогда я скажу тебе так - ты нас на работу не нанимал и денег нам не платишь, так что не тебе решать, что нам делать, understood?


*** Наташа Б. ***

Лично я не считаю все ее письма спамом (как сама Наташа все время пыталась их представить) и не согласен с ее позицией относительно того, что мы виноваты в этом спаме, но это отдельный разговор. Несмотря на большое количество противоречий в ее вопросах (что доказывает то, что "Наталья Березовец" не существует под таким именем) в них есть немало полезной информации. В частности многим читателям может оказаться интересным узнать про SG, т.к. очень часто попадаются вопросы с просьбой выслать исходник вируса (желательно с комментариями) для ознакомительных целей. А именно это и рассматривалось в IV. Тут, конечно, некоторые читатели могут возмутиться: "Не надо раздавать информацию про написание вирусов, потому что это может привести к действительному их написанию". Моя позиция в этом вопросе проста - ничего плохого в написании вируса нет. Это может быть интересным, познавательным и уж точно совершенствует тебя как программиста. Плохо (я бы даже сказал очень плохо и недопустимо) эти вирусы распространять. А это уже зависит от конкретного человека, будет он так поступать или нет. Причем если мировоззрение человека позволяет ему подсунуть вирус другу, то если под рукой не будет вируса, он сделает что-то еще, потому что ему будет нужен адреналин, самоудовлетворение и самоутверждение как "крутого программиста".
Возвращаясь к теме хочу отметить, что "произведение вирусного искусства" предыдущего тысячелетия WinCIH в исходных файлах был представлен именно в журнале IV. А в этом исходнике есть чему поучиться! И совсем необязательно, что учиться по нему можно только написанию других вирусов - я использовал его при создании драйвера под 9х, выполняющего функции антивирусного(!) монитора, т.к. DDK достаточно плохо документирован.


В общем я не понимаю, что ты вообще хотел сказать, но лучше больше этого никогда не делай (а то обосрать и даже e-mail не оставить - на это ума много не надо).
А если ты хочешь реально что-то сделать для "очищения" рассылки - то делай, а не пи*ди. Становись экспертом, напиши скрипт для голосования, чтобы если какому-либо эксперту вопрос кажется не по теме, то он мог это выразить, и если набирается определенное количество претензий на вопрос, то вопрос снимается и не попадает в рассылку. Но лично мне кажется, что обычному, незапаренному и незакомплексованному читателю с определенным чувством юмора будет даже несколько приятно читать все эти "offtopic" вопросы, потому что они расслабляют. С другой стороны, если наложить какие-либо серьезные ограничения на экспертов rusfaq, то многим это не понравится (помни, что все, что мы тут делаем - полностью добровольно и бесплатно).

* EMan1.4: ---===*** Have your friend the way you would like him ... never mind, do anything that comes natural ***===---


Ответ отправлен: 20.07.2003, 21:00
Отправитель: Bob Johnson


 Вопрос № 3728

Здравствуйте, уважаемые эксперты. Вопрос касается быстрых алгоритмов и потому, кроме вас не знаю куда обратиться. Проблема вот в чем: существует большой массив из последовательных чисел 1,2,3... 1000000, надо сформировать другой массив, в котором все эти исла были перемешаны в случайном порядке (не повторялись). Требуется сделать с максималной быстротой.
Огромное всем спасибо за вимание. (просто потом и поблагодарить проблематично - e-mail-ов нет).
P.S. я раньше высылала вопрос, но почему-то подтверждения так и не пришло. Может интернет чахнуть начал. Иногда страшные вещи пишет - "Internet system error"...



Вопрос отправлен: 18.07.2003, 23:04
Отправитель: Светлана (swetlana_news@rambler.ru)

[Следующий вопрос >>] [Список вопросов]

Отвечает Bob Johnson

Приветствую Вас, Светлана!
> просто потом и поблагодарить проблематично - e-mail-ов нет
Как это нет??? Есть... :) Даже не по одному...
> Internet system error
По правилам перевода получаем "ошибка системы интернета". Это плохо...


Теперь по делу :)
Похожий вопрос уже был (№ 730 в рассылке по дельфи) - прежде всего посмотри, что там отвечали. Но у тебя массив значительно больше.
Вот простая идея - проходишь массив один раз циклом от первого до последнего элементы. На каждом шагу цикла вычисляешь случайное число в диапазоне 1 ... 1 000 000 и меняешь текущий элемент массива с элементом, номер которого соответствует случайному числу. В результате должно получиться примено то, что тебе нужно...

* EMan1.4: ---===*** Have your friend the way you would like him ... never mind, do anything that comes natural ***===---


Ответ отправлен: 19.07.2003, 01:07
Отправитель: Bob Johnson


Отвечает Евгений Иванов

Доброе время суток, Светлана!
Предлагаю так:
1.берёшь случайное число в диапазоне от искомого размера,
2.Число под этим индексом из массива выдаёшь в выходной массив.
3.Сдвигаешь всё, что позади взятого числа, вперёд с накладкой на взятое,
4.уменьшаешь искомый размер,
5.снова на 1, если искомый размер не нулю.


Ответ отправлен: 19.07.2003, 23:24
Отправитель: Евгений Иванов


 Вопрос № 3729

хайте;), ув. товарищи эксперты!
возращаюсь к вопросу №3660
я, наверное, не так выразился,скорее всего, совсем нетак;(
проблема в следующем:
дано число, к примеру 42.15
ax=42
bx=15
ax=cos(этого числа)
На компе, где пишу эту программку,
нет FPU, он древний, как кости мамонта;)



Вопрос отправлен: 19.07.2003, 06:41
Отправитель: Zensor_ (zasm@mail.ru)

[Следующий вопрос >>] [Список вопросов]

Отвечает Теоретик

Добрый день, Zensor_!
Вы используете совершенно неправильный подход для хранения дробной части.
Посудите сами, число 3.5 у вас будет записано так:
ax=3
bx=5
А число 3.1234 будет записано так:
ax=3
bx=1234
То есть дробная часть должна быть меньше, а вас получится больше.
На самом деле необходимо принять число 65536 за единицу.
В этом случае 0.5 будет записываться как 65536*0.5 = 32768,
а число 0.1234 так: 65536*0.1234 ~= 8087.
Максимальная дробная часть будет обозначаться числом 65535, что соответсвует 65535/65536 (примерно 0.999985).
Для нахождения косинуса используйте ряд Тейлора.
Записать это на асме не так легко (раз нельзя просто воспользоваться fcos). Кстати, начиная с 486-го сопроцессор встроенный, а тачку древнее я в наше время плохо представляю.
Но если вы всё-таки настаиваете на отсутствие сопроцессора, вот вам алгоритм. Переведите на асм сами - возьня с числами с фиксированной запятой, особенно в 16-битном асме - дело крайне скучное.
Итак, ряд следующий Тейлора для косинуса следующий:
cos x = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - ...
Таким образом, для того, чтобы получить i-тый элемент ряда надо взять (i-1)-вый, поменять знак, домножить на x^2, разделить на (2*i-1), а потом снова разделить на 2*i.
Получив очередной элемент, прибавляем его к регистру (или ячейке), где накапливается результат. Вычисляем следующий элемент и т.д.
Так как используется запись с фиксированной точкой, то можно экспериментальным путём установить оптимальное количество элементов, которые необходимо просчитывать (так как начиная с какого-то элемента они перестают влиять на наше число, заданное с точностью до 1/65536).
С целью оптимизации два деления (на 2*i-1 и на 2*i) можно заменить на одно.
В начале считаем, что первую единицу мы уже прибавили.
Непосредственно алгоритм.
Сумма = 1
Элемент = 1
Для каждого i от 1 до Max делаем:
...Удвоенное = i*2
...Делитель = (Удвоенное - 1) * Удвоенное
...Элемент = -Элемент * X * X / Делитель
...Если Элемент = 0 то Прервать цикл -- для оптимизации
...Сумма = Сумма + Элемент
Конец цикла
Краткий список геморроев:
1. Деление надо проводит в несколько этапов. Сперва делишь целую часть, затем делишь полученный при первом
делении остаток, заетм дробную часть, а потом это всё ещё объединяешь.
2. Надо работать со знаковым числами. Обрати внимание, что знак у нас хранится только у целой части.
Таким образом, уелые части можно складывать операцией ADD. А вот для сложения дробных частей, нужно проверить знаки чисел, если совпадают, значит ADD, если различаются - значит SUB.
3. После каждой операции сложения дробюных частей не надо забывать прибавлять флаг переноса к дробной части.
4. Умножение дробных чисел выполняется с помощью четырех операций простого умножения. Есть хитрый способ, позволяющий использовать только три умножения, но от этого не легче.
5. Результат умножения будет 64-битным. Необходимо будет выкинуть лишние биты.
6. Данный способ работает только, если угол задан в радианах. Если у тебя угол в градусах, то переводи по формуле radian = gradus*pi/180
7. Данный способ не работает, если угол выходит за пределы от -2*pi..2*pi

Одним словом, если у вас всё-таки 486-й или выше, то лучше используйте fcos.
Я понимаю, вам, возможно, лень взять книжку и выучить наконец то, чего вы так боитесь.
Однако самому запрограммировать косинус ГОРАЗДО сложнее.


Ответ отправлен: 20.07.2003, 17:37
Отправитель: Теоретик


Отвечает Hangatyr

Здравствуйте, Zensor_!
Так проблема-то в чем? Косинус что ли вычислить?
cos(x)=1 - x^2/2! + x^4/4! - x^6/6! + x^8/8!... и так далее.

Ответ отправлен: 19.07.2003, 08:47
Отправитель: Hangatyr


Отвечает Bob Johnson

Здравствуйте, Zensor_!
Для представления нецелых чисел в компе используется масштабирование. При этом, если под дробную часть отведено 16 разрядов, то единица в этом числе будет означать 1/65536 действительного числа. Вариант как у тебя не применяется.
Две основные тригонометрические функции (sin & cos) разлагаются кроме всего прочего в ряды Тейлора. Обычно это делают в точке 0, а аргумент приводят в диапазон до pi/4 по модулю. Это позволяет получать весьма высокую точность при вполне умеренном числе членов ряда (3 - 6). В общем, формула для синуса такая: sin(x) = x - x^3/3! + x^5/5! - x^7/7! и т.д.
В приложении 16-ти разрядная процедура для вычисления синуса - хочешь, разберись (я уже не помню, т.к. давно писал).

* EMan1.4: ---===*** Have your friend the way you would like him ... never mind, do anything that comes natural ***===---


Приложение:

Ответ отправлен: 20.07.2003, 14:46
Отправитель: Bob Johnson


 Вопрос № 3730

хайте, эксперты!
определился с компилятором, это будет fasm 1.44.
инета небыло, всвязи с чем вознило
много проблем;) :
1.movsx и movzx чем различаются?
org 100h
mov bl,12h
movsx ax,bl
cmp ax,0012h
je @e
mov ah,10h
int 16h
@e:
ret
делает тоже, что и
org 100h
mov bl,12h
movzx ax,bl
cmp ax,0012h
je @e
mov ah,10h
int 16h
@e:
ret
код разный генерируется, в первом
случае BE, во втором B6.
2.Расскажите пожалуста про bt, bts, btr, btc
3.младшие пять бит из AL это 11111111



Вопрос отправлен: 19.07.2003, 06:42
Отправитель: Zensor_ (zasm@mail.ru)

[Следующий вопрос >>] [Список вопросов]

Отвечает Теоретик

Добрый день, Zensor_!
S = Sign
Z = Zero
Другими словами, MOVSX дополняет значением бита знака, а MOVZX - нулями.
Если бит знака нулевой, то разницы действительно никакой.
В вашем случае так и есть.

Ответ отправлен: 20.07.2003, 19:43
Отправитель: Теоретик


Отвечает Ayl

Добрый день, Zensor_!
1. movsx - расширение числа с помощью знакового бита (старший бит регистра), movzx - расширение числа с помощью нулей.
В твоем случае bl равен 12h, это положительное число, старший бит равен 0 - соответственно, результат обеих команд будет совпадать. Если же ты в bl поместишь, скажем, 82h, то старший бит будет равен 1 и в случае movsx ax, bl у тебя в регистре ax будет число ff82h, а в случае movzx ax, bl - 0082h.
2. Это команды для работы с битами. BT копирует указанный бит во флаг переноса (CF), BTC - копирует и затем инвертирует указанный бит в операнде, BTS - копирует и устанавливает в 1, BTR - копирует и сбрасывает в 0.
Пример:
ax = 0011 0001 1100 1010 (31cah)
bt ax, 4 : CF = 0, ax = 31cah
btc ax, 4 : CF = 0, ax = 31Dah
bts ax, 4 : CF = 0, ax = 31Dah
btr ax, 4 : CF = 0, ax = 31cah
btr ax, 3 : CF = 0, ax = 31c2h
3. Вопрос не понял. Что ты имел в виду? Младшие 5 битов из AL - это биты 0-4, например:
биты:76543210
AL = 10100110
Младшие 5 бит - это 00110.

Ответ отправлен: 20.07.2003, 21:56
Отправитель: Ayl


Отвечает Bob Johnson

Добрый день, Zensor_!
1. MovZX - MOVe Zero eXtension
MovSX - MOVe Sign eXtension
первая предполагает, что операнд без знака, вторая - со знаком.
Пример al = 0x5
movzx ax, al; ax = 5
movsx ax, al; ax = 5
-----
al = -1 = 0xFF
movzx ax, al; ax = 0xFF = 255
movsx ax, al; ax = 0xFFFF = 65535 = -1
2. Команды проверки и установки (bts), сброса (btr) или инверсии (btc) бита. bt бит не меняет.

* EMan1.4: ---===*** Have your friend the way you would like him ... never mind, do anything that comes natural ***===---


Ответ отправлен: 20.07.2003, 14:46
Отправитель: Bob Johnson


Отвечает Tigran K. Kalaidjian

Приветствую Вас, Zensor_!
MOVSX "назначение", "источник" - перенос со знаком-расширителем: считывает байт или слово в "источнике", и копирует его в слово или двойное слово, определенное "назначением" со знаком-расширителем. Назначение - регистр, источник - значение памяти или регистр.
MOVZX "назначение", "источник" - перенос с расширителем-нулем: считывает байт или слово в "источнике", и копирует его в слово или двойное слово, определенное "назначением" со знаком-нулем. Назначение - регистр, источник - значение памяти или регистр.
BTC
(Bit Test and Complement)
Проверка бита с инверсией (дополнением)
Схема команды: btc источник,индекс
Назначение: извлечение значения заданного бита в флаг cf и изменение его значения в операнде на обратное.
Алгоритм работы:
получить значение бита с номером позиции индекс в операнде источник;
инвертировать значение выбранного бита в операнде источник;
установить флаг сf исходным значением бита.
Состояние флагов после выполнения команды:
Применение:
Команда btс используется для определения и инвертирования значения конкретного бита в операнде источник. Номер проверяемого бита задается содержимым второго операнда индекс (значение из диапазона 0...31). После выполнения команды флаг cf устанавливается в соответствии с исходным значением бита, то есть тем, которое было до выполнения команды.
.386
mov ebx,01001100h
;проверка состояния бита 8 и его обращение:
btc ebx,8 ;cf=1 и ebx=01001000h

BTR
(Bit Test and Reset)
Проверка бита с его сбросом в 0
Схема команды: btr источник,индекс
Назначение: извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
Алгоритм работы:
получить значение бита с указанным номером позиции в операнде источник;
установить флаг cf значением выбранного бита;
установить значение исходного бита в операнде в 0.
Применение:
Команда btr используется для определения значения конкретного бита в операнде источник и его сброса в 0. Номер проверяемого бита задается содержимым второго операнда индекс (значение из диапазона 0...31). В результате выполнения команды флаг cf устанавливается в соответствии со значением исходного бита, то есть тем, что было до выполнения операции.
.386
mov ebx,01001100h
;проверка состояния бита 8 и его сброс в 0
btr ebx,8 ;cf=1 и ebx=01001000h

BT
(Bit Test)
Проверка битов
Схема команды: bt источник,индекс
Назначение: извлечение значения заданного бита в флаг cf.
Синтаксис
Алгоритм работы:
получить бит по указанному номеру позиции в операнде источник;
установить флаг cf согласно значению этого бита.
Применение:
Команду bt используют для определения значения конкретного бита в операнде источник. Номер проверяемого бита задается содержимым второго операнда (значение числом из диапазона 0...31). После выполнения команды, флаг cf устанавливается в соответствии со значением проверяемого бита.
.386
mov ebx,01001100h
bt ebx,8 ;проверка состояния бита 8 и установка cf= в 1
jc m1 ;перейти на m1, если проверяемый бит равен 1
...

BTS
(Bit Test and Set)
Проверка бита с его установкой в 1
Схема команды: bts источник,индекс
Назначение: извлечение значения заданного бита операнда в флаг cf и установка этого бита в единицу.
Алгоритм работы:
получить значение бита с указанным номером позиции в операнде источник;
установить флаг cf значением выбранного бита;
установить значение исходного бита в операнде источник в 1.
Применение:
Команда bts используется для определения значения конкретного бита в операнде источник и установки проверяемого бита в 1. Номер проверяемого бита задается содержимым второго операнда индекс (значение из диапазона 0...31). После выполнения команды флаг cf устанавливается в соответствии со значением исходного бита, то есть тем, что было до выполнения операции.
.386
mov ebx,01001100h
;проверка состояния бита 0 и его установка в 1
bts ebx,0 ;cf=0 ebx=01001001h




Ответ отправлен: 19.07.2003, 22:29
Отправитель: Tigran K. Kalaidjian


Отвечает Hangatyr

Приветствую Вас, Zensor_!
1. Это разные команды. Потому и разные опкоды. MOVZX - пересылка с нулевым расширением, а MOVSX - со знаковым.
Например,
movzx bx, al
При al = 0ffh
после выполнения bx будет равен 00ffh,
а после "movsx bx, al" - 0ffffh
Если бы al был, допустим 02h, то bx был бы равен 00002h и в том и в другом случае.
Т.е. если в al положительное число, то результат будет одинаков в обоих случаях.
2. Что про них расказывать-то? Все они извлекают значение определенного бита операнда в cf, после чего изменяют его значение в операнде: bt - никак, btc - инвертирует, btr - в 0, bts - в 1.

Ответ отправлен: 19.07.2003, 07:37
Отправитель: Hangatyr


Отвечает Евгений Иванов

Добрый день, Zensor_!
movsx - знаковое расширение.
movzx - беззнаковое.
У тебя всё правильно работает.
Если бы был 7 бит установлен в BL, например, BL=93h,
тогда в AX будет не 93h, а FF93h,
то есть знаковый бит расширяется в старшую часть слова.
;---
BT - это проверка бита.
флаг-C становится равным значению требуемого бита.
Например:
ax=67h = 0110.0111b
bt ax, 2
значит флаг CF=1
bt ax, 3
значит флаг CF=0
позиция битов с младшего и с нуля считаются.
BTC - то же делает и ещё инвертирует требуемый бит.
BTR - ..., и сбрасывает (=0)
BTS - ..., и устанавливает (=1)
спасибо за вопрос, только что сам узнал, что это.
Никогда до этого не использовал эти команды.
использовал так:
test ax, 4
и флаг Z=1, если бит был 1, и 0, если 0.
а вот изменять бит - это интересно!


Ответ отправлен: 19.07.2003, 23:24
Отправитель: Евгений Иванов



Форма отправки вопроса

Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+ или отправлять вопросы с сайта по адресу: http://rusfaq.ru/cgi-bin/Message.cgi.

(C) 2002-2003 Команда RusFAQ.ru.

 Персональные данные

Ваше имя:

Ваш e-mail:

Опубликовать мой e-mail в рассылке


 Вопрос и дополнение

Ваш вопрос:


Приложение (если необходимо):


Получить ответов:


 Выбор рассылки

Программисту
Assembler (33)
C / C++ (24)
Perl (4)
Builder / Delphi (18)
Pascal (22)
Basic / VBA (10)
Java / JavaScript (11)
PHP (8)
Криптография (8)
WinAPI (10)
Пользователю
Windows 95/98/Me (42)
Windows NT/2000/XP (36)
"Железо" (31)
Поиск информации (22)
Администратору
Windows NT/2000/XP (22)
Linux / Unix (8)
Юристу
Гражданское право (11)
Семейное право (6)
Трудовое право (9)
КоАП (5)

Отправить вопрос всем экспертам выбранной рассылки.




Задать вопрос | Регистрация эксперта | Поиск в базе | Чат | Форумы | Новости
Проект экспертов RusFAQ.ru | Фотоальбом | Virus.RusFAQ.ru | Администрирование
Профессиональная WEB-Студия B.I.T.


Яндекс цитирования
© 2001-2003 Россия, Москва. Авторское право: Калашников О.А.


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное