Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.12.2014, 10:40   #21
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

сортировка вставками.
Код:
format PE console
include 'include\win32a.inc'
entry start
 
section '.data' data readable writeable
        array dd 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -100500
        size=($-array)/4
 
section '.code' code readable executable
start:
        stdcall insert_sort, array, size
        invoke ExitProcess, 0
 
insert_sort:
i equ ecx
j equ edx
        push ebp
        mov ebp, esp
        pushad
 
        mov esi, [ebp+8]     ;esi=array
        mov i, 1             ;i=1
is1:    cmp i, [ebp+12]      ;i<size
        ja is_exit
        mov eax, [esi+i*4]    ;eax=key=array[i]
        mov j, i              ;j=i-1
        dec j
is2:    cmp j, 0              ;j>=o
        jl is3
        cmp [esi+j*4], eax    ;array[j]>key
        jl is3
        mov ebx, [esi+j*4]    ;array[j+1]=array[j]
        mov [esi+j*4+4], ebx
        dec j                 ;j-=1
        jmp is2
is3:
        mov [esi+j*4+4], eax  ;array[j+1]=key
        inc i
        jmp is1
is_exit:
        popad
        leave
        ret 8
 
section '.idata' import data readable writeable
library KERNEL32, 'KERNEL32.DLL'
 
import KERNEL32,\
       ExitProcess, 'ExitProcess'
Код:
#include <stdio.h>
#include <stdlib.h>
 
void print_array(int*, int);
void ins_sort(int*, int);
 
int main(int argc, char *argv[])
{
  int array[]={9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -500};
  print_array(array, sizeof(array)/sizeof(int));
  putchar('\n');
  ins_sort(array, sizeof(array)/sizeof(int));
  print_array(array, sizeof(array)/sizeof(int));
  getchar();
  return 0;
}
 
 
void print_array(int* array, int size)
{
     int i;
     for (i=0; i<size; ++i)
         printf("%d ", array[i]);
     
}
 
void ins_sort(int* array, int size)
{
     int i, j, key;
     for (i=1; i<size; ++i)
     {
         key=array[i];
         j=i-1;
         while (j>=0 && array[j]>key)
         {
               array[j+1]=array[j];
               j-=1;
         }
         array[j+1]=key;
     }
}
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 10:49   #22
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

драйвер, позволяющий установить глобальный хук на всё время работы системы до перезагрузки
Тема на одном из форумов натолкнула меня (автор раздела Not at all! он же vadimych) на написание драйвера, позволяющего установить глобальный хук на всё время работы системы до перезагрузки. В данном случае будет изменена функция MessageBoxA из библиотеки user32.dll. Это пример для Windows x32, но и на х64 можно сделать подобное. Требуется только цифровая подпись драйвера.
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:05   #23
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Код:
UNICODE__STRING struct
Length_     dw ?
MaxLength   dw ?
Buffer      dd ?
UNICODE__STRING ends
 
unis macro name,string
local s,e
len sizestr <string> 
align 4
sstr substr <string>,2,len-2 
s label word 
% forc n,<sstr>
dw '&n'
endm
e dw 0
align 4
k=(e-s)
name UNICODE__STRING {k,k+2,s}
endm 
.686P
.model flat,stdcall
option casemap:none 
include \masm32\include\ntstatus.inc
include \masm32\include\ntddk.inc
include \masm32\include\ntoskrnl.inc
include \masm32\include\native.inc 
includelib \masm32\lib\ntoskrnl.lib
include \masm32\macros\strings.mac
include \masm32\macros\du.mac 
.const
 
function db 'MessageBoxA',0
unis ndirectory,'\KnownDlls'
unis ndll,'user32.dll'
fin dd fin_ 
.code
assume fs:nothing 
DriverUnload proc uses ebx edi esi pdrobject:dword 
invoke DbgPrint,$CTA0("UNLOADING") 
mov eax,STATUS_SUCCESS 
ret
DriverUnload endp 
.code; INIT 
driver_entry proc uses ebx edi esi pdrobject:dword,pregpath:dword
local oa:OBJECT_ATTRIBUTES
local iob:IO_STATUS_BLOCK
local li:LARGE_INTEGER
local hdll,pmem,hdir,hsec,cbytes:dword
local pspace:dword
and pmem,0
and li.LowPart,0
and li.HighPart,0
invoke RtlZeroMemory,addr oa,sizeof oa
mov oa._Length,sizeof oa
lea eax,ndirectory
mov oa.ObjectName,eax
mov oa.Attributes,OBJ_KERNEL_HANDLE
invoke ZwOpenDirectoryObject,addr hdir,0fh,addr oa
; получаем описатель директории \KnownDlls
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle directory 0x%X"),hdir
push hdir
pop oa.RootDirectory
lea eax,ndll
mov oa.ObjectName,eax
invoke ZwOpenSection,addr hsec,SECTION_ALL_ACCESS,addr oa
; открываем секцию user32.dll  
test eax,eax
js @f
invoke NtClose,hdir
invoke DbgPrint,$CTA0("Handle section 0x%x"),hsec
; отображаем в адресное пространство своего процесса
invoke ZwMapViewOfSection,hsec,-1,addr pmem,0,li.LowPart,0,addr li,1,0,PAGE_EXECUTE_READWRITE
test eax,eax
js @f
push pmem
call get_address
test eax,eax
js @f
mov ebx,eax
push pmem
call get_space
mov pspace,eax
mov eax,(get_space-my_messagebox)
cmp ecx,eax
ja @ok
invoke DbgPrint,$CTA0("Free space is too small, fail...")
jmp @un
@ok: try
cli
mov eax,cr0
; сбрасываем бит WP в регистре CR0, тем самым разрешая запись 
and eax,0fffeffffh          ; на readonly страницы
mov cr0,eax
sti
mov eax,[ebx]
;несмотря на то, что запись разрешена, попытка записи без  
mov byte ptr [ebx],0e8h
;предварительного чтения приведёт  к краху 
mov eax,pspace
; правим функцию MessageBoxA
sub eax,5
sub eax,ebx
mov [ebx+1],eax
mov edi,pspace
mov eax,[edi]
mov ecx,(get_space-my_messagebox)
mov esi,offset my_messagebox
rep movsb
; теперь до перезагрузки системы любой диалог, выданный функцией 
;MessageBoxA будет иметь заголовок и текст "Hook!"
cli
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
invoke DbgPrint,$CTA0("MessageBox address 0x%X"),ebx
fin_:: 
finally
@un:
invoke ZwUnmapViewOfSection,-1,pmem 
; закрываем проекцию секции,
;при этом в ней сохранятся все сделанные изменения.
@@: invoke NtClose,hsec 
@1: invoke DbgPrint,$CTA0("Last Error 0x%X"),eax
mov eax,pdrobject
mov (DRIVER_OBJECT ptr [eax]).DriverUnload,offset DriverUnload
mov eax,STATUS_SUCCESS
ret
driver_entry endp
except fin
  
my_messagebox proc
call @f
@@: pop eax
sub eax,offset @b
add eax,offset message
mov [esp+10h],eax
mov [esp+0ch],eax
mov eax,[esp]
add esp,4
push ebp
mov ebp,esp
jmp eax
message db 'Hook!',0 
my_messagebox endp
get_space proc uses ebx edi esi psection
mov ebx,psection
push ebx
add ebx,(IMAGE_DOS_HEADER ptr [ebx]).e_lfanew
movzx esi,(IMAGE_NT_HEADERS ptr [ebx]).FileHeader.SizeOfOptionalHeader
movzx ecx,(IMAGE_NT_HEADERS ptr [ebx]).FileHeader.NumberOfSections
add esi,ebx
lea esi,[esi+sizeof IMAGE_FILE_HEADER+4]
mov edi,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader.SizeOfCode
mov ebx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader.BaseOfCode 
pop eax
add ebx,eax
invoke DbgPrint,$CTA0("ImageBase 0x%X, Base of Code 0x%X"),psection,ebx
@@: cmp edi,(IMAGE_SECTION_HEADER ptr [esi]).SizeOfRawData
je @f
add esi,sizeof IMAGE_SECTION_HEADER
loop @b
xor eax,eax
jmp @ret 
@@: mov esi,(IMAGE_SECTION_HEADER ptr [esi]).Misc.VirtualSize 
sub edi,esi
add ebx,esi
invoke DbgPrint,$CTA0("Base of space 0x%X, Size 0x%X"),ebx,edi
mov eax,ebx
mov ecx,edi
@ret:  ret
get_space endp
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:06   #24
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Код:
get_address proc uses ebx edi esi psection
mov eax,psection
mov ebx,eax
add ebx,(IMAGE_DOS_HEADER ptr [eax]).e_lfanew
lea ebx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader
mov ebx,(IMAGE_OPTIONAL_HEADER ptr [ebx]).DataDirectory.VirtualAddress
add ebx,eax
lea esi,function
mov edi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNames
push ebx
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).NumberOfNames
lea edi,[edi+eax-4]
mov edx,-1
@@:add edi,4
push edi
mov edi,[edi]
add edi,eax
inc edx
push esi
mov ecx,sizeof function-1
repe cmpsb
pop esi
pop edi 
je @f
dec ebx
jne @b
pop ebx
mov eax,-1
jmp @ret 
@@: pop ebx
mov esi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNameOrdinals
shl edx,1
add edx,esi
add edx,eax
movzx edx,word ptr [edx]
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfFunctions
add ebx,eax
shl edx,2
add edx,ebx
mov edx,[edx]
add eax,edx 
@ret:  ret
get_address endp
end driver_entry
Коды драйверов под х32 и х64, позволяющие найти адрес неэкспортируемой ядром функции, в данных примерах это ZwProtectVirtualMemory. Сначала в библиотеке ntdll.dll находится номер соответствующего системного сервиса, затем, от адреса экспортируемой функции ядра по определённому смещению, фиксированному как в х32, так и в х64 системах проверяются номера системных сервисов до совпадения с требуемым. Имя функции, адрес которой взят за точку отсчёта, определено в дизассембелере. Источник вдохновения - та же тема на том же форуме, название которого здесь нельзя привести.
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:14   #25
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Код:
.686P
.model flat,stdcall
option casemap:none
 
include \masm32\include\ntstatus.inc
include \masm32\include\ntddk.inc
include \masm32\include\ntoskrnl.inc
include \masm32\include\native.inc
 
includelib \masm32\lib\ntoskrnl.lib
include \masm32\macros\strings.mac
include \masm32\macros\du.mac
 
.const
 
nfunction db 'ZwProtectVirtualMemory',0
unis function,'ZwPulseEvent'
unis nfile,'\SystemRoot\system32\ntdll.dll'
.code
assume fs:nothing
DriverUnload proc uses ebx edi esi pdrobject:dword
invoke DbgPrint,$CTA0("UNLOADING")
mov eax,STATUS_SUCCESS
ret
DriverUnload endp
 
.code; INIT
 
driver_entry proc uses ebx edi esi pdrobject:dword,pregpath:dword
local oa:OBJECT_ATTRIBUTES
local iob:IO_STATUS_BLOCK
local li:LARGE_INTEGER
local hfile,pmem,hdo,hsec:dword
 
and pmem,0
and li.LowPart,0
and li.HighPart,0
 
invoke RtlZeroMemory,addr oa,sizeof oa
mov oa._Length,sizeof oa
lea eax,nfile
mov oa.ObjectName,eax
mov oa.Attributes,OBJ_KERNEL_HANDLE
 
invoke ZwCreateFile,addr hfile,FILE_READ_DATA+FILE_EXECUTE,addr oa,addr iob,0,0,FILE_SHARE_READ,FILE_OPEN,0,0,0
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle file 0x%X"),hfile
 
mov oa.ObjectName,0
invoke ZwCreateSection,addr hsec,SECTION_MAP_EXECUTE+SECTION_MAP_READ,addr oa,0,PAGE_EXECUTE_READ,SEC_IMAGE,hfile
push eax
invoke NtClose,hfile
pop eax
test eax,eax
js @1
 
invoke DbgPrint,$CTA0("Handle section 0x%x"),hsec
 
invoke ZwMapViewOfSection,hsec,-1,addr pmem,0,li.LowPart,0,addr li,1,0,PAGE_EXECUTE_READ
test eax,eax
js @f
 
push pmem
call get_service_number
test eax,eax
js @f
 
mov ebx,[eax]
mov eax,ebx
shr eax,8
 
invoke DbgPrint,$CTA0("Service number 0x%X"),eax
invoke ZwUnmapViewOfSection,-1,pmem
 
call search
test eax,eax
jz @1
invoke DbgPrint,$CTA0("Kernel address 0x%X"),eax
 
@@:
invoke NtClose,hsec
 
@1:
 
invoke DbgPrint,$CTA0("Last Error 0x%X"),eax
 
mov eax,pdrobject
 
mov (DRIVER_OBJECT ptr [eax]).DriverUnload,offset DriverUnload
 
mov eax,STATUS_SUCCESS
ret
driver_entry endp
 
; -------------------------------------------------------------------------
search proc uses ebx edi esi
local psearch:dword
 
invoke MmGetSystemRoutineAddress,addr function
test eax,eax
js @r
 
mov psearch,eax
mov esi,eax
mov edx,14h
mov edi,2
 
@1:
mov ecx,30
 
@@:
mov eax,[esi]
cmp eax,ebx
je @f
add esi,edx
loop @b
 
mov esi,psearch
neg edx
dec edi
jnz @1
 
xor eax,eax
jmp @r
 
@@:
mov eax,esi
@r:
ret
search endp
 
; -------------------------------------------------------------------------
 
get_service_number proc uses ebx edi esi psection
 
mov eax,psection
mov ebx,eax
 
add ebx,(IMAGE_DOS_HEADER ptr [eax]).e_lfanew
lea ebx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader
 
mov ebx,(IMAGE_OPTIONAL_HEADER ptr [ebx]).DataDirectory.VirtualAddress
add ebx,eax
 
lea esi,nfunction
mov edi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNames
 
push ebx
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).NumberOfNames
 
lea edi,[edi+eax-4]
mov edx,-1
 
@@:
add edi,4
push edi
mov edi,[edi]
add edi,eax
 
inc edx
push esi
mov ecx,sizeof nfunction-1
repe cmpsb
pop esi
pop edi 
je @f
dec ebx
jne @b
pop ebx
mov eax,-1
jmp @ret
 
@@:
pop ebx
mov esi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNameOrdinals
shl edx,1
add edx,esi
add edx,eax
movzx edx,word ptr [edx]
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfFunctions
add ebx,eax
shl edx,2
add edx,ebx
mov edx,[edx]
add eax,edx
 
@ret:
ret
get_service_number endp
end driver_entry
 
;x64
 
include f:\masm32\include64\win64.inc
include f:\masm32\include64\ntddk.inc
include f:\masm32\macros\strings.mac
include f:\masm32\include64\ntdef.inc
include f:\masm32\include64\ntstatus.inc
include f:\masm32\include64\rtl.inc
 
includelib f:\masm32\lib64\ntoskrnl.lib
include f:\masm32\macros\x64.mac
 
extrn DbgPrint:proc
extrn RtlZeroMemory:proc
extrn ZwCreateFile:proc
extrn ZwCreateSection:proc
extrn ZwMapViewOfSection:proc
extrn ZwUnmapViewOfSection:proc
extrn NtClose:proc
extrn MmGetSystemRoutineAddress:proc
 
.const
 
nfunction db 'ZwProtectVirtualMemory',0
unis function,'ZwQuerySection'
unis nfile,'\SystemRoot\system32\ntdll.dll'
 
.code
 
DriverUnload proc uses rbx rdi pdrobject:qword
mov pdrobject,rcx
 
invoke DbgPrint,$CTA0("Unload")
 
mov rax,STATUS_SUCCESS
ret
DriverUnload endp
 
.code
 
driver_entry proc uses rbx rdi rsi pdrobject:qword,pregpath:qword
local oa:OBJECT_ATTRIBUTES
local iob:IO_STATUS_BLOCK
local li:LARGE_INTEGER
local hfile:qword
local hsec:qword
local hdo:qword
local pmem:qword
 
mov pdrobject,rcx
mov pregpath,rdx
 
and pmem,0
and li.LowPart,0
and li.HighPart,0
 
invoke RtlZeroMemory,addr oa,sizeof oa
mov oa._Length,sizeof oa
lea rax,nfile
mov oa.ObjectName,rax
mov oa.Attributes,OBJ_KERNEL_HANDLE
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:15   #26
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Код:
invoke ZwCreateFile,addr hfile,FILE_READ_DATA+FILE_EXECUTE,addr oa,addr iob,0,0,FILE_SHARE_READ,FILE_OPEN,0,0,0
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle file 0x%X"),hfile
 
mov oa.ObjectName,0
invoke ZwCreateSection,addr hsec,SECTION_MAP_EXECUTE+SECTION_MAP_READ,addr oa,0,PAGE_EXECUTE_READ,SEC_IMAGE,hfile
push rax
 
invoke NtClose,hfile
pop rax
test eax,eax
js @1
 
invoke DbgPrint,$CTA0("Handle section 0x%x"),hsec
 
invoke ZwMapViewOfSection,hsec,-1,addr pmem,0,li.QuadPart,0,addr li,1,0,PAGE_EXECUTE_READ
test eax,eax
js @f
 
invoke DbgPrint,$CTA0("Memory address 0x%X"),pmem
mov rcx,pmem
sub rsp,20h
call get_service_number
add rsp,20h
 
test eax,eax
js @f
 
add eax,3
mov ebx,[eax]
mov eax,ebx
shr eax,8
 
invoke DbgPrint,$CTA0("Service number 0x%X"),rax
invoke ZwUnmapViewOfSection,-1,pmem
 
sub rsp,20h
call search
add rsp,20h
test eax,eax
jz @1
mov rbx,rax
shr rax,32
invoke DbgPrint,$CTA0("ZwProtectVirtualMemory address 0x%X%X"),rax,rbx
 
@@:
invoke NtClose,hsec
 
@1:
 
invoke DbgPrint,$CTA0("Last Error 0x%X"),rax
 
mov rax,pdrobject
lea rcx,DriverUnload
mov (DRIVER_OBJECT ptr [rax]).DriverUnload,rcx
mov rax,STATUS_SUCCESS
ret
driver_entry endp
search proc uses rbx rdi rsi
local psearch:qword
 
invoke MmGetSystemRoutineAddress,addr function
test eax,eax
jz @r
push rax
mov rcx,rax
shr rax,32
invoke DbgPrint,$CTA0("ZwQuerySection address 0x%X%X"),rax,rcx
 
pop rax
add rax,14h
 
mov psearch,rax
mov rsi,rax
mov rdx,20h
mov rdi,2
 
@1:
mov rcx,50
 
@@:
mov rax,[rsi]
cmp ax,bx
je @f
add rsi,rdx
loop @b
 
mov rsi,psearch
neg rdx
dec rdi
jnz @1
 
xor eax,eax
jmp @r
 
@@:
mov rax,rsi
sub rax,14h
@r:
ret
search endp
get_service_number proc uses rbx rdi rsi psection:qword
mov psection,rcx
mov rax,rcx
mov rbx,rax
 
and rdi,0
add ebx,(IMAGE_DOS_HEADER ptr [rax]).e_lfanew
lea rbx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader
 
mov ebx,(IMAGE_OPTIONAL_HEADER ptr [rbx]).DataDirectory.VirtualAddress
add ebx,eax
 
lea rsi,nfunction
mov edi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNames
 
push rbx
and rbx,0ffffffffh
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).NumberOfNames
 
lea edi,[edi+eax-4]
mov rdx,-1
 
@@:
add rdi,4
push rdi
mov edi,[rdi]
add edi,eax
 
inc edx
push rsi
mov ecx,sizeof nfunction-1
repe cmpsb
pop rsi
pop rdi 
je @f
 
dec ebx
jne @b
pop rbx
mov eax,-1
jmp @ret
 
@@:
pop rbx
mov esi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNameOrdinals
shl rdx,1
add edx,esi
add edx,eax
movzx edx,word ptr [edx]
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfFunctions
add ebx,eax
shl edx,2
add edx,ebx
mov rdx,[edx]
add eax,edx
 
@ret:
ret 
get_service_number endp
end
Макрос unis для х64.
Код:
UNICODE__STRING struct
Length_     dw ?
MaxLength   dw ?
Reserve     dd 0
Buffer      dq ?
UNICODE__STRING ends
 
unis macro name,string
local s,e
len sizestr <string>
 
align 4
sstr substr <string>,2,len-2
 
s label word
 
% forc n,<sstr>
dw '&n'
endm
e dw 0
align 8
k=(e-s)
name UNICODE__STRING {k,k+2,0,s}
endm
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:22   #27
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Перевод строки из десятеричных цифр в DWORD

автор The Svin взято здесь
Код:
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
atodw proc FORCENOFRAME
    ;----------------------------------------
    ; перевод десятеричной строки в число типа dword
    ; значение возвращается в регистре eax
    ;----------------------------------------
    ;   String EQU [esp+4]
    mov edx, [esp+4]
    xor eax, eax
    cmp BYTE PTR [edx], 2Eh
    sbb [esp+4], edx
    adc edx, eax
    jmp @F
again:
    lea eax, [eax+4*eax]
    inc edx
    lea eax, [ecx+2*eax-30h]
@@: movzx ecx, BYTE PTR [edx]
    cmp BYTE PTR [edx], 30h
    jns again
    add eax, [esp+4]
    xor eax, [esp+4]
    retn 4
atodw ENDP
OPTION PROLOGUE:DefaultOption
OPTION EPILOGUE:DefaultOption
Перевод строки из шестнадцатеричных цифр в число типа DWORD с использованием MMX

автор bitRAKE, взято здесь
Код:
StrHex2bin PROC
    _CONST SEGMENT
        lpString db "89aBcDeF"
    _CONST ENDS
    movq mm0,QWORD PTR [lpString]
 
    psubusb  mm0,mxc(<30>) ; "0" = 0
    movq mm1,mm0
 
    pcmpgtb mm1,mxc(<09>) ; letter?
    pand mm1,mxc(<07>)
 
    psubusb mm0,mm1 ; fix letters
 
    movq mm1,mm0         ; 0F0E0D0C0B0A0908
    pand mm0,mxc(<0F00>) ; 0E000C000A000800
    pand mm1,mxc(<000F>) ; 000F000D000B0009
    psrlq mm0,8          ; 000E000C000A0008
 
    packuswb mm1,mm1     ; 0F0D0B09
    packuswb mm0,mm0     ; 0E0C0A08
    psllq mm1,4          ; F0D0B090
    por mm0,mm1          ; FEDCBA98
    movd eax,mm0         ; FEDCBA98
 
    bswap eax            ; 89ABCDEF
    ret
StrHex2bin ENDP
Перевод числа типа DWORD в строку из двоичных цифр
с удалением лидирующих нулей


Автор Sloat, взято здесь
Код:
buff db 128 dup (?)
number equ 45432
....
 
 
mov eax, number
or eax, eax
jz _exit
bsr edx, eax
mov ecx, 31
sub ecx, edx
shl eax, cl
lea edx, buff
@@:
    shl eax, 1
    setc BYTE PTR[edx]
    add BYTE PTR[edx],"0"
    inc edx
    inc ecx
cmp ecx, 32
jl @B
_exit:
Перевод числа типа QWORD в строку из десятичных цифр
с использованием MMX


Автор The Svin, взято здесь
Код:
.586
.MMX
.model flat,stdcall
option casemap:none
 
.data
ALIGN 8
mmxb0F dq 0F0F0F0F0F0F0F0Fh
mmxb30 dq 3030303030303030h
 
.code
Q2Ammxf proc uses edi lpBuffer,lpNumber
    mov ecx,lpNumber
    mov edi,lpBuffer
    mov eax,[ecx]
    mov edx,[ecx+4]
 
D05H    equ 045639182h
D05L    equ 044F40000h
D04H    equ 03782DACEh
D04L    equ 09D900000h
D01H    equ 00DE0B6B3h
D01L    equ 0A7640000h
QtoA:
    sub esp,12
    xor ecx,ecx
    sub eax,D01L
    sbb edx,D01H
    jb    @@a01f
    sub eax,D04L
    sbb edx,D04H
    jb    @@a05
    mov cl,05h
    sub eax,D05L
    sbb edx,D05H
    jb    @@a05
    mov cl,15h
    sub eax,D05L
    sbb edx,D05H
    jae  @@l01
    mov cl,10h
@@a05:    add eax,D05L
    adc edx,D05H
@@l01:  inc ecx
    sub eax,D01L
    sbb edx,D01H
    jae  @@l01
    dec ecx
@@a01f:    add eax,D01L
    adc edx,D01H
 
    push edx
    push eax
    fild qword ptr [esp]
    fbstp [esp]
    mov [esp+9],ecx
    mov edx,2
    cmp dword ptr [esp+8],0
    jne @@dg16
    cmp dword ptr [esp+4],1
    sbb edx,1
@@dg16:    bsr ecx,[esp+edx*4]
    je @@zero
    shr ecx,3
    lea eax,[ecx+4*edx]
    lea edx,[eax+eax]
    cmp byte ptr [esp][eax],10h
    sbb edx,-1
 
    movq mm(7),mmxb0F
    movq mm(6),mmxb30
    movq mm(0),[esp]
    movq mm(4),[esp+8]
    movq mm(1),mm(0)
    psrlq mm(1),4
    pand mm(0),mm(7)
    por    mm(0),mm(6)
    pand mm(1),mm(7)
    por mm(1),mm(6)
    movq mm(2),mm(0)
    punpcklbw mm(0),mm(1)
    movq [esp],mm(0)
    punpckhbw mm(2),mm(1)
    movq [esp+8],mm(2)
    movq mm(5),mm(4)
    psrlq mm(5),4
    pand mm(4),mm(7)
    por mm(4),mm(6)
    pand mm(5),mm(7)
    por mm(5),mm(6)
    punpcklbw mm(4),mm(5)
    movd [esp+16],mm(4)
    emms
@@lpS:    mov eax,[esp+edx-3]
    bswap eax
    mov [edi],eax
    add edi,4
    sub edx,4
    jns  @@lpS
    mov byte ptr [edi+edx][1],0
    add esp,20
    ret
@@zero:    mov dword ptr [edi],'0'
    add esp,20
    ret
Q2Ammxf endp
    end
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:26   #28
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Ещё один вариант перевода числа типа QWORD в строку из десятичных цифр
с использованием MMX


Автор The Svin, взято здесь
Код:
.586
.MMX
.model flat,stdcall
option casemap:none
.data
ALIGN 8
mmxb0F dq 0F0F0F0F0F0F0F0Fh
mmxb30 dq 3030303030303030h
num dq 12345678901234567890
.data?
buffer db 24 dup (?)
.code
 
    mov edx,dword ptr num+4
    mov eax,dword ptr num
    mov edi, offset buffer
 
N19H EQU 00DE0B6B3H
N19L EQU 0A7640000H
N20H EQU 08AC72304H
N20L EQU 089E80000H
 
Q2Ammx proc uses edi lpBuffer, lpNumber
    mov ecx,lpNumber
    mov eax,[ecx]
    mov edx,[ecx+4]
    mov edi,lpBuffer
    sub esp,12
    xor ecx,ecx
    cmp edx,N19H
    jb     @@nm18
    jne   @@cp20
    cmp eax,N19L
    jb     @@nm18
@@cp20:    cmp edx,N20H
    jb     @@do19
    jne   @@do20
    cmp eax,N20L
    jb     @@do19
@@do20:    mov cl,10h-1
    sub  eax,N20L
    sbb edx,N20H
@@lp19:    inc ecx
@@do19:    sub eax,N19L
    sbb edx,N19H
    jae  @@lp19
    add eax,N19L
    adc edx,N19H
@@nm18:    push edx
    push eax
    fild qword ptr [esp]
    fbstp [esp]
    mov [esp+9],ecx
 
    mov edx,2
    cmp dword ptr [esp+8],0
    jne @@dg16
    cmp dword ptr [esp+4],1
    sbb edx,1
@@dg16:    bsr ecx,[esp+edx*4]
    je @@zero
    shr ecx,3
    lea eax,[ecx+4*edx]
    lea edx,[eax+eax]
    cmp byte ptr [esp+eax],10h
    sbb edx,-1
 
    movq mm(7),mmxb0F
    movq mm(6),mmxb30
    movq mm(0),[esp]
    movq mm(4),[esp+8]
    movq mm(1),mm(0)
    psrlq mm(1),4
    pand mm(0),mm(7)
    por    mm(0),mm(6)
    pand mm(1),mm(7)
    por mm(1),mm(6)
    movq mm(2),mm(0)
    punpcklbw mm(0),mm(1)
    movq [esp],mm(0)
    punpckhbw mm(2),mm(1)
    movq [esp+8],mm(2)
    movq mm(5),mm(4)
    psrlq mm(5),4
    pand mm(4),mm(7)
    por mm(4),mm(6)
    pand mm(5),mm(7)
    por mm(5),mm(6)
    punpcklbw mm(4),mm(5)
    movd [esp+16],mm(4)
    emms
@@lpS:    mov eax,[esp+edx-3]
    bswap eax
    mov [edi],eax
    add edi,4
    sub edx,4
    jns  @@lpS
    mov byte ptr [edi+edx][1],0
    add esp,20
    ret
@@zero:    mov dword ptr [edi],'0'
    add esp,20
    ret
Q2Ammx endp 
end
Перевод строки из шестнадцатеричных цифр в число типа DWORD

автор The Svin, взято здесь
Используются только строчные буквы (ABCDEF)
Модуль написан в формате masm32.inc. При использовании описывайте прототип как
htodwc proto :DWORD
Код:
 
    ; --------------------------------------
    ; This procedure was written by Svin
    ; --------------------------------------
 
      .386
      .model flat, stdcall  ; 32 bit memory model
      option casemap :none  ; case sensitive
 
    .code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
 
htodwc         proc FORCENOFRAME
 
 
    push ebx
    xor eax,eax
    mov ebx,[esp+8]
    xor edx,edx
@@: mov dl,[ebx] ;1
    shl eax,4        ;0
    cmp dl,41h   ;1
    inc ebx         ;0
    sbb cl,cl       ;1
    sub dl,'A'-0Ah ;0
    and cl,7        ;1
    add dl,cl      ;1
    cmp byte ptr [ebx],0 ;0
    lea eax,[eax][edx] ;1
    jne @B  ;1
    pop ebx
    ret 4
htodwc         endp
 
OPTION PROLOGUE:DEFAULTOPTION
OPTION EPILOGUE:DEFAULTOPTION
 
end
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:32   #29
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

FPU. Округление.

Порой бывают такие случаи, когда надо вытащить целую часть дроби. В этом случаи все прибегают к помощи такой связки, как
Код:
finit
fld __float
fistp __int
но она почему-то не всегда срабатывает.

Например, у меня был случай, когда при делении надо было от частного оставлять только целую часть, но связка, упомянутая выше, в случае с частным 0.501 выдавала результатом 1, а не 0.

Когда такое происходит, помогает вот такая связка:
Код:
fstcw cw
or cw,0C00h
fldcw cw
Связка выше устанавливает принудительное округление в режиме "Round toward zero" или "Округление к нулю".

После применения данной инструкции всё заработало так, как надо. Вот так.
Mikl___ вне форума Ответить с цитированием
Старый 03.12.2014, 11:35   #30
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

процедура пищания динамиком под DOS-ом
Код:
;на вход процедуре в регистре di подается частота звучания
sound proc 
    push ax
    push cx
    mov al, 0B6h
    out 43h, al
    in al, 61h
    or al, 3
    out 61h, al
    mov ax, 34DCh
    mov dx, 12h
    div di
    out 42h, al
    mov al, ah
    out 42h, al
    mov cx, 3000        ;небольшая задержка
@@: push cx
    mov cx, 50000
    loop $
    pop cx 
    loop @@
    in al, 61h
    and al, 0FCh
    out 61h, al
    pop cx
    pop ax 
    ret
sound endp
Mikl___ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа для шифрования раздела с виндой Жека90 Софт 1 12.06.2012 18:17
макрос для решения квадратных уравнений (перемещено из раздела Excel) sashkkk Помощь студентам 3 22.09.2010 23:06
Собираем команду для FAQ Aexx Свободное общение 112 14.10.2009 09:20
Формат по образцу для раздела... Busine2009 Microsoft Office Word 0 28.07.2009 08:05
Программа для копирования заданного раздела. С++ x007 Общие вопросы C/C++ 5 23.04.2009 23:52